preface

In the front end, most people say that vue.js has a very low threshold to get started, and most scenarios in work only need simple and skilled use of API and rely on its open source ecosystem to complete the development of the front end requirements. But the interview is no longer just about your application level, the interviewer also likes to examine the implementation of the principle behind the technology to judge your degree of technical mastery, and whether there is the spirit of technical research. But learning source code is very boring, and abstract, understanding is also more difficult, many people will give up, this article will be combined with the vue. js design and implementation, with a global perspective to see the framework design ideas, I hope to read Vue3 source before you help.

This article directory

(a) basic knowledge framework From two kinds of framework model is introduced to virtual DOM performance situation, to the runtime and compilation of relevant knowledge, and introduces the Vue. Js3 is a runtime and compile time frame (2) the frame design of the core elements From development framework designers considered in the design framework of user experience, volume control framework code, Vue3 design from a global perspective understand vue. js3 design ideas, and how each module collaboration

(4) Vue3 optimization set shows the optimization of VUue. Js 3.0 in the form of mind map from the three dimensions of source optimization, performance optimization and syntax API optimization

Note: the source version of Vue3 cited in this article is"Version" : "3.2.31"

First, basic knowledge of the framework

1.1 Framework paradigm

imperative

Focus on the process. JQuery, for example, has a one-to-one correspondence between natural language descriptions and code

$('#app').text('hello world').on('click'.() = >{console.log(Hello world)})
Copy the code

declarative

Focus on results. Like Vue, which helps us encapsulate the process, the internal implementation is imperative and more declarative to expose to the user

<div @click="()=>{console.log(' Hello world ')}">hello world</div>
Copy the code

1.2 Tradeoff between performance and maintainability

Update performance cost of imperative code = Direct modification performance cost of update performance of declarative code = direct modification + performance cost of finding differences

You can see that declarative code performance is theoretically no better than imperative code performance, but why does vue.js choose a declarative framework? The reason for this is that declarative code is more maintainable, so we don’t have to focus on the process at the time of development, and it shows what we want, which is more intuitive. Of course, when declarative code improves maintainability, there is a certain loss of performance, so most iterations of framework versions are optimized to minimize the loss of performance.

1.3 What is the performance of the virtual DOM

The virtual DOM was created to minimize the performance cost of differentiation, allowing the performance of declarative code to approach that of imperative code indefinitely. The virtual DOM update technology theoretically cannot be higher than the native JS manipulation DOM.

(1) Native JS operations have the highest DOM performance, but the highest mental burden and low code maintainability. You need to manually create, delete and modify a large number of DOM elements. (2) innerHML, which is something like concatenating a string with a native JS binding event, performs worst if the template is large, especially with small updates. (3) Virtual DOM has small mental burden and strong maintainability

Run and compile

As a front end, the framework we use tends to have three types, one is pure run time, run time + compile time, compile time.

At runtime, the framework recurses to a tree structure of data objects, rendering the data into DOM elements like render in vue.js. The tree structure of the data object, is essentially used to describe DOM JS objects, in vue.js can describe different types of nodes, such as common element nodes, component nodes, etc.. Something like this:

const vnode = {
  type: 'button'.props: { 
    'class': 'btn'.style: {
      width: '100px'.height: '50px'}},children: 'click me'
}
Copy the code

The type attribute represents the tag type of the DOM, the props attribute represents some additional information of the DOM, such as style and class, and the children attribute represents a child node of the DOM. It can be an array (representing child nodes) or a string representing simple text.

Of course, we will find that writing tree structure data objects is too cumbersome, and not intuitive, can support the way to describe tree structure objects like HTML tags? Like the following:

<div> 
  <span>hello world</span>
</div>
Copy the code

convert

const vnode = {
  type: 'div'.children:[
    {type:'span'.children:'hello world'}}]Copy the code

To do this, we need to write a Compiler function to compile the tree structure of the data object, and then call the render function to render.

At this point you might be thinking, if the compiler can compile HTML strings into data objects, why not compile them directly into imperative code? Just like vue.js is a compile-time + runtime framework, it is designed to maintain flexibility and analyze user-provided content through compilation methods, so as to further improve update performance.

Second, the core elements of the framework design

2.1 Improve user development experience

For example, friendly warning messages can help users quickly locate problems and save users’ time

2.2 Control the volume of framework code

In the same case, the less code the better, the smaller the volume, and the less time the browser takes to load the resource. Vue. Js prints warnings only in development environments, not production environments. Vue.js each printed warning message has a _DEV_ constant

2.3 Frameworks should be tree-shaking well

Tree-shaking is the removal of code that will never be executed, a concept popularized in the front-end domain by rollup.js and supported by Webpack. But modules must be ESM(ES Module), because tree-shaking depends on the static structure of ESM

If a function is called with parameter side effects, it cannot be removed. Rollup. js and Webpack recognize /*#__PURE__*/ as well as some compression tools

What build artifacts should the framework produce

(1) Immediately called function expression (IIFE)

(function () {
// ...} ())Copy the code

Format :’iife’ in the output format of rollup.js. In Vue, vue.global.js is the iife resource

(2) ESM

Native ESM is now well supported by major browsers, such as Vue3, which outputs vue.ems-browser.js files that can be imported directly with the

<script type='module' src='/path/to/vue.ems-browser.js'></script>
Copy the code

In the rollup.js output format: format:’es’ can be used to output EMS resources, but if you look at the Vue source code, you may see that Vue also has an esM.-bundler.js file.

Why is it designed this way? The answer is that EMS resources with -bundler are used for packaging tools like rollup.js, webpack, vite, etc., while those with -browser are used for

(3) the CJS

In the rollup.js output format: format:’ CJS ‘, output require statement reference resource, server render scene, suitable for running in Node.js

(Note: Source path of this screenshot: core-main\rollup.config.js)

2.4 Feature Switch

(1) Users can turn framework features on and off, and they can not be included in the final project resources through tree-shaking mechanism

(2) Make the framework design bring flexibility, can arbitrarily add new features for the framework through the feature switch

In the vue.js3 source code, we can see a number of feature switches implemented, such as __FEATURE_OPTIONS_API__ controlling whether to write code using the option API or Composition API

  globals: {
    __DEV__: true.__TEST__: true.__VERSION__: require('./package.json').version,
    __BROWSER__: false.__GLOBAL__: false.__ESM_BUNDLER__: true.__ESM_BROWSER__: false.__NODE_JS__: true.__SSR__: true.__FEATURE_OPTIONS_API__: true.__FEATURE_SUSPENSE__: true.__FEATURE_PROD_DEVTOOLS__: false.__COMPAT__: true.'ts-jest': {
      tsconfig: {
        target: 'esnext'.sourceMap: true}}},Copy the code

2.5 Error Handling

Through unified encapsulation of error handling functions, the captured error information is transmitted to users, facilitating users to track and locate problems when using. In vue. js3 source code, we can see the unified error handling function callWithErrorHandling

2.6 Good TypeScript type support

Code is documentation, the compiler automatically prompts, low-level bugs can be avoided to a certain extent, and the code is more maintainable.

3. Design ideas of Vue3

3.1 Declarative UI framework

Vue. Js3 corresponding scheme (1) template

Vue. Js3 corresponding scheme (2) virtual DOM,JS object to describe

import {h} from 'vue'
export default {
  render(){
   return h('h1', {onClick:handler})
  }
}
Copy the code

The h function is a utility function that assists in creating the virtual DOM, and the render function is the component’s render function

3.2 the renderer

The renderer renders the virtual DOM into the real DOM by recursing the virtual DOM object and calling the native DOM API to create the real DOM. The essence of the renderer is the subsequent update, which uses the Diff algorithm to find changes and only updates what needs to be updated.

3.3 The nature of components

A component is a wrapper around a set of DOM elements. It can be a function that returns the virtual DOM, or an object that has a function that produces the virtual DOM that the component needs to render. So the implementation of the component depends on the renderer.

3.4 Working Principles of templates

The compiler parses the template into a rendering function, rendering the virtual DOM returned by the rendering function into the real DOM, and the process of Vue rendering the page. Each module of vue. js is directly related to each other, mutual restriction, together constitute an organic framework as a whole.

Four optimized sets of vue.js 3.0

4.1 Source optimization

4.2 Performance Optimization

(1) source volume optimization

(2) Data hijacking optimization

(3) Compilation optimization

4.3 Syntax API Optimization: Composition API

(1) Optimize logical organization

(2) Optimize logic reuse

The last

As the title says, when you read this article whether to Vue. Js3 source reading learning, will be more suddenly, source learning is a boring process, but when you realize the framework of the door, taste the framework designer’s implementation ideas and details, will be the clouds to see the moonlight, corresponding to your native JavaScript ability will also be improved, So your technical skills will definitely take a step up, and you’ll be in the driver’s seat for promotions, raises, and job changes