Skip to content

Commit 929c16f

Browse files
committed
slightly improve ssr hydration performance
1 parent 9cfd63a commit 929c16f

File tree

2 files changed

+24
-19
lines changed

2 files changed

+24
-19
lines changed

src/core/vdom/patch.js

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
import config from '../config'
1616
import VNode from './vnode'
17-
import { isPrimitive, _toString, warn } from '../util/index'
17+
import { makeMap, isPrimitive, _toString, warn } from '../util/index'
1818
import { activeInstance } from '../instance/lifecycle'
1919
import { registerRef } from './modules/ref'
2020

@@ -468,6 +468,11 @@ export function createPatchFunction (backend) {
468468
}
469469

470470
let bailed = false
471+
// list of modules that can skip create hook during hydration because they
472+
// are already rendered on the client or has no need for initialization
473+
const isRenderedModule = makeMap('attrs,style,class,staticClass,staticStyle,key')
474+
475+
// Note: this is a browser-only function so we can assume elms are DOM nodes.
471476
function hydrate (elm, vnode, insertedVnodeQueue) {
472477
if (process.env.NODE_ENV !== 'production') {
473478
if (!assertNodeMatch(elm, vnode)) {
@@ -486,36 +491,40 @@ export function createPatchFunction (backend) {
486491
}
487492
if (isDef(tag)) {
488493
if (isDef(children)) {
489-
const childNodes = nodeOps.childNodes(elm)
490494
// empty element, allow client to pick up and populate children
491-
if (!childNodes.length) {
495+
if (!elm.hasChildNodes()) {
492496
createChildren(vnode, children, insertedVnodeQueue)
493497
} else {
494498
let childrenMatch = true
495-
if (childNodes.length !== children.length) {
496-
childrenMatch = false
497-
} else {
498-
for (let i = 0; i < children.length; i++) {
499-
if (!hydrate(childNodes[i], children[i], insertedVnodeQueue)) {
500-
childrenMatch = false
501-
break
502-
}
499+
let childNode = elm.firstChild
500+
for (let i = 0; i < children.length; i++) {
501+
if (!childNode || !hydrate(childNode, children[i], insertedVnodeQueue)) {
502+
childrenMatch = false
503+
break
503504
}
505+
childNode = childNode.nextSibling
504506
}
505-
if (!childrenMatch) {
507+
// if childNode is not null, it means the actual childNodes list is
508+
// longer than the virtual children list.
509+
if (!childrenMatch || childNode) {
506510
if (process.env.NODE_ENV !== 'production' &&
507511
typeof console !== 'undefined' &&
508512
!bailed) {
509513
bailed = true
510514
console.warn('Parent: ', elm)
511-
console.warn('Mismatching childNodes vs. VNodes: ', childNodes, children)
515+
console.warn('Mismatching childNodes vs. VNodes: ', elm.childNodes, children)
512516
}
513517
return false
514518
}
515519
}
516520
}
517521
if (isDef(data)) {
518-
invokeCreateHooks(vnode, insertedVnodeQueue)
522+
for (const key in data) {
523+
if (!isRenderedModule(key)) {
524+
invokeCreateHooks(vnode, insertedVnodeQueue)
525+
break
526+
}
527+
}
519528
}
520529
}
521530
return true
@@ -525,7 +534,7 @@ export function createPatchFunction (backend) {
525534
if (vnode.tag) {
526535
return (
527536
vnode.tag.indexOf('vue-component') === 0 ||
528-
vnode.tag.toLowerCase() === nodeOps.tagName(node).toLowerCase()
537+
vnode.tag.toLowerCase() === node.tagName.toLowerCase()
529538
)
530539
} else {
531540
return _toString(vnode.text) === node.data

src/platforms/weex/runtime/node-ops.js

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,6 @@ export function setTextContent (node, text) {
6969
node.parentNode.setAttr('value', text)
7070
}
7171

72-
export function childNodes (node) {
73-
return node.pureChildren
74-
}
75-
7672
export function setAttribute (node, key, val) {
7773
node.setAttr(key, val)
7874
}

0 commit comments

Comments
 (0)