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-…