From eca4d7891a410aace11a622b4599c8da26c8de95 Mon Sep 17 00:00:00 2001 From: fishDog <40156382+Bigfish8@users.noreply.github.com> Date: Fri, 16 Jul 2021 04:50:54 +0800 Subject: [PATCH] chore(compiler-core): reduce unnecessary cache inside v-once (#4112) --- .../__tests__/transforms/vModel.spec.ts | 12 ++++++++++++ .../compiler-core/__tests__/transforms/vOn.spec.ts | 9 +++++++++ .../compiler-core/__tests__/transforms/vOnce.spec.ts | 7 +++++++ packages/compiler-core/src/transform.ts | 2 ++ packages/compiler-core/src/transforms/vModel.ts | 1 + packages/compiler-core/src/transforms/vOn.ts | 4 +++- packages/compiler-core/src/transforms/vOnce.ts | 4 +++- 7 files changed, 37 insertions(+), 2 deletions(-) diff --git a/packages/compiler-core/__tests__/transforms/vModel.spec.ts b/packages/compiler-core/__tests__/transforms/vModel.spec.ts index 8acaa493e..fd611cddf 100644 --- a/packages/compiler-core/__tests__/transforms/vModel.spec.ts +++ b/packages/compiler-core/__tests__/transforms/vModel.spec.ts @@ -425,6 +425,18 @@ describe('compiler: transform v-model', () => { ).not.toBe(NodeTypes.JS_CACHE_EXPRESSION) }) + test('should not cache update handler if it inside v-once', () => { + const root = parseWithVModel( + '
', + { + prefixIdentifiers: true, + cacheHandlers: true + } + ) + expect(root.cached).not.toBe(2) + expect(root.cached).toBe(1) + }) + test('should mark update handler dynamic if it refers slot scope variables', () => { const root = parseWithVModel( '', diff --git a/packages/compiler-core/__tests__/transforms/vOn.spec.ts b/packages/compiler-core/__tests__/transforms/vOn.spec.ts index 24789d16f..fe2f6be78 100644 --- a/packages/compiler-core/__tests__/transforms/vOn.spec.ts +++ b/packages/compiler-core/__tests__/transforms/vOn.spec.ts @@ -530,6 +530,15 @@ describe('compiler: transform v-on', () => { expect(root.cached).toBe(0) }) + test('should not be cached inside v-once', () => { + const { root } = parseWithVOn(`
`, { + prefixIdentifiers: true, + cacheHandlers: true + }) + expect(root.cached).not.toBe(2) + expect(root.cached).toBe(1) + }) + test('inline function expression handler', () => { const { root, node } = parseWithVOn(`
`, { prefixIdentifiers: true, diff --git a/packages/compiler-core/__tests__/transforms/vOnce.spec.ts b/packages/compiler-core/__tests__/transforms/vOnce.spec.ts index d3b74f924..553ac1dfa 100644 --- a/packages/compiler-core/__tests__/transforms/vOnce.spec.ts +++ b/packages/compiler-core/__tests__/transforms/vOnce.spec.ts @@ -80,6 +80,13 @@ describe('compiler: v-once transform', () => { expect(generate(root).code).toMatchSnapshot() }) + // v-once inside v-once should not be cached + test('inside v-once', () => { + const root = transformWithOnce(`
`) + expect(root.cached).not.toBe(2) + expect(root.cached).toBe(1) + }) + // cached nodes should be ignored by hoistStatic transform test('with hoistStatic: true', () => { const root = transformWithOnce(`
`, { diff --git a/packages/compiler-core/src/transform.ts b/packages/compiler-core/src/transform.ts index eb328dcd2..77164f90a 100644 --- a/packages/compiler-core/src/transform.ts +++ b/packages/compiler-core/src/transform.ts @@ -105,6 +105,7 @@ export interface TransformContext parent: ParentNode | null childIndex: number currentNode: RootNode | TemplateChildNode | null + inVOnce: boolean helper(name: T): T removeHelper(name: T): void helperString(name: symbol): string @@ -192,6 +193,7 @@ export function createTransformContext( parent: null, currentNode: root, childIndex: 0, + inVOnce: false, // methods helper(name) { diff --git a/packages/compiler-core/src/transforms/vModel.ts b/packages/compiler-core/src/transforms/vModel.ts index 011e4c620..d55c4c617 100644 --- a/packages/compiler-core/src/transforms/vModel.ts +++ b/packages/compiler-core/src/transforms/vModel.ts @@ -107,6 +107,7 @@ export const transformModel: DirectiveTransform = (dir, node, context) => { if ( !__BROWSER__ && context.prefixIdentifiers && + !context.inVOnce && context.cacheHandlers && !hasScopeRef(exp, context.identifiers) ) { diff --git a/packages/compiler-core/src/transforms/vOn.ts b/packages/compiler-core/src/transforms/vOn.ts index 68fd77b49..42a289bb8 100644 --- a/packages/compiler-core/src/transforms/vOn.ts +++ b/packages/compiler-core/src/transforms/vOn.ts @@ -70,7 +70,7 @@ export const transformOn: DirectiveTransform = ( if (exp && !exp.content.trim()) { exp = undefined } - let shouldCache: boolean = context.cacheHandlers && !exp + let shouldCache: boolean = context.cacheHandlers && !exp && !context.inVOnce if (exp) { const isMemberExp = isMemberExpression(exp.content) const isInlineStatement = !(isMemberExp || fnExpRE.test(exp.content)) @@ -90,6 +90,8 @@ export const transformOn: DirectiveTransform = ( // to scope variables. shouldCache = context.cacheHandlers && + // unnecessary to cache inside v-once + !context.inVOnce && // runtime constants don't need to be cached // (this is analyzed by compileScript in SFC