mirror of https://github.com/vuejs/core.git
fix(vue): properly cache runtime compilation (#12019)
This commit is contained in:
parent
4da688141d
commit
fa0ba24b3a
|
@ -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
|
||||||
|
|
|
@ -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,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in New Issue