Skip to content

Commit b69b4a4

Browse files
committed
tweak style merge for performance
1 parent e960cd1 commit b69b4a4

File tree

5 files changed

+34
-29
lines changed

5 files changed

+34
-29
lines changed

flow/vnode.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ declare interface VNodeData {
3737
tag?: string;
3838
staticClass?: string;
3939
class?: any;
40-
staticStyle?: string;
40+
staticStyle?: { [key: string]: any };
4141
style?: Array<Object> | Object;
4242
props?: { [key: string]: any };
4343
attrs?: { [key: string]: string };

src/platforms/web/compiler/modules/style.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/* @flow */
22

33
import { parseText } from 'compiler/parser/text-parser'
4+
import { parseStyleText } from 'web/util/style'
45
import {
56
getAndRemoveAttr,
67
getBindingAttr,
@@ -22,7 +23,7 @@ function transformNode (el: ASTElement, options: CompilerOptions) {
2223
)
2324
}
2425
}
25-
el.staticStyle = JSON.stringify(staticStyle)
26+
el.staticStyle = JSON.stringify(parseStyleText(staticStyle))
2627
}
2728

2829
const styleBinding = getBindingAttr(el, 'style', false /* getStatic */)

src/platforms/web/runtime/modules/style.js

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/* @flow */
22

3-
import { cached, camelize, extend, looseEqual } from 'shared/util'
4-
import { normalizeBindingStyle, getStyle } from 'web/util/style'
3+
import { cached, camelize, extend } from 'shared/util'
4+
import { normalizeStyleBinding, getStyle } from 'web/util/style'
55

66
const cssVarRE = /^--/
77
const setProp = (el, name, val) => {
@@ -43,14 +43,11 @@ function updateStyle (oldVnode: VNodeWithData, vnode: VNodeWithData) {
4343
let cur, name
4444
const el: any = vnode.elm
4545
const oldStyle: any = oldVnode.data.style || {}
46-
const style: Object = normalizeBindingStyle(vnode.data.style || {})
47-
vnode.data.style = extend({}, style)
46+
const style = normalizeStyleBinding(vnode.data.style) || {}
4847

49-
const newStyle: Object = getStyle(vnode, true)
48+
vnode.data.style = style.__ob__ ? extend({}, style) : style
5049

51-
if (looseEqual(el._prevStyle, newStyle)) {
52-
return
53-
}
50+
const newStyle = getStyle(vnode, true)
5451

5552
for (name in oldStyle) {
5653
if (newStyle[name] == null) {
@@ -64,7 +61,6 @@ function updateStyle (oldVnode: VNodeWithData, vnode: VNodeWithData) {
6461
setProp(el, name, cur == null ? '' : cur)
6562
}
6663
}
67-
el._prevStyle = newStyle
6864
}
6965

7066
export default {

src/platforms/web/util/style.js

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import { cached, extend, toObject } from 'shared/util'
44

5-
const parseStyleText = cached(function (cssText) {
5+
export const parseStyleText = cached(function (cssText) {
66
const rs = {}
77
if (!cssText) {
88
return rs
@@ -20,17 +20,21 @@ const parseStyleText = cached(function (cssText) {
2020
return rs
2121
})
2222

23-
function normalizeStyleData (styleData: Object): Object {
24-
const style = normalizeBindingStyle(styleData.style)
25-
const staticStyle = parseStyleText(styleData.staticStyle)
26-
return extend(extend({}, staticStyle), style)
23+
// merge static and dynamic style data on the same vnode
24+
function normalizeStyleData (data: VNodeData): ?Object {
25+
const style = normalizeStyleBinding(data.style)
26+
// static style is pre-processed into an object during compilation
27+
// and is always a fresh object, so it's safe to merge into it
28+
return data.staticStyle
29+
? extend(data.staticStyle, style)
30+
: style
2731
}
2832

29-
export function normalizeBindingStyle (bindingStyle: any): Object {
33+
// normalize possible array / string values into Object
34+
export function normalizeStyleBinding (bindingStyle: any): ?Object {
3035
if (Array.isArray(bindingStyle)) {
3136
return toObject(bindingStyle)
3237
}
33-
3438
if (typeof bindingStyle === 'string') {
3539
return parseStyleText(bindingStyle)
3640
}
@@ -42,25 +46,29 @@ export function normalizeBindingStyle (bindingStyle: any): Object {
4246
* so that parent component's style could override it
4347
*/
4448
export function getStyle (vnode: VNode, checkChild: boolean): Object {
45-
let data = vnode.data
46-
let parentNode = vnode
47-
let childNode = vnode
48-
49-
data = normalizeStyleData(data)
49+
const res = {}
50+
let styleData
5051

5152
if (checkChild) {
53+
let childNode = vnode
5254
while (childNode.child) {
5355
childNode = childNode.child._vnode
54-
if (childNode.data) {
55-
data = extend(normalizeStyleData(childNode.data), data)
56+
if (childNode.data && (styleData = normalizeStyleData(childNode.data))) {
57+
extend(res, styleData)
5658
}
5759
}
5860
}
61+
62+
if ((styleData = normalizeStyleData(vnode.data))) {
63+
extend(res, styleData)
64+
}
65+
66+
let parentNode = vnode
5967
while ((parentNode = parentNode.parent)) {
60-
if (parentNode.data) {
61-
data = extend(data, normalizeStyleData(parentNode.data))
68+
if (parentNode.data && (styleData = normalizeStyleData(parentNode.data))) {
69+
extend(res, styleData)
6270
}
6371
}
64-
return data
72+
return res
6573
}
6674

types/vnode.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ export interface VNodeData {
3838
tag?: string;
3939
staticClass?: string;
4040
class?: any;
41-
staticStyle?: string;
41+
staticStyle?: { [key: string]: any };
4242
style?: Object[] | Object;
4343
props?: { [key: string]: any };
4444
attrs?: { [key: string]: any };

0 commit comments

Comments
 (0)