About Vue3 Block Tree

2,275 阅读2分钟

Before Start

Before we start(quote from cap),is anyone know about what is mvvm and vdom?cause we will not explain these concepts again in here.

What is Block Tree

As we all know, in Vue3.0,Block Tree is introduced for fastering vdom diff, but what is that and what does it do? Maybe we have heard BlockChain before, but they are two totally deferent things.Block Tree, is an area that anything inside is stable structure.There is a key word stable structure.Why we need that and what is wrong with unstable structure ?

If you ever wrote jsx before, we know a condition or a loop surely change the vdom stucture, so does in Vue2.Yes, we accept and embrace the change, but stucture change mean unstable, and When comes to traverse children , we have to fully traverse them. There is not doubt, if our template scales, any small tiny state change costs more time to patch.Maybe some expeirenced programmers splited the template into small components and claimed this is a better way.Ironiclly, this will not help if a top state is used by a deep level vnode.Why?Because we can't split any more.WTF?Then what should we do ? Just pretend we don't care about that and V8 is so fast enough.Aka, acts like a camel.

Shining come to stage

We have seen the limis of traditional vdom diff, So, let's welcome our super star Block Tree.What we want? Don't be shy, speak loundly.Yes, we need a stragy then makes tree stable so when we do the vdom diff, we only care about the dynamic children and no matter how many levels we encounter, we can skip most useless traverse and just directly patch the dynamic one.Can you imagine that? That means a lot. When we wrote our bussinss code, we just wrote and don't have to worry about how to get a better performance.

As we metion above, a condition or a loop can break the tree stucture. So, we can wrap them into a block, for example, we wrap the condition vdom to a block, if the condition is falsey, we place a placeholder block for them, to the outside, event the upside down, the whole tree is stable, when we do the vdom diff, the order of children never change, we can just patch the dynamic one.That's the whole point! See that!

Vue3 Implements

Ok, talk is cheap, show me the code! A classic Vue template code, when we patch, we just care about the conditoon aa and the interporate hello

<div>
    <div v-if="aa" id="foo">
        <p>{{ hello }}</p>
    </div>
</div>

Let' see the render function Vue3 genarate.v-if have a placeholder block then make the tree stable.

  return (_openBlock(), _createBlock("div", null, [
    (_ctx.aa)
      ? (_openBlock(), _createBlock("div", _hoisted_1, [
          _createVNode("p", null, _toDisplayString(_ctx.hello), 1 /* TEXT */)
        ]))
      : _createCommentVNode("v-if", true)
  ]))
}

With stable stucture, and when we patch, we don't do the fully stupid diff, instead, go to the vip path,just patch the dynamicChildren, that save a lot of time indeed.

 const patchElement = (
    n1: HostVNode,
    n2: HostVNode,
    parentComponent: ComponentInternalInstance | null,
    parentSuspense: HostSuspenseBoundary | null,
    isSVG: boolean,
    optimized: boolean
  ) => {
      ...
      if (dynamicChildren != null) {
      patchBlockChildren(
        n1.dynamicChildren!,
        dynamicChildren,
        el,
        parentComponent,
        parentSuspense,
        areChildrenSVG
      )
    } else if (!optimized) {
      // full diff
      patchChildren(
        n1,
        n2,
        el,
        null,
        parentComponent,
        parentSuspense,
        areChildrenSVG
      )
    }
      ...
  }

Behide the magic, just the Code Design.I think I don't have to explain anymore, just close your eye, touch it and feel it, Vue3 is coming, the spring of frontend is coming.In the end ,thx for reading.