diff --git a/docs/markdown-charts.md b/docs/markdown-charts.md
index 8f26350..e9945f1 100644
--- a/docs/markdown-charts.md
+++ b/docs/markdown-charts.md
@@ -33,6 +33,7 @@
- 서버 HTML과 최초 hydration에는 제목·단위·수치 표가 동일하게 렌더된다. 검색엔진과 스크립트를 사용할 수 없는 환경도 값을 읽을 수 있다.
- 기본 선택은 차트다. 화면 200px 근처에 도달했을 때 차트 모듈을 가져온다. 차트 로딩 중·실패 시 표를 유지하고 실패 시 재시도 버튼을 제공한다.
+- 코드·다이어그램과 기존 benchmark 모듈의 다운로드 실패도 글 전체 오류로 전파하지 않는다. 원본 코드와 본문을 유지하고 해당 블록에 재시도 버튼을 표시한다.
- `표`·`차트` 전환은 shadcn ToggleGroup을 사용한다. 키보드로 조작 가능하며 툴팁을 사용하지 않아도 표에서 모든 수치와 조건을 확인할 수 있다.
- 막대 축은 0부터 시작한다. 계열 색은 라이트·다크 모드에 맞춰 바뀐다. 불완전 주차의 별표·사선 표시는 표와 차트 모두 유지한다.
- 초기 차트 애니메이션은 사용하지 않는다. 차트와 표는 좁은 본문 너비에 맞춰 표시하며 넓은 표만 자체 가로 스크롤을 허용한다.
diff --git a/src/components/CodeBlock.tsx b/src/components/CodeBlock.tsx
index 952ac1f..7b6b1b6 100644
--- a/src/components/CodeBlock.tsx
+++ b/src/components/CodeBlock.tsx
@@ -1,12 +1,26 @@
-import { lazy, Suspense, type ComponentPropsWithoutRef, useCallback, useEffect, useId, useRef, useState } from "react"
+import { type ComponentPropsWithoutRef, useCallback, useEffect, useId, useRef, useState } from "react"
import { Copy, Check } from "lucide-react"
import { Button } from "@/components/ui/button"
import { useT } from "@/i18n"
import { useTheme } from "@/hooks/useTheme"
import mermaid from "mermaid"
import { readMarkdownCode } from "@/lib/markdown-code"
+import { createRetryableLoader } from "@/lib/async-loader"
+import { useDeferredModule } from "@/hooks/useDeferredModule"
-const BenchmarkChart = lazy(() => import("@/components/BenchmarkChart").then((module) => ({ default: module.BenchmarkChart })))
+const loadBenchmark = createRetryableLoader(() => import("@/components/BenchmarkChart"))
+
+function DeferredBenchmark({ code, children, ...props }: ComponentPropsWithoutRef<"pre"> & { code: string }) {
+ const { value: module, error, retry } = useDeferredModule(loadBenchmark)
+ const t = useT()
+ if (module) return
{t.common.chartLoadError}
+{children}
+ >
+}
function getCssHex(varName: string): string {
const temp = document.createElement("div")
@@ -311,7 +325,7 @@ export function CodeBlock({ children, ...props }: ComponentPropsWithoutRef<"pre"
}
if (language === "benchmark") {
- return ) {
}
function HydratedCodeBlock(props: ComponentPropsWithoutRef<"pre">) {
- const isClient = useSyncExternalStore(subscribeHydration, getClientSnapshot, getServerSnapshot)
-
- if (!isClient) {
- return
- }
-
+ const { value: module, error, retry } = useDeferredModule(loadCodeBlock)
+ const { t } = useLanguage()
+ if (module) return
return (
- }>
-
-
+ <>
+ {error &&
+ {t.components.codeLoadError}
+
+ }
+
+ >
)
}