Skip to content

Commit

Permalink
perf: prevent renderer hot functions being inlined by minifiers
Browse files Browse the repository at this point in the history
Terser will aggressively inline hot functions in renderer.ts in order
to reduce "function" declarations, but the inlining leads to performance
overhead (small, but noticeable in benchmarks).

Since we cannot control user's minifier options, we have to avoid the
deopt in the source code by using arrow functions in hot paths.
  • Loading branch information
yyx990803 committed Feb 14, 2020
1 parent f71a50a commit 629ee75
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 73 deletions.
17 changes: 9 additions & 8 deletions packages/runtime-core/src/hydration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { ComponentInternalInstance } from './component'
import { invokeDirectiveHook } from './directives'
import { warn } from './warning'
import { PatchFlags, ShapeFlags, isReservedProp, isOn } from '@vue/shared'
import { RendererOptions } from './renderer'

// Note: hydration is DOM-specific
// But we have to place it in core due to tight coupling with core - splitting
Expand All @@ -20,9 +21,9 @@ import { PatchFlags, ShapeFlags, isReservedProp, isOn } from '@vue/shared'
// passed in via arguments.
export function createHydrationFunctions(
mountComponent: any, // TODO
patchProp: any // TODO
patchProp: RendererOptions['patchProp']
) {
function hydrate(vnode: VNode, container: Element) {
const hydrate = (vnode: VNode, container: Element) => {
if (__DEV__ && !container.hasChildNodes()) {
warn(`Attempting to hydrate existing markup but container is empty.`)
return
Expand All @@ -34,11 +35,11 @@ export function createHydrationFunctions(
// TODO handle mismatches
// TODO SVG
// TODO Suspense
function hydrateNode(
const hydrateNode = (
node: Node,
vnode: VNode,
parentComponent: ComponentInternalInstance | null = null
): Node | null | undefined {
): Node | null | undefined => {
const { type, shapeFlag } = vnode
vnode.el = node
switch (type) {
Expand Down Expand Up @@ -73,11 +74,11 @@ export function createHydrationFunctions(
}
}

function hydrateElement(
const hydrateElement = (
el: Element,
vnode: VNode,
parentComponent: ComponentInternalInstance | null
) {
) => {
const { props, patchFlag } = vnode
// skip props & children if this is hoisted static nodes
if (patchFlag !== PatchFlags.HOISTED) {
Expand Down Expand Up @@ -124,11 +125,11 @@ export function createHydrationFunctions(
return el.nextSibling
}

function hydrateChildren(
const hydrateChildren = (
node: Node | null | undefined,
vnodes: VNode[],
parentComponent: ComponentInternalInstance | null
): Node | null | undefined {
): Node | null | undefined => {
for (let i = 0; node != null && i < vnodes.length; i++) {
// TODO can skip normalizeVNode in optimized mode
// (need hint on rendered markup?)
Expand Down
Loading

0 comments on commit 629ee75

Please sign in to comment.