From 81f0b8e11c09bc3eb2df0c0d9d141a30ebf25360 Mon Sep 17 00:00:00 2001 From: Eugene Choi <4eugenechoi@gmail.com> Date: Wed, 24 Sep 2025 15:12:20 -0400 Subject: [PATCH 1/3] Fix useEffect on tabify --- .../playground/components/Editor/Output.tsx | 45 ++++++++++++++----- 1 file changed, 34 insertions(+), 11 deletions(-) diff --git a/compiler/apps/playground/components/Editor/Output.tsx b/compiler/apps/playground/components/Editor/Output.tsx index 331aa66bcbe..bb6b60009f3 100644 --- a/compiler/apps/playground/components/Editor/Output.tsx +++ b/compiler/apps/playground/components/Editor/Output.tsx @@ -19,8 +19,8 @@ import { import parserBabel from 'prettier/plugins/babel'; import * as prettierPluginEstree from 'prettier/plugins/estree'; import * as prettier from 'prettier/standalone'; -import {memo, ReactNode, useEffect, useState} from 'react'; import {type Store} from '../../lib/stores'; +import {memo, ReactNode, use, useState, Suspense} from 'react'; import AccordionWindow from '../AccordionWindow'; import TabbedWindow from '../TabbedWindow'; import {monacoOptions} from './monacoOptions'; @@ -32,6 +32,8 @@ export default MemoizedOutput; export const BASIC_OUTPUT_TAB_NAMES = ['Output', 'SourceMap']; +let tabifyCache = new Map>>(); + export type PrintedCompilerPipelineValue = | { kind: 'hir'; @@ -200,6 +202,28 @@ ${code} return reorderedTabs; } +function tabifyCached( + store: Store, + compilerOutput: CompilerOutput, +): Promise> { + const key = store; + if (tabifyCache.has(key)) { + return tabifyCache.get(key)!; + } + const result = tabify(store.source, compilerOutput, store.showInternals); + tabifyCache.set(key, result); + return result; +} + +function Fallback(): JSX.Element { + console.log('Fallback'); + return ( +
+ Loading... +
+ ); +} + function utf16ToUTF8(s: string): string { return unescape(encodeURIComponent(s)); } @@ -213,12 +237,17 @@ function getSourceMapUrl(code: string, map: string): string | null { } function Output({store, compilerOutput}: Props): JSX.Element { + return ( + }> + + + ); +} + +function OutputContent({store, compilerOutput}: Props): JSX.Element { const [tabsOpen, setTabsOpen] = useState>( () => new Set(['Output']), ); - const [tabs, setTabs] = useState>( - () => new Map(), - ); const [activeTab, setActiveTab] = useState('Output'); /* @@ -233,13 +262,6 @@ function Output({store, compilerOutput}: Props): JSX.Element { setTabsOpen(new Set(['Output'])); setActiveTab('Output'); } - - useEffect(() => { - tabify(store.source, compilerOutput, store.showInternals).then(tabs => { - setTabs(tabs); - }); - }, [store.source, compilerOutput, store.showInternals]); - const changedPasses: Set = new Set(['Output', 'HIR']); // Initial and final passes should always be bold let lastResult: string = ''; for (const [passName, results] of compilerOutput.results) { @@ -254,6 +276,7 @@ function Output({store, compilerOutput}: Props): JSX.Element { lastResult = currResult; } } + const tabs = use(tabifyCached(store, compilerOutput)); if (!store.showInternals) { return ( From 8adc468bf226824b36de092ebb61e73eaa45cf3a Mon Sep 17 00:00:00 2001 From: Eugene Choi <4eugenechoi@gmail.com> Date: Thu, 25 Sep 2025 10:27:51 -0400 Subject: [PATCH 2/3] Use LRU cache --- .../apps/playground/components/Editor/Output.tsx | 14 +++++++------- compiler/apps/playground/package.json | 1 + compiler/apps/playground/yarn.lock | 5 +++++ 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/compiler/apps/playground/components/Editor/Output.tsx b/compiler/apps/playground/components/Editor/Output.tsx index bb6b60009f3..da6d97119bc 100644 --- a/compiler/apps/playground/components/Editor/Output.tsx +++ b/compiler/apps/playground/components/Editor/Output.tsx @@ -25,6 +25,7 @@ import AccordionWindow from '../AccordionWindow'; import TabbedWindow from '../TabbedWindow'; import {monacoOptions} from './monacoOptions'; import {BabelFileResult} from '@babel/core'; +import {LRUCache} from 'lru-cache'; const MemoizedOutput = memo(Output); @@ -32,7 +33,9 @@ export default MemoizedOutput; export const BASIC_OUTPUT_TAB_NAMES = ['Output', 'SourceMap']; -let tabifyCache = new Map>>(); +const tabifyCache = new LRUCache>>({ + max: 100, +}); export type PrintedCompilerPipelineValue = | { @@ -206,17 +209,14 @@ function tabifyCached( store: Store, compilerOutput: CompilerOutput, ): Promise> { - const key = store; - if (tabifyCache.has(key)) { - return tabifyCache.get(key)!; - } + const cached = tabifyCache.get(store); + if (cached) return cached; const result = tabify(store.source, compilerOutput, store.showInternals); - tabifyCache.set(key, result); + tabifyCache.set(store, result); return result; } function Fallback(): JSX.Element { - console.log('Fallback'); return (
Loading... diff --git a/compiler/apps/playground/package.json b/compiler/apps/playground/package.json index 08aed45e0f3..6d5757008a5 100644 --- a/compiler/apps/playground/package.json +++ b/compiler/apps/playground/package.json @@ -32,6 +32,7 @@ "hermes-eslint": "^0.25.0", "hermes-parser": "^0.25.0", "invariant": "^2.2.4", + "lru-cache": "^11.2.2", "lz-string": "^1.5.0", "monaco-editor": "^0.52.0", "next": "15.6.0-canary.7", diff --git a/compiler/apps/playground/yarn.lock b/compiler/apps/playground/yarn.lock index 53f0d24db70..00b8a6950f9 100644 --- a/compiler/apps/playground/yarn.lock +++ b/compiler/apps/playground/yarn.lock @@ -3104,6 +3104,11 @@ lru-cache@^10.2.0: resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.4.3.tgz#410fc8a17b70e598013df257c2446b7f3383f119" integrity sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ== +lru-cache@^11.2.2: + version "11.2.2" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-11.2.2.tgz#40fd37edffcfae4b2940379c0722dc6eeaa75f24" + integrity sha512-F9ODfyqML2coTIsQpSkRHnLSZMtkU8Q+mSfcaIyKwy58u+8k5nvAYeiNhsyMARvzNcXJ9QfWVrcPsC9e9rAxtg== + lru-cache@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" From d52fed8c8b8ec2b500bcf4fffe11870a5d624259 Mon Sep 17 00:00:00 2001 From: Eugene Choi <4eugenechoi@gmail.com> Date: Thu, 25 Sep 2025 14:41:08 -0400 Subject: [PATCH 3/3] Lower LRU size --- compiler/apps/playground/components/Editor/Output.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/apps/playground/components/Editor/Output.tsx b/compiler/apps/playground/components/Editor/Output.tsx index da6d97119bc..dcc8dea5c83 100644 --- a/compiler/apps/playground/components/Editor/Output.tsx +++ b/compiler/apps/playground/components/Editor/Output.tsx @@ -34,7 +34,7 @@ export default MemoizedOutput; export const BASIC_OUTPUT_TAB_NAMES = ['Output', 'SourceMap']; const tabifyCache = new LRUCache>>({ - max: 100, + max: 5, }); export type PrintedCompilerPipelineValue =