From cd8fcfab467a49fc25bafef7e29c73012ff8b28e Mon Sep 17 00:00:00 2001 From: isaaclombardssw Date: Thu, 23 Jul 2026 17:26:05 +1000 Subject: [PATCH] =?UTF-8?q?=F0=9F=92=B8=20Load=20AOS=20only=20where=20it's?= =?UTF-8?q?=20used=20(#4901)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit AOS was initialised in TinaClient on every page and its CSS imported globally, even on pages with no data-aos elements. Move init into a small client AosLoader that dynamically imports the AOS JS and carries the CSS, and render it only from the 9 components that actually use data-aos. Drop the global init and the 6 stray aos.css imports (3 pages + 3 blocks with no data-aos). Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01Q8genJyZboXaa4vgYhJF4P --- app/(events)/events/[...filename]/page.tsx | 1 - app/consulting/[filename]/page.tsx | 1 - .../video-production/[filename]/page.tsx | 1 - app/tina-client.tsx | 19 ----------- .../imageComponents/ImageComponentLayout.tsx | 1 - .../accordionBlock/accordionBlock.tsx | 1 - .../imageTextBlock/imageTextBlock.tsx | 1 - components/blocks/testimonialsCard.tsx | 2 ++ components/blocks/youtubePlaylist.tsx | 2 ++ components/button/utilityButton.tsx | 2 ++ components/consulting/mediaCard/mediaCard.tsx | 2 ++ components/liveStream/liveStreamWidget.tsx | 2 ++ components/technologyCard/technologyCard.tsx | 2 ++ components/training/presenterBlock.tsx | 2 ++ components/util/aosLoader.tsx | 32 +++++++++++++++++++ components/util/consulting/benefits.tsx | 2 ++ components/util/videoCards.tsx | 2 ++ 17 files changed, 50 insertions(+), 25 deletions(-) create mode 100644 components/util/aosLoader.tsx diff --git a/app/(events)/events/[...filename]/page.tsx b/app/(events)/events/[...filename]/page.tsx index ee73ff94c3..406e4287a0 100644 --- a/app/(events)/events/[...filename]/page.tsx +++ b/app/(events)/events/[...filename]/page.tsx @@ -6,7 +6,6 @@ import { getSEOProps } from "@/lib/seo"; import { EVENTS_MAX_SIZE_OVERRIDE } from "@/services/server/getEvents"; import { fetchTinaData, FileType } from "@/services/tina/fetchTinaData"; import client from "@/tina/client"; -import "aos/dist/aos.css"; // This is important to keep the animation import { Metadata } from "next"; import { cache } from "react"; import EventsPage from "./events"; diff --git a/app/consulting/[filename]/page.tsx b/app/consulting/[filename]/page.tsx index 0ed0b91cb9..90f7b7fa79 100644 --- a/app/consulting/[filename]/page.tsx +++ b/app/consulting/[filename]/page.tsx @@ -2,7 +2,6 @@ import { TinaClient } from "@/app/tina-client"; import { getSEOProps } from "@/lib/seo"; import { fetchTinaData, FileType } from "@/services/tina/fetchTinaData"; import client from "@/tina/client"; -import "aos/dist/aos.css"; // This is important to keep the animation import { Metadata } from "next"; import { cache } from "react"; diff --git a/app/consulting/video-production/[filename]/page.tsx b/app/consulting/video-production/[filename]/page.tsx index 35c89d5d6c..6c38b2765c 100644 --- a/app/consulting/video-production/[filename]/page.tsx +++ b/app/consulting/video-production/[filename]/page.tsx @@ -3,7 +3,6 @@ import ClientFallback from "@/components/client-fallback"; import { getSEOProps } from "@/lib/seo"; import { fetchTinaData } from "@/services/tina/fetchTinaData"; import client from "@/tina/client"; -import "aos/dist/aos.css"; // This is important to keep the animation import { Metadata } from "next"; import VideoProduction from "./video-production"; diff --git a/app/tina-client.tsx b/app/tina-client.tsx index d7a867a64a..5f78ab649d 100644 --- a/app/tina-client.tsx +++ b/app/tina-client.tsx @@ -1,7 +1,5 @@ "use client"; -import AOS from "aos"; -import { useEffect } from "react"; import { useTina } from "tinacms/dist/react"; export type UseTinaProps = { query: string; @@ -21,22 +19,5 @@ export function TinaClient({ props, Component }: TinaClientProps) { data: props.data, }); - useEffect(() => { - if (typeof window !== "undefined") { - AOS.init({ - duration: 1200, - once: true, - }); - - AOS.refresh(); - } - - return () => { - if (typeof window !== "undefined") { - AOS.refreshHard(); - } - }; - }, []); - return ; } diff --git a/components/blocks/imageComponents/ImageComponentLayout.tsx b/components/blocks/imageComponents/ImageComponentLayout.tsx index 1f6641e99a..0d244fa486 100644 --- a/components/blocks/imageComponents/ImageComponentLayout.tsx +++ b/components/blocks/imageComponents/ImageComponentLayout.tsx @@ -1,7 +1,6 @@ "use client"; import { Container } from "@/components/util/container"; import { VideoModal } from "@/components/videoModal"; -import "aos/dist/aos.css"; import Image from "next/image"; import { cn } from "@/lib/utils"; import { tinaField } from "tinacms/dist/react"; diff --git a/components/blocks/imageComponents/accordionBlock/accordionBlock.tsx b/components/blocks/imageComponents/accordionBlock/accordionBlock.tsx index 2b4f9f766b..10b546782d 100644 --- a/components/blocks/imageComponents/accordionBlock/accordionBlock.tsx +++ b/components/blocks/imageComponents/accordionBlock/accordionBlock.tsx @@ -8,7 +8,6 @@ import { AccordionTrigger, } from "@/components/ui/accordion"; import { cn } from "@/lib/utils"; -import "aos/dist/aos.css"; import classNames from "classnames"; import { tinaField } from "tinacms/dist/react"; import { TinaMarkdown } from "tinacms/dist/rich-text"; diff --git a/components/blocks/imageComponents/imageTextBlock/imageTextBlock.tsx b/components/blocks/imageComponents/imageTextBlock/imageTextBlock.tsx index 347142e611..dca08faf0f 100644 --- a/components/blocks/imageComponents/imageTextBlock/imageTextBlock.tsx +++ b/components/blocks/imageComponents/imageTextBlock/imageTextBlock.tsx @@ -2,7 +2,6 @@ import AlternatingText from "@/components/alternating-text"; import ButtonRow from "@/components/blocksSubtemplates/buttonRow"; import { cn } from "@/lib/utils"; -import "aos/dist/aos.css"; import classNames from "classnames"; import React from "react"; import { tinaField } from "tinacms/dist/react"; diff --git a/components/blocks/testimonialsCard.tsx b/components/blocks/testimonialsCard.tsx index 81fd45d101..f02b3e6f72 100644 --- a/components/blocks/testimonialsCard.tsx +++ b/components/blocks/testimonialsCard.tsx @@ -4,6 +4,7 @@ import dynamic from "next/dynamic"; import { useState } from "react"; import { TestimonialType } from "../../helpers/getTestimonials"; import { CustomLink } from "../customLink"; +import AosLoader from "../util/aosLoader"; const Image = dynamic(() => import("next/image")); @@ -23,6 +24,7 @@ export const TestimonialCard = ({ testimonial }: TestimonialCardProps) => { data-aos="flip-right" key={testimonial?.name} > +
{`Avatar = (props) => { data-aos={playlistButton.animated ? "fade-up" : undefined} data-tina-field={tinaField(props.playlistButton, "text")} > + {playlistButton.animated && } {playlistButton.text} diff --git a/components/button/utilityButton.tsx b/components/button/utilityButton.tsx index 70ddd7f6a8..9f23f43c91 100644 --- a/components/button/utilityButton.tsx +++ b/components/button/utilityButton.tsx @@ -5,6 +5,7 @@ import { JSX } from "react"; import { BsArrowLeftCircle, BsArrowRightCircle } from "react-icons/bs"; import type { Template } from "tinacms"; import { CustomLink } from "../customLink"; +import AosLoader from "../util/aosLoader"; import Button from "./rippleButton"; const sizes = { @@ -64,6 +65,7 @@ export const UtilityButton = ({ onClick={() => !disabled && onClick()} data-aos={animated ? "fade-up" : undefined} > + {animated && } {buttonText} {btnIcon && iconMapper(btnIcon)} diff --git a/components/consulting/mediaCard/mediaCard.tsx b/components/consulting/mediaCard/mediaCard.tsx index 605626408d..b2c9544968 100644 --- a/components/consulting/mediaCard/mediaCard.tsx +++ b/components/consulting/mediaCard/mediaCard.tsx @@ -1,6 +1,7 @@ import classNames from "classnames"; import { FC } from "react"; import { TinaMarkdown, TinaMarkdownContent } from "tinacms/dist/rich-text"; +import AosLoader from "../../util/aosLoader"; export type MediaCardProps = { type: "video" | "blog"; @@ -22,6 +23,7 @@ const MediaCard: FC = ({ type, content }) => { bgImagesClasses[type] )} > +
); diff --git a/components/liveStream/liveStreamWidget.tsx b/components/liveStream/liveStreamWidget.tsx index 0759b1f313..fec5c5da20 100644 --- a/components/liveStream/liveStreamWidget.tsx +++ b/components/liveStream/liveStreamWidget.tsx @@ -17,6 +17,7 @@ import layoutData, { import { LiveStreamProps } from "../../hooks/useLiveStreamProps"; import { VideoEmbed } from "../blocks/videoEmbed"; import { CustomLink } from "../customLink"; +import AosLoader from "../util/aosLoader"; import { InlineJotForm } from "../inlineJotForm/inlineJotForm"; import { SocialIcons } from "../socialIcons/socialIcons"; @@ -147,6 +148,7 @@ export const LiveStreamWidget = ({ isLive, event }: LiveStreamWidgetProps) => { data-aos-anchor="#thumbnailAnchor" data-aos-anchor-placement="bottom-top" > + import("next/image")); @@ -14,6 +15,7 @@ const TechnologyCard: FC = (props) => { className="mx-3.5 mb-15 mt-5 flex h-full flex-col border-b-2 border-solid border-sswRed bg-gray-75 px-8 py-11" data-aos="flip-left" > + {thumbnail ? (
{ return ( +

{ + useEffect(() => { + let cancelled = false; + + void import("aos").then((mod) => { + if (cancelled) return; + const AOS = mod.default; + if (!initialised) { + AOS.init({ duration: 1200, once: true }); + initialised = true; + } + AOS.refresh(); + }); + + return () => { + cancelled = true; + }; + }, []); + + return null; +}; + +export default AosLoader; diff --git a/components/util/consulting/benefits.tsx b/components/util/consulting/benefits.tsx index fab2831fb8..72d24cc9f1 100644 --- a/components/util/consulting/benefits.tsx +++ b/components/util/consulting/benefits.tsx @@ -3,6 +3,7 @@ import dynamic from "next/dynamic"; import { tinaField } from "tinacms/dist/react"; import { TinaMarkdown } from "tinacms/dist/rich-text"; import { CustomLink } from "../../customLink"; +import AosLoader from "../aosLoader"; const Image = dynamic(() => import("next/image")); @@ -68,6 +69,7 @@ export const Benefits = ({ data }) => { return (
+
{benefitList?.map((benefit, index) => { return ( diff --git a/components/util/videoCards.tsx b/components/util/videoCards.tsx index b04e9e6250..745207dd60 100644 --- a/components/util/videoCards.tsx +++ b/components/util/videoCards.tsx @@ -5,6 +5,7 @@ import Image from "next/image"; import { FC } from "react"; import Button from "../button/rippleButton"; import { VideoModal } from "../videoModal"; +import AosLoader from "./aosLoader"; import { Container } from "./container"; import { Section } from "./section"; @@ -110,6 +111,7 @@ const VideoCards = ({ window.open(channelLink || defaultChannelLink, "_blank") } > + Watch More Videos