mirror of
https://github.com/GitbookIO/gitbook.git
synced 2026-11-02 02:09:55 +00:00
Load the inline expression runtime only for blocks that use it (RND-13530)
This commit is contained in:
@@ -6,11 +6,10 @@ import { useDebounceCallback } from 'usehooks-ts';
|
||||
import type { CustomizationThemedCodeTheme, DocumentBlockCode } from '@gitbook/api';
|
||||
|
||||
import type { BlockProps } from '../Block';
|
||||
import { type InlineExpressionVariables, useEvaluateInlineExpression } from '../InlineExpression';
|
||||
import type { InlineExpressionVariables } from '../InlineExpression/types';
|
||||
import { CodeBlockRenderer } from './CodeBlockRenderer';
|
||||
import type { HighlightTheme, RenderedInline } from './highlight-tokens';
|
||||
import { plainHighlight } from './plain-highlight';
|
||||
import { useAdaptiveVisitor } from '@/components/Adaptive';
|
||||
import { useInViewportListener } from '@/components/hooks/useInViewportListener';
|
||||
import { useScrollListener } from '@/components/hooks/useScrollListener';
|
||||
import { Button, ToggleChevron } from '@/components/primitives';
|
||||
@@ -20,6 +19,8 @@ import { type ClassValue, tcls } from '@/lib/tailwind';
|
||||
export type ClientBlockProps = Pick<BlockProps<DocumentBlockCode>, 'block' | 'style'> & {
|
||||
inlines: RenderedInline[];
|
||||
inlineExprVariables: InlineExpressionVariables;
|
||||
/** Only set for blocks with inline expressions, keeping `@gitbook/expr` out of the bundle. */
|
||||
evaluateInlineExpression?: (expression: string) => string;
|
||||
mode: BlockProps<DocumentBlockCode>['context']['mode'];
|
||||
themes?: CustomizationThemedCodeTheme;
|
||||
embedded?: boolean;
|
||||
@@ -34,18 +35,12 @@ export const CODE_BLOCK_DEFAULT_COLLAPSED_LINE_COUNT = 10;
|
||||
* It allows us to defer some load to avoid blocking the rendering of the whole page with block highlighting.
|
||||
*/
|
||||
export function ClientCodeBlock(props: ClientBlockProps) {
|
||||
const { block, mode, style, inlines, inlineExprVariables, themes, embedded, commentKey } =
|
||||
const { block, mode, style, inlines, evaluateInlineExpression, themes, embedded, commentKey } =
|
||||
props;
|
||||
const blockRef = useRef<HTMLDivElement>(null);
|
||||
const isInViewportRef = useRef(false);
|
||||
const [isInViewport, setIsInViewport] = useState(false);
|
||||
|
||||
const getAdaptiveVisitorClaims = useAdaptiveVisitor();
|
||||
const visitorClaims = getAdaptiveVisitorClaims();
|
||||
const evaluateInlineExpression = useEvaluateInlineExpression({
|
||||
visitorClaims,
|
||||
variables: inlineExprVariables,
|
||||
});
|
||||
const plainTheme = useMemo(
|
||||
() => plainHighlight(block, inlines, { evaluateInlineExpression, themes }),
|
||||
[block, inlines, evaluateInlineExpression, themes]
|
||||
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
'use client';
|
||||
|
||||
import { ClientCodeBlock, type ClientBlockProps } from './ClientCodeBlock';
|
||||
import { useAdaptiveVisitor } from '@/components/Adaptive';
|
||||
import { useEvaluateInlineExpression } from '@/components/DocumentView/InlineExpression/useEvaluateInlineExpression';
|
||||
|
||||
/**
|
||||
* Code block with inline expressions; its own module because it pulls in `@gitbook/expr`.
|
||||
*/
|
||||
export function ClientCodeBlockWithExpressions(props: ClientBlockProps) {
|
||||
const getAdaptiveVisitorClaims = useAdaptiveVisitor();
|
||||
const evaluateInlineExpression = useEvaluateInlineExpression({
|
||||
visitorClaims: getAdaptiveVisitorClaims(),
|
||||
variables: props.inlineExprVariables,
|
||||
});
|
||||
|
||||
return <ClientCodeBlock {...props} evaluateInlineExpression={evaluateInlineExpression} />;
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
'use client';
|
||||
|
||||
import dynamic from 'next/dynamic';
|
||||
|
||||
import type { ClientBlockProps } from './ClientCodeBlock';
|
||||
|
||||
// Keeps `@gitbook/expr` out of the eager bundle; `ssr: true` keeps values in the HTML.
|
||||
const ClientCodeBlockWithExpressions = dynamic(
|
||||
() =>
|
||||
import('./ClientCodeBlockWithExpressions').then(
|
||||
(mod) => mod.ClientCodeBlockWithExpressions
|
||||
),
|
||||
{ ssr: true }
|
||||
);
|
||||
|
||||
export function ClientCodeBlockWithExpressionsLazy(props: ClientBlockProps) {
|
||||
return <ClientCodeBlockWithExpressions {...props} />;
|
||||
}
|
||||
@@ -10,6 +10,7 @@ import type { BlockProps } from '../Block';
|
||||
import { Blocks } from '../Blocks';
|
||||
import { getCommentKeyProp, getCommentMarkerProps } from '../utils';
|
||||
import { ClientCodeBlock } from './ClientCodeBlock';
|
||||
import { ClientCodeBlockWithExpressionsLazy } from './ClientCodeBlockWithExpressionsLazy';
|
||||
import { CodeBlockRenderer } from './CodeBlockRenderer';
|
||||
import { highlight } from './highlight';
|
||||
import { type RenderedInline, getInlines } from './highlight-tokens';
|
||||
@@ -130,8 +131,11 @@ export async function CodeBlock(
|
||||
{isMermaid ? (
|
||||
<MermaidCodeBlockLazy
|
||||
{...clientProps}
|
||||
hasInlineExpression={hasInlineExpression}
|
||||
mermaidRuntimeURL={getAssetURL(MERMAID_RUNTIME_PATH)}
|
||||
/>
|
||||
) : hasInlineExpression ? (
|
||||
<ClientCodeBlockWithExpressionsLazy {...clientProps} />
|
||||
) : (
|
||||
<ClientCodeBlock {...clientProps} />
|
||||
)}
|
||||
|
||||
@@ -8,6 +8,7 @@ import { useCallback, useEffect, useId, useLayoutEffect, useMemo, useRef, useSta
|
||||
import { createPortal } from 'react-dom';
|
||||
|
||||
import { type ClientBlockProps, ClientCodeBlock } from './ClientCodeBlock';
|
||||
import { ClientCodeBlockWithExpressions } from './ClientCodeBlockWithExpressions';
|
||||
import { getPlainCodeBlock } from './highlight-tokens';
|
||||
import { MermaidPanZoomControls } from './MermaidPanZoomControls';
|
||||
import { useHasBeenInViewport } from '@/components/hooks/useHasBeenInViewport';
|
||||
@@ -20,6 +21,7 @@ import { tcls } from '@/lib/tailwind';
|
||||
export function MermaidCodeBlock(
|
||||
props: ClientBlockProps & {
|
||||
mermaidRuntimeURL: string;
|
||||
hasInlineExpression: boolean;
|
||||
}
|
||||
) {
|
||||
const { block, mode, style, mermaidRuntimeURL } = props;
|
||||
@@ -169,7 +171,11 @@ export function MermaidCodeBlock(
|
||||
}, []);
|
||||
|
||||
if (error) {
|
||||
return <ClientCodeBlock {...props} />;
|
||||
return props.hasInlineExpression ? (
|
||||
<ClientCodeBlockWithExpressions {...props} />
|
||||
) : (
|
||||
<ClientCodeBlock {...props} />
|
||||
);
|
||||
}
|
||||
|
||||
// The live diagram subtree. It is portaled into a stable host that moves between the
|
||||
|
||||
@@ -11,6 +11,8 @@ const MermaidCodeBlock = dynamic(
|
||||
{ ssr: true }
|
||||
);
|
||||
|
||||
export function MermaidCodeBlockLazy(props: ClientBlockProps & { mermaidRuntimeURL: string }) {
|
||||
export function MermaidCodeBlockLazy(
|
||||
props: ClientBlockProps & { mermaidRuntimeURL: string; hasInlineExpression: boolean }
|
||||
) {
|
||||
return <MermaidCodeBlock {...props} />;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import * as React from 'react';
|
||||
import type { DocumentInlineExpression } from '@gitbook/api';
|
||||
|
||||
import type { InlineProps } from '../Inline';
|
||||
import { InlineExpressionValue } from './InlineExpressionValue';
|
||||
import { InlineExpressionValueLazy } from './InlineExpressionValueLazy';
|
||||
|
||||
/**
|
||||
* Render an inline expression.
|
||||
@@ -25,7 +25,7 @@ export function InlineExpression(props: InlineProps<DocumentInlineExpression>) {
|
||||
|
||||
return (
|
||||
<React.Suspense fallback={null}>
|
||||
<InlineExpressionValue expression={data.expression} variables={variables} />
|
||||
<InlineExpressionValueLazy expression={data.expression} variables={variables} />
|
||||
</React.Suspense>
|
||||
);
|
||||
}
|
||||
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
'use client';
|
||||
|
||||
import dynamic from 'next/dynamic';
|
||||
|
||||
import type { InlineExpressionVariables } from './types';
|
||||
|
||||
// Keeps `@gitbook/expr` out of the eager bundle; `ssr: true` keeps values in the HTML.
|
||||
const InlineExpressionValue = dynamic(
|
||||
() => import('./InlineExpressionValue').then((mod) => mod.InlineExpressionValue),
|
||||
{ ssr: true }
|
||||
);
|
||||
|
||||
export function InlineExpressionValueLazy(props: {
|
||||
expression: string;
|
||||
variables: InlineExpressionVariables;
|
||||
}) {
|
||||
return <InlineExpressionValue {...props} />;
|
||||
}
|
||||
@@ -1,3 +1,2 @@
|
||||
export * from './InlineExpression';
|
||||
export * from './types';
|
||||
export * from './useEvaluateInlineExpression';
|
||||
|
||||
Reference in New Issue
Block a user