fix(vue): properly cache runtime compilation (#12019)

This commit is contained in:
edison 2024-09-26 17:05:37 +08:00 committed by GitHub
parent 4da688141d
commit fa0ba24b3a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 27 additions and 34 deletions

View File

@ -18,6 +18,7 @@ import { createCache } from './cache'
import type { ImportBinding } from './compileScript' import type { ImportBinding } from './compileScript'
import { isImportUsed } from './script/importUsageCheck' import { isImportUsed } from './script/importUsageCheck'
import type { LRUCache } from 'lru-cache' import type { LRUCache } from 'lru-cache'
import { genCacheKey } from '@vue/shared'
export const DEFAULT_FILENAME = 'anonymous.vue' export const DEFAULT_FILENAME = 'anonymous.vue'
@ -103,24 +104,14 @@ export const parseCache:
| Map<string, SFCParseResult> | Map<string, SFCParseResult>
| LRUCache<string, SFCParseResult> = createCache<SFCParseResult>() | LRUCache<string, SFCParseResult> = createCache<SFCParseResult>()
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( export function parse(
source: string, source: string,
options: SFCParseOptions = {}, options: SFCParseOptions = {},
): SFCParseResult { ): SFCParseResult {
const sourceKey = genCacheKey(source, options) const sourceKey = genCacheKey(source, {
...options,
compiler: { parse: options.compiler?.parse },
})
const cache = parseCache.get(sourceKey) const cache = parseCache.get(sourceKey)
if (cache) { if (cache) {
return cache return cache

View File

@ -208,3 +208,12 @@ export function genPropsAccessExp(name: string): string {
? `__props.${name}` ? `__props.${name}`
: `__props[${JSON.stringify(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,
)
)
}

View File

@ -12,7 +12,13 @@ import {
registerRuntimeCompiler, registerRuntimeCompiler,
warn, warn,
} from '@vue/runtime-dom' } 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 type { InternalRenderFunction } from 'packages/runtime-core/src/component'
import * as runtimeDom from '@vue/runtime-dom' import * as runtimeDom from '@vue/runtime-dom'
import { import {
@ -35,7 +41,7 @@ function compileToFunction(
} }
} }
const key = template const key = genCacheKey(template, options)
const cached = compileCache[key] const cached = compileCache[key]
if (cached) { if (cached) {
return cached return cached

View File

@ -13,9 +13,9 @@ import {
} from '@vue/runtime-dom' } from '@vue/runtime-dom'
import * as runtimeDom from '@vue/runtime-dom' import * as runtimeDom from '@vue/runtime-dom'
import { import {
EMPTY_OBJ,
NOOP, NOOP,
extend, extend,
genCacheKey,
generateCodeFrame, generateCodeFrame,
isString, isString,
} from '@vue/shared' } from '@vue/shared'
@ -25,19 +25,7 @@ if (__DEV__) {
initDev() initDev()
} }
const compileCache = new WeakMap< const compileCache: Record<string, RenderFunction> = Object.create(null)
CompilerOptions,
Record<string, RenderFunction>
>()
function getCache(options?: CompilerOptions) {
let c = compileCache.get(options ?? EMPTY_OBJ)
if (!c) {
c = Object.create(null) as Record<string, RenderFunction>
compileCache.set(options ?? EMPTY_OBJ, c)
}
return c
}
function compileToFunction( function compileToFunction(
template: string | HTMLElement, template: string | HTMLElement,
@ -52,9 +40,8 @@ function compileToFunction(
} }
} }
const key = template const key = genCacheKey(template, options)
const cache = getCache(options) const cached = compileCache[key]
const cached = cache[key]
if (cached) { if (cached) {
return cached return cached
} }
@ -111,7 +98,7 @@ function compileToFunction(
// mark the function as runtime compiled // mark the function as runtime compiled
;(render as InternalRenderFunction)._rc = true ;(render as InternalRenderFunction)._rc = true
return (cache[key] = render) return (compileCache[key] = render)
} }
registerRuntimeCompiler(compileToFunction) registerRuntimeCompiler(compileToFunction)