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