From 5b90e8043cf5cd3c445f3995768df580b6475f07 Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Mon, 24 Aug 2026 14:15:45 +0000 Subject: [PATCH] =?UTF-8?q?=E2=9A=A1=20Bolt:=20[=EC=84=B1=EB=8A=A5=20?= =?UTF-8?q?=EA=B0=9C=EC=84=A0]=20i18n=20=EB=85=B8=EB=93=9C=20dataset=20?= =?UTF-8?q?=EC=BA=90=EC=8B=B1=EC=9D=84=20=ED=86=B5=ED=95=9C=20=EB=B0=98?= =?UTF-8?q?=EB=B3=B5=20=EC=98=A4=EB=B2=84=ED=97=A4=EB=93=9C=20=EC=B5=9C?= =?UTF-8?q?=EC=A0=81=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .jules/bolt.md | 4 ++++ i18n.js | 10 +++++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/.jules/bolt.md b/.jules/bolt.md index 11eed41..29f7796 100644 --- a/.jules/bolt.md +++ b/.jules/bolt.md @@ -20,3 +20,7 @@ ## 2026-08-08 - 애니메이션 성능을 위해 top/left 대신 transform 사용 **Learning:** 이 skip-link 전환을 `top`에서 `transform`으로 바꾸면 애니메이션 중 레이아웃 재계산을 피하는 데 유리합니다. 개발자 도구에서 이 전환의 Layout 이벤트가 관찰되지 않았지만, 브라우저·장치별 GPU 가속이나 메인 스레드 비용 0ms를 보장하지는 않습니다. **Action:** 레이아웃 속성 대신 `transform` 전환을 우선 검토하고, 성능 효과는 브라우저별 측정으로 확인하며 절대적인 GPU·비용 보장으로 기록하지 않습니다. + +## 2026-08-24 - DOMStringMap (dataset) Proxy 성능 최적화 +**Learning:** NodeList를 반복하며 `node.dataset.i18n`에 접근할 때, DOMStringMap이 Proxy 객체로 구현되어 있어 일반 프로퍼티 접근보다 속도가 느립니다. 특히 수백 개의 노드를 언어 변경 시마다 반복하면 오버헤드가 발생합니다. +**Action:** `document.querySelectorAll` 결과를 일반 객체의 배열(`{node, key}`)로 매핑하여 `dataset` 키를 미리 캐싱함으로써 반복(iteration) 성능을 향상시켰습니다. diff --git a/i18n.js b/i18n.js index 00b81d3..d7dc95f 100644 --- a/i18n.js +++ b/i18n.js @@ -365,12 +365,16 @@ function setLanguage(lang) { if (!isInitialDefault) { if (!i18nNodes) { - i18nNodes = document.querySelectorAll("[data-i18n]"); + // ⚡ Bolt: Cache dataset keys as plain object properties to avoid DOMStringMap proxy overhead + i18nNodes = Array.from(document.querySelectorAll("[data-i18n]")).map((node) => ({ + node, + key: node.getAttribute("data-i18n") + })); } // Only update textContent if it actually changed to avoid layout recalculations - i18nNodes.forEach((node) => { - const newText = dict[node.dataset.i18n]; + i18nNodes.forEach(({ node, key }) => { + const newText = dict[key]; if (newText && node.textContent !== newText) { node.textContent = newText; }