Skip to content

Commit 5f718bc

Browse files
committed
lazy load stats using intersection obs
1 parent 5901520 commit 5f718bc

File tree

2 files changed

+82
-3
lines changed

2 files changed

+82
-3
lines changed

src/components/LazyLoadComponent.tsx

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import React, { Suspense, useEffect, useRef, useState } from "react"
2+
3+
interface LazyLoadComponentProps<T extends React.ElementType> {
4+
component: T
5+
fallback: React.ReactNode
6+
componentProps: React.ComponentProps<T>
7+
intersectionOptions?: IntersectionObserverInit
8+
}
9+
10+
const LazyLoadComponent = <T extends React.ElementType>({
11+
component: Component,
12+
fallback,
13+
componentProps,
14+
intersectionOptions = {},
15+
}: LazyLoadComponentProps<T>) => {
16+
const [isVisible, setIsVisible] = useState(false)
17+
const ref = useRef<HTMLDivElement>(null)
18+
19+
useEffect(() => {
20+
const observer = new IntersectionObserver(([entry]) => {
21+
// Update the state when observer callback fires
22+
if (entry.isIntersecting) {
23+
setIsVisible(true)
24+
observer.disconnect()
25+
}
26+
}, intersectionOptions)
27+
28+
if (ref.current) {
29+
observer.observe(ref.current)
30+
}
31+
32+
// Clean up the observer on component unmount
33+
return () => {
34+
if (ref.current) {
35+
observer.disconnect()
36+
}
37+
}
38+
}, [])
39+
40+
return (
41+
<div ref={ref}>
42+
{isVisible ? (
43+
<Suspense fallback={fallback}>
44+
<Component {...componentProps} />
45+
</Suspense>
46+
) : (
47+
fallback // Show fallback until the component is visible
48+
)}
49+
</div>
50+
)
51+
}
52+
53+
export default LazyLoadComponent

src/pages/index.tsx

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { ReactNode, useState } from "react"
1+
import { lazy, ReactNode, useState } from "react"
22
import type { GetStaticProps, InferGetStaticPropsType } from "next"
33
import { useRouter } from "next/router"
44
import { useTranslation } from "next-i18next"
@@ -14,6 +14,7 @@ import {
1414
HeadingProps,
1515
Icon,
1616
SimpleGridProps,
17+
SkeletonText,
1718
Stack,
1819
useToken,
1920
} from "@chakra-ui/react"
@@ -29,9 +30,9 @@ import CodeModal from "@/components/CodeModal"
2930
import CommunityEvents from "@/components/CommunityEvents"
3031
import HomeHero from "@/components/Hero/HomeHero"
3132
import { Image } from "@/components/Image"
33+
import LazyLoadComponent from "@/components/LazyLoadComponent"
3234
import MainArticle from "@/components/MainArticle"
3335
import PageMetadata from "@/components/PageMetadata"
34-
import StatsBoxGrid from "@/components/StatsBoxGrid"
3536
import TitleCardList, { ITitleCardItem } from "@/components/TitleCardList"
3637
import Translation from "@/components/Translation"
3738

@@ -70,6 +71,21 @@ import merge from "@/public/images/upgrades/merge.png"
7071
import robotfixed from "@/public/images/wallet-cropped.png"
7172
import ethereum from "@/public/images/what-is-ethereum.png"
7273

74+
const StatsBoxGrid = lazy(() => import("@/components/StatsBoxGrid"))
75+
76+
// FIXME: using same design as in #13121 for testing purposes
77+
const CodeblockSkeleton = () => (
78+
<Stack px={6}>
79+
<SkeletonText
80+
mt="4"
81+
noOfLines={10}
82+
spacing={3}
83+
skeletonHeight="1rem"
84+
startColor="body.base"
85+
/>
86+
</Stack>
87+
)
88+
7389
const SectionHeading = (props: HeadingProps) => (
7490
<Heading
7591
lineHeight={1.4}
@@ -563,7 +579,17 @@ const HomePage = ({
563579
<Translation id="page-index:page-index-network-stats-subtitle" />
564580
</SectionDecription>
565581
</ContentBox>
566-
<StatsBoxGrid data={metricResults} />
582+
583+
<LazyLoadComponent
584+
component={StatsBoxGrid}
585+
fallback={<CodeblockSkeleton />}
586+
componentProps={{ data: metricResults }}
587+
intersectionOptions={{
588+
root: null,
589+
rootMargin: "500px",
590+
threshold: 0,
591+
}}
592+
/>
567593
</GrayContainer>
568594
<Divider mb={16} mt={16} w="10%" height="0.25rem" bgColor="homeDivider" />
569595
<CommunityEvents events={communityEvents} />

0 commit comments

Comments
 (0)