From 5388ec8fa618f7fbaa9b31d0cda5288ea3de84b4 Mon Sep 17 00:00:00 2001 From: Sean Parsons Date: Fri, 12 Jul 2024 18:29:32 +0100 Subject: [PATCH] performance(editor) Cache Execution Scope - `createExecutionScope` caches the scopes by filename and the project contents as a whole. --- .../ui-jsx-canvas-execution-scope.tsx | 24 ++++++++++++++----- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/editor/src/components/canvas/ui-jsx-canvas-renderer/ui-jsx-canvas-execution-scope.tsx b/editor/src/components/canvas/ui-jsx-canvas-renderer/ui-jsx-canvas-execution-scope.tsx index cd40fbbbf6f4..28c442e395c1 100644 --- a/editor/src/components/canvas/ui-jsx-canvas-renderer/ui-jsx-canvas-execution-scope.tsx +++ b/editor/src/components/canvas/ui-jsx-canvas-renderer/ui-jsx-canvas-execution-scope.tsx @@ -54,6 +54,9 @@ export interface ExecutionScope { requireResult: MapLike } +let lastSeenProjectContents: ProjectContentTreeRoot | null +let executionScopeCache: { [filename: string]: ExecutionScope } = {} + export function createExecutionScope( filePath: string, customRequire: (importOrigin: string, toImport: string) => any, @@ -70,11 +73,18 @@ export function createExecutionScope( updateInvalidatedPaths: DomWalkerInvalidatePathsCtxData, shouldIncludeCanvasRootInTheSpy: boolean, editedText: ElementPath | null, -): { - scope: MapLike - topLevelJsxComponents: Map - requireResult: MapLike -} { +): ExecutionScope { + // Return something from the cache as appropriate. + if (lastSeenProjectContents === projectContents) { + if (filePath in executionScopeCache) { + return executionScopeCache[filePath] + } + } else { + lastSeenProjectContents = projectContents + executionScopeCache = {} + } + + // Build the scope. const { topLevelElements, imports, jsxFactoryFunction, combinedTopLevelArbitraryBlock } = getParseSuccessForFilePath(filePath, projectContents) const requireResult: MapLike = importResultFromImports(filePath, imports, customRequire) @@ -236,11 +246,13 @@ export function createExecutionScope( }, }) - return { + const toReturn = { scope: executionScope, topLevelJsxComponents: topLevelJsxComponents, requireResult: requireResult, } + executionScopeCache[filePath] = toReturn + return toReturn } const emptyHighlightBoundsResult = { code: '', highlightBounds: null }