Skip to content

Commit 075cd86

Browse files
committed
perf: add picture tag with webp source for static mode and lazy-load mermaid
1 parent be08bd6 commit 075cd86

3 files changed

Lines changed: 34 additions & 7 deletions

File tree

packages/chronicle/src/components/mdx/code.tsx

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
'use client'
22

3-
import { type ComponentProps, isValidElement, Children } from 'react'
4-
import { Mermaid } from './mermaid'
3+
import { type ComponentProps, isValidElement, lazy, Suspense } from 'react'
54
import styles from './code.module.css'
65

6+
const Mermaid = lazy(() => import('./mermaid').then(m => ({ default: m.Mermaid })))
7+
78
type PreProps = ComponentProps<'pre'> & {
89
'data-language'?: string
910
title?: string
@@ -21,7 +22,11 @@ export function MdxPre({ children, title, className, ...props }: PreProps) {
2122
if (isValidElement(children)) {
2223
const childProps = children.props as { className?: string; children?: string }
2324
if (childProps.className?.includes('language-mermaid') && typeof childProps.children === 'string') {
24-
return <Mermaid chart={childProps.children} />
25+
return (
26+
<Suspense fallback={<pre className={styles.pre}><code>{childProps.children}</code></pre>}>
27+
<Mermaid chart={childProps.children} />
28+
</Suspense>
29+
)
2530
}
2631
}
2732

packages/chronicle/src/components/mdx/image.tsx

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,28 @@ import { isLocalImage, isSvg, buildOptimizedUrl, DEFAULT_WIDTH } from '@/lib/ima
33

44
type MDXImageProps = ComponentProps<'img'>;
55

6+
function isStaticMode(): boolean {
7+
return typeof window !== 'undefined' && '__STATIC_MODE__' in window && (window as unknown as Record<string, unknown>).__STATIC_MODE__ === true;
8+
}
9+
10+
function webpUrl(src: string): string {
11+
return src.replace(/\.[^.]+$/, '.webp');
12+
}
13+
614
export function MDXImage({ src, alt, ...props }: MDXImageProps) {
715
if (!src) return null;
816

917
const optimize = isLocalImage(src) && !isSvg(src);
10-
const imgSrc = optimize ? buildOptimizedUrl(src, DEFAULT_WIDTH) : src;
1118

19+
if (optimize && isStaticMode()) {
20+
return (
21+
<picture>
22+
<source srcSet={webpUrl(src)} type="image/webp" />
23+
<img src={src} alt={alt ?? ''} loading='lazy' decoding='async' {...props} />
24+
</picture>
25+
);
26+
}
27+
28+
const imgSrc = optimize ? buildOptimizedUrl(src, DEFAULT_WIDTH) : src;
1229
return <img src={imgSrc} alt={alt ?? ''} loading='lazy' decoding='async' {...props} />;
1330
}

packages/chronicle/src/components/mdx/index.tsx

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@ import { Link } from './link'
44
import { MdxTable, MdxThead, MdxTbody, MdxTr, MdxTh, MdxTd } from './table'
55
import { MdxPre, MdxCode } from './code'
66
import { MdxDetails, MdxSummary } from './details'
7-
import { Mermaid } from './mermaid'
87
import { MdxParagraph } from './paragraph'
98
import { CalloutContainer, CalloutTitle, CalloutDescription, MdxBlockquote } from '@/components/common/callout'
109
import { Tabs } from '@raystack/apsara'
11-
import { type ComponentProps, useEffect, useState } from 'react'
10+
import { type ComponentProps, lazy, useEffect, useState, Suspense } from 'react'
11+
12+
const LazyMermaid = lazy(() => import('./mermaid').then(m => ({ default: m.Mermaid })))
1213

1314
function ClientOnly({ children }: { children: React.ReactNode }) {
1415
const [mounted, setMounted] = useState(false)
@@ -42,7 +43,11 @@ export const mdxComponents: MDXComponents = {
4243
CalloutTitle,
4344
CalloutDescription,
4445
Tabs: MdxTabs,
45-
Mermaid,
46+
Mermaid: (props: { chart: string }) => (
47+
<Suspense fallback={<pre><code>{props.chart}</code></pre>}>
48+
<LazyMermaid {...props} />
49+
</Suspense>
50+
),
4651
}
4752

4853
export { MDXImage } from './image'

0 commit comments

Comments
 (0)