Skip to content

Commit 9a65959

Browse files
committed
adjust optimizer strategy and avoid marking simple elements as static root
1 parent 8f7c49c commit 9a65959

File tree

3 files changed

+27
-15
lines changed

3 files changed

+27
-15
lines changed

src/compiler/optimizer.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,17 @@ function markStaticRoots (node: ASTNode, isInFor: boolean) {
6363
if (node.static || node.once) {
6464
node.staticInFor = isInFor
6565
}
66-
if (node.static) {
66+
// For a node to qualify as a static root, it should have children that
67+
// are not just static text. Otherwise the cost of hoisting out will
68+
// outweigh the benefits and it's better off to just always render it fresh.
69+
if (node.static && node.children.length && !(
70+
node.children.length === 1 &&
71+
node.children[0].type === 3
72+
)) {
6773
node.staticRoot = true
6874
return
75+
} else {
76+
node.staticRoot = false
6977
}
7078
if (node.children) {
7179
for (let i = 0, l = node.children.length; i < l; i++) {

test/unit/modules/compiler/codegen.spec.js

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,7 @@ describe('codegen', () => {
112112
it('generate slot fallback content', () => {
113113
assertCodegen(
114114
'<slot><div>hi</div></slot>',
115-
`with(this){return _t("default",[_m(0)])}`,
116-
[`with(this){return _h('div',["hi"])}`]
115+
`with(this){return _t("default",[_h('div',["hi"])])}`
117116
)
118117
})
119118

@@ -128,8 +127,7 @@ describe('codegen', () => {
128127
// static
129128
assertCodegen(
130129
'<p class="class1">hello world</p>',
131-
'with(this){return _m(0)}',
132-
[`with(this){return _h('p',{staticClass:"class1"},["hello world"])}`]
130+
`with(this){return _h('p',{staticClass:"class1"},["hello world"])}`,
133131
)
134132
// dynamic
135133
assertCodegen(
@@ -169,8 +167,7 @@ describe('codegen', () => {
169167
it('generate static attrs', () => {
170168
assertCodegen(
171169
'<input name="field1">',
172-
`with(this){return _m(0)}`,
173-
[`with(this){return _h('input',{attrs:{"name":"field1"}})}`]
170+
`with(this){return _h('input',{attrs:{"name":"field1"}})}`
174171
)
175172
})
176173

@@ -297,22 +294,22 @@ describe('codegen', () => {
297294
it('generate component with inline-template', () => {
298295
// have "inline-template'"
299296
assertCodegen(
300-
'<my-component inline-template><p>hello world</p></my-component>',
301-
`with(this){return _h('my-component',{inlineTemplate:{render:function(){with(this){return _m(0)}},staticRenderFns:[function(){with(this){return _h('p',["hello world"])}}]}})}`
297+
'<my-component inline-template><p><span>hello world</span></p></my-component>',
298+
`with(this){return _h('my-component',{inlineTemplate:{render:function(){with(this){return _m(0)}},staticRenderFns:[function(){with(this){return _h('p',[_h('span',["hello world"])])}}]}})}`
302299
)
303300
// "have inline-template attrs, but not having extactly one child element
304301
assertCodegen(
305302
'<my-component inline-template><hr><hr></my-component>',
306-
`with(this){return _h('my-component',{inlineTemplate:{render:function(){with(this){return _m(0)}},staticRenderFns:[function(){with(this){return _h('hr')}}]}})}`
303+
`with(this){return _h('my-component',{inlineTemplate:{render:function(){with(this){return _h('hr')}},staticRenderFns:[]}})}`
307304
)
308305
expect('Inline-template components must have exactly one child element.').toHaveBeenWarned()
309306
})
310307

311308
it('generate static trees inside v-for', () => {
312309
assertCodegen(
313-
`<div><div v-for="i in 10"><span></span></div></div>`,
310+
`<div><div v-for="i in 10"><p><span></span></p></div></div>`,
314311
`with(this){return _h('div',[_l((10),function(i){return _h('div',[_m(0,true)])})])}`,
315-
[`with(this){return _h('span')}`]
312+
[`with(this){return _h('p',[_h('span')])}`]
316313
)
317314
})
318315

test/unit/modules/compiler/optimizer.spec.js

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,18 @@ import { baseOptions } from 'web/compiler/index'
44

55
describe('optimizer', () => {
66
it('simple', () => {
7-
const ast = parse('<h1 id="section1">hello world</h1>', baseOptions)
7+
const ast = parse('<h1 id="section1"><span>hello world</span></h1>', baseOptions)
88
optimize(ast, baseOptions)
99
expect(ast.static).toBe(true) // h1
1010
expect(ast.staticRoot).toBe(true)
11-
expect(ast.children[0].static).toBe(true) // text node
11+
expect(ast.children[0].static).toBe(true) // span
12+
})
13+
14+
it('skip simple nodes', () => {
15+
const ast = parse('<h1 id="section1">hello</h1>', baseOptions)
16+
optimize(ast, baseOptions)
17+
expect(ast.static).toBe(true)
18+
expect(ast.staticRoot).toBe(false) // this is too simple to warrant a static tree
1219
})
1320

1421
it('interpolation', () => {
@@ -197,7 +204,7 @@ describe('optimizer', () => {
197204
})
198205

199206
it('mark static trees inside v-for', () => {
200-
const ast = parse(`<div><div v-for="i in 10"><span>hi</span></div></div>`, baseOptions)
207+
const ast = parse(`<div><div v-for="i in 10"><p><span>hi</span></p></div></div>`, baseOptions)
201208
optimize(ast, baseOptions)
202209
expect(ast.children[0].children[0].staticRoot).toBe(true)
203210
expect(ast.children[0].children[0].staticInFor).toBe(true)

0 commit comments

Comments
 (0)