1. Design objectives of VUE3 and what optimization has been made

smaller

  • Remove some unused apis
  • Tree-shaking, clipping useless modules and packaging only what is needed, reducing the overall size of the packaging

faster

Mainly reflected in the compilation stage

  • Diff algorithm optimization
  • Static ascension
  • Event listener cache
  • SSR optimization

More friendly

  • TypeScript support

Better type checking + complex type derivation + source jump + problem location + easy debugging

  • composition api

Enhanced code logic organization and reuse capabilities

2. Which aspects can vuE3 performance improve through

Compilation phase

In vue2, each component instance corresponds to a Watcher, which records the data property used as a dependency during component rendering. When the dependency changes, the setter will be triggered and Watcher will be notified so that the associated components can be re-rendered.

Template, dynamic node, static node

  • Diff algorithm optimization

Vue 3 Virtual Dom Diff

Vue3 source diff algorithm address

1) Pretreatment optimization:

Different from the bidirectional traversal of VUe2, VUe3 firstly carries out single traversal of the head and tail for preprocessing optimization

2) Static marking

Vue2 will perform full diff in the patch stage, but some nodes are obviously unchanged, so there is no need to diff. In VUe3, the concept of PatchFlags is proposed to add a flag to possible changes, so that the next change can be directly found and compared with the changed places

export const enum PatchFlags {
  // Dynamic text
  TEXT = 1./ / dynamic class
  CLASS = 1 << 1./ / dynamic style
  STYLE = 1 << 2./ / dynamic props
  PROPS = 1 << 3.// Dynamically changing attributes, such as [attr] = "foo"
  FULL_PROPS = 1 << 4. }Copy the code
  • Static ascension

Vue3 does static promotion for non-updated elements, which are created only once and reused at rendering time

For the template

< span > hello < / span ><div>{{ message }}</div>
Copy the code

Before static lift

export function render(_ctx, _cache, $props, $setup, $data, $options) {
  return (_openBlock(), _createBlock(_Fragment, null, [
    _createVNode("span".null."Hello"),
    _createVNode("div".null, _toDisplayString(_ctx.message), 1 /* TEXT */)].64 /* STABLE_FRAGMENT */))}Copy the code

After static promotion, the static content outside the render function can be reused in the cache every time. At the same time, patchFlag has been tagged, and the static flag value is -1

const _hoisted_1 = /*#__PURE__*/_createVNode("span".null."Hello", -1 /* HOISTED */)

export function render(_ctx, _cache, $props, $setup, $data, $options) {
  return (_openBlock(), _createBlock(_Fragment, null, [
    _hoisted_1,
    _createVNode("div".null, _toDisplayString(_ctx.message), 1 /* TEXT */)].64 /* STABLE_FRAGMENT */))}Copy the code
  • Event listener cache

By default, the binding event behavior is considered dynamic, so it is tracked every time

  • SSR optimization

When static content reaches a certain level, the createstaticVnode method is used to generate a static node on the client side. These static nodes are directly innerHtml, eliminating the need to create objects and render from them

Source code size reduction

Remove some unneeded apis + tree-shaking

Any function in the Composition API is packaged only when it is used, and unused modules are shaken by Tree

Responsive system

In contrast to the performance problems of hijacking Object attributes with Vue2’s Object.defineProperty approach, and the inability to add and delete data attributes in a reactive manner (Vue. Set and vuue. Delete are provided), VUe3 rewrites the reactive system using Proxy

3. Why use Proxy instead of defineProperty

DefineProperty way

function defineReactive(data, key, val){
    const dep = new Dep()
    Object.defineProperty(data, key, {
        get(key){
            if(Dep.target){
                dep.depend
            }
            return val
        },
        set(key, newVal){
            if(val ! == newVal){ val = newVal dep.notify() } } } }Copy the code

The proxy pattern

function reactive(data){
    const observed = new Proxy(obj, {
        get(target, key, receiver) {
            const res = Reflect.get(target, key, receiver)
            return isObject(res) ? reactive(res) : res
        },
        set(target, key, value, receiver) {
            const res = Reflect.set(target, key, value, receiver)
            return res
        },
        deleteProperty(target, key) {
            const res = Reflect.deleteProperty(target, key)
            return res
        }
    })
}
Copy the code

Disadvantages:

Proxy is not compatible with IE, there is no polyfill, defineProperty supports IE9

I guess that’s why vuE3 is not widely used

4. Compare the Options API and Composition API

  • Composition API is superior to Options API in logic organization and reuse
  • Composition apis are almost always functions that allow for better type inference
  • The Composition API is more tree Shaking friendly
  • There is no use of this in the Composition API, reducing the ambiguity of this pointing to the problem

5. The tree shaking principle

Tree Shaking is based on ES6 template syntax (import and exports). It takes advantage of the static compilation of ES6 modules. At compile time, you can determine module dependencies and input and output variables

Tree shaking does two things:

The compilation phase uses ES6 Module to determine which modules have been loaded and which modules and variables are not used or referenced, and then deletes the corresponding code

reference

Vue3 source: github.com/vuejs/vue-n…

Interview guide: github.com/febobo/web-…