From 9a59ceeb7abf0e39c875b3dc41dbe8cc59dc3e0f Mon Sep 17 00:00:00 2001 From: daiwei Date: Tue, 24 Sep 2024 21:11:29 +0800 Subject: [PATCH] fix(vue): properly cache runtime compilation --- packages/compiler-sfc/src/parse.ts | 19 +++++-------------- packages/shared/src/general.ts | 9 +++++++++ packages/vue-compat/src/index.ts | 10 ++++++++-- packages/vue/src/index.ts | 23 +++++------------------ 4 files changed, 27 insertions(+), 34 deletions(-) diff --git a/packages/compiler-sfc/src/parse.ts b/packages/compiler-sfc/src/parse.ts index 32c26d3acac..c8be865508f 100644 --- a/packages/compiler-sfc/src/parse.ts +++ b/packages/compiler-sfc/src/parse.ts @@ -18,6 +18,7 @@ import { createCache } from './cache' import type { ImportBinding } from './compileScript' import { isImportUsed } from './script/importUsageCheck' import type { LRUCache } from 'lru-cache' +import { genCacheKey } from '@vue/shared' export const DEFAULT_FILENAME = 'anonymous.vue' @@ -103,24 +104,14 @@ export const parseCache: | Map | LRUCache = createCache() -function genCacheKey(source: string, options: SFCParseOptions): string { - return ( - source + - JSON.stringify( - { - ...options, - compiler: { parse: options.compiler?.parse }, - }, - (_, val) => (typeof val === 'function' ? val.toString() : val), - ) - ) -} - export function parse( source: string, options: SFCParseOptions = {}, ): SFCParseResult { - const sourceKey = genCacheKey(source, options) + const sourceKey = genCacheKey(source, { + ...options, + compiler: { parse: options.compiler?.parse }, + }) const cache = parseCache.get(sourceKey) if (cache) { return cache diff --git a/packages/shared/src/general.ts b/packages/shared/src/general.ts index 552b447064c..9c6a2313240 100644 --- a/packages/shared/src/general.ts +++ b/packages/shared/src/general.ts @@ -208,3 +208,12 @@ export function genPropsAccessExp(name: string): string { ? `__props.${name}` : `__props[${JSON.stringify(name)}]` } + +export function genCacheKey(source: string, options: any): string { + return ( + source + + JSON.stringify(options, (_, val) => + typeof val === 'function' ? val.toString() : val, + ) + ) +} diff --git a/packages/vue-compat/src/index.ts b/packages/vue-compat/src/index.ts index 639ccfd94c6..d7e9695d824 100644 --- a/packages/vue-compat/src/index.ts +++ b/packages/vue-compat/src/index.ts @@ -12,7 +12,13 @@ import { registerRuntimeCompiler, warn, } from '@vue/runtime-dom' -import { NOOP, extend, generateCodeFrame, isString } from '@vue/shared' +import { + NOOP, + extend, + genCacheKey, + generateCodeFrame, + isString, +} from '@vue/shared' import type { InternalRenderFunction } from 'packages/runtime-core/src/component' import * as runtimeDom from '@vue/runtime-dom' import { @@ -35,7 +41,7 @@ function compileToFunction( } } - const key = template + const key = genCacheKey(template, options) const cached = compileCache[key] if (cached) { return cached diff --git a/packages/vue/src/index.ts b/packages/vue/src/index.ts index 35077b3cf63..785f3fd4bb4 100644 --- a/packages/vue/src/index.ts +++ b/packages/vue/src/index.ts @@ -13,9 +13,9 @@ import { } from '@vue/runtime-dom' import * as runtimeDom from '@vue/runtime-dom' import { - EMPTY_OBJ, NOOP, extend, + genCacheKey, generateCodeFrame, isString, } from '@vue/shared' @@ -25,19 +25,7 @@ if (__DEV__) { initDev() } -const compileCache = new WeakMap< - CompilerOptions, - Record ->() - -function getCache(options?: CompilerOptions) { - let c = compileCache.get(options ?? EMPTY_OBJ) - if (!c) { - c = Object.create(null) as Record - compileCache.set(options ?? EMPTY_OBJ, c) - } - return c -} +const compileCache: Record = Object.create(null) function compileToFunction( template: string | HTMLElement, @@ -52,9 +40,8 @@ function compileToFunction( } } - const key = template - const cache = getCache(options) - const cached = cache[key] + const key = genCacheKey(template, options) + const cached = compileCache[key] if (cached) { return cached } @@ -111,7 +98,7 @@ function compileToFunction( // mark the function as runtime compiled ;(render as InternalRenderFunction)._rc = true - return (cache[key] = render) + return (compileCache[key] = render) } registerRuntimeCompiler(compileToFunction)