Skip to content

Commit 8f7dcde

Browse files
authored
Merge pull request #13121 from ethereum/performance-lazy-load-code-modal
performance: lazy load Codeblock component
2 parents 5248f9e + 92adad7 commit 8f7dcde

File tree

5 files changed

+71
-33
lines changed

5 files changed

+71
-33
lines changed

src/components/Codeblock.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@ import { Box, BoxProps, Flex, useColorModeValue } from "@chakra-ui/react"
1010

1111
import CopyToClipboard from "@/components/CopyToClipboard"
1212
import Emoji from "@/components/Emoji"
13+
1314
// https://github.com/FormidableLabs/prism-react-renderer/tree/master#custom-language-support
15+
import { LINES_BEFORE_COLLAPSABLE } from "@/lib/constants"
1416
;(typeof global !== "undefined" ? global : window).Prism = Prism
1517
require("prismjs/components/prism-solidity")
1618

17-
const LINES_BEFORE_COLLAPSABLE = 8
18-
1919
const TopBarItem = (props: BoxProps) => {
2020
const bgColor = useColorModeValue("#f7f7f7", "#363641")
2121

src/components/TitleCardList.tsx

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,21 +11,12 @@ import {
1111
} from "@chakra-ui/react"
1212

1313
import { TranslationKey } from "@/lib/types"
14+
import { ITitleCardItem } from "@/lib/interfaces"
1415

1516
import { Image } from "@/components/Image"
1617
import { BaseLink } from "@/components/Link"
1718
import Translation from "@/components/Translation"
1819

19-
export interface ITitleCardItem {
20-
title: string
21-
description: string
22-
caption?: string
23-
link?: string
24-
image?: string
25-
alt?: string
26-
id?: number
27-
}
28-
2920
export type TitleCardListProps = {
3021
content: Array<ITitleCardItem>
3122
className?: string

src/lib/constants.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,3 +149,6 @@ export const DEFAULT_GLOSSARY_NS = "glossary"
149149
export const HAMBURGER_BUTTON_ID = "mobile-menu-button"
150150
export const MOBILE_LANGUAGE_BUTTON_NAME = "mobile-language-button"
151151
export const DESKTOP_LANGUAGE_BUTTON_NAME = "desktop-language-button"
152+
153+
// Codeblock
154+
export const LINES_BEFORE_COLLAPSABLE = 8

src/lib/interfaces.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,3 +163,26 @@ export interface IGetInvolvedCard {
163163
title: string
164164
description: string
165165
}
166+
167+
/**
168+
* TitleCardList
169+
*/
170+
171+
export interface ITitleCardItem {
172+
title: string
173+
description: string
174+
caption?: string
175+
link?: string
176+
image?: string
177+
alt?: string
178+
id?: number
179+
}
180+
181+
/**
182+
* Codeblock
183+
*/
184+
185+
export interface CodeExample extends ITitleCardItem {
186+
codeLanguage: string
187+
code: string
188+
}

src/pages/index.tsx

Lines changed: 42 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { ReactNode, useState } from "react"
1+
import { lazy, ReactNode, Suspense, useState } from "react"
22
import type { GetStaticProps, InferGetStaticPropsType } from "next"
33
import { useRouter } from "next/router"
44
import { useTranslation } from "next-i18next"
@@ -14,25 +14,25 @@ import {
1414
HeadingProps,
1515
Icon,
1616
SimpleGridProps,
17+
SkeletonText,
1718
Stack,
1819
useToken,
1920
} from "@chakra-ui/react"
2021

2122
import { AllMetricData, BasePageProps, ChildOnlyProp, Lang } from "@/lib/types"
22-
import type { CommunityEventsReturnType } from "@/lib/interfaces"
23+
import type { CodeExample, CommunityEventsReturnType } from "@/lib/interfaces"
2324

2425
import ActionCard from "@/components/ActionCard"
2526
import ButtonLink from "@/components/Buttons/ButtonLink"
2627
import CalloutBanner from "@/components/CalloutBanner"
27-
import Codeblock from "@/components/Codeblock"
2828
import CodeModal from "@/components/CodeModal"
2929
import CommunityEvents from "@/components/CommunityEvents"
3030
import HomeHero from "@/components/Hero/HomeHero"
3131
import { Image } from "@/components/Image"
3232
import MainArticle from "@/components/MainArticle"
3333
import PageMetadata from "@/components/PageMetadata"
3434
import StatsBoxGrid from "@/components/StatsBoxGrid"
35-
import TitleCardList, { ITitleCardItem } from "@/components/TitleCardList"
35+
import TitleCardList from "@/components/TitleCardList"
3636
import Translation from "@/components/Translation"
3737

3838
import { existsNamespace } from "@/lib/utils/existsNamespace"
@@ -225,6 +225,27 @@ export const getStaticProps = (async ({ locale }) => {
225225
}
226226
}) satisfies GetStaticProps<Props>
227227

228+
const CodeblockSkeleton = () => (
229+
<Stack px={6} pt="2.75rem" h="50vh">
230+
<SkeletonText
231+
mt="4"
232+
noOfLines={6}
233+
spacing={4}
234+
skeletonHeight="1.4rem"
235+
startColor="body.medium"
236+
opacity={0.2}
237+
/>
238+
</Stack>
239+
)
240+
241+
const Codeblock = lazy(() =>
242+
Promise.all([
243+
import("@/components/Codeblock"),
244+
// Add a delay to prevent the skeleton from flashing
245+
new Promise((resolve) => setTimeout(resolve, 1000)),
246+
]).then(([module]) => module)
247+
)
248+
228249
const HomePage = ({
229250
communityEvents,
230251
metricResults,
@@ -295,11 +316,6 @@ const HomePage = ({
295316
},
296317
]
297318

298-
interface CodeExample extends ITitleCardItem {
299-
codeLanguage: string
300-
code: string
301-
}
302-
303319
const codeExamples: Array<CodeExample> = [
304320
{
305321
title: t("page-index:page-index-developers-code-example-title-0"),
@@ -538,19 +554,24 @@ const HomePage = ({
538554
</ButtonLink>
539555
</ButtonLinkRow>
540556
</FeatureContent>
541-
<CodeModal
542-
isOpen={isModalOpen}
543-
setIsOpen={setModalOpen}
544-
title={codeExamples[activeCode].title}
545-
>
546-
<Codeblock
547-
codeLanguage={codeExamples[activeCode].codeLanguage}
548-
allowCollapse={false}
549-
fromHomepage
557+
{/* Render CodeModal & Codeblock conditionally */}
558+
{isModalOpen && (
559+
<CodeModal
560+
isOpen={isModalOpen}
561+
setIsOpen={setModalOpen}
562+
title={codeExamples[activeCode].title}
550563
>
551-
{codeExamples[activeCode].code}
552-
</Codeblock>
553-
</CodeModal>
564+
<Suspense fallback={<CodeblockSkeleton />}>
565+
<Codeblock
566+
codeLanguage={codeExamples[activeCode].codeLanguage}
567+
allowCollapse={false}
568+
fromHomepage
569+
>
570+
{codeExamples[activeCode].code}
571+
</Codeblock>
572+
</Suspense>
573+
</CodeModal>
574+
)}
554575
</Row>
555576
</MainSectionContainer>
556577
{/* Eth Today Section */}

0 commit comments

Comments
 (0)