Vue3 optimization
Differences of Vue2 and Vue3
Performance
- diff Algorithm
- VNodes in Vue2 will be completely compared
- Vue3 adds a static flag(PatchFlat). While comparing, only nodes with static flags are compared, and the specific comparison content can be learned through the flags
In a word,The pointers on sides both are compared and move to the middle until oldCn or newCn traversed completely. When the object is too large will be slowly
PatchFlag is roughly is divided into two types
- Greater than 0,it’s an element that can be optimized and updated during patch VNode or render
- Less than 0, the element needs full diff
In this way, the element that don’t need to update will only be created by once,and directly reused when render
1 | <div>Hello World!</div> |
1 | import { |
1 | // Patch flags can be combined using the | bitwise operator and can be checked using the & operator, e.g. |
- Cache of events
1 | <button @click="btnClick">SmallStars</button> |
Build of used
Vue3 introduces the Tree shaking feature, which removes useless code when packing, reduces the volume of the packaging, and reduces the execution time of the program
Fragment, Teleport, Suspense
Fragment
Vue2 instance only has only one root node, because it needs to be bound to a DOM element. Fragment label resolved this problem in Vue3, and it doesn’t display in DOM
Teleport
Component Development encourages us build our UIs and actions to into components, these components are combined into a component tree. However, sometimes a part of components’ template belong to those components logically, it would be preferable to move this part to somewhere else in DOM, outside of the Vue app. For example, the modal of full-screen.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
// Add a new anchor point
<div id="modal"></div>
<!-- built files will be auto injected -->
</body>
app.component( 'modal-button', { template: `
<button @click="modalOpen = true">
Open full screen modal! (With teleport!)
</button>
<teleport to="modal">
<div v-if="modalOpen" class="modal">
<div>
<span> Content </span>
<button @click="modalOpen = false">Close</button>
</div>
</div>
</teleport>
`, data() { return { modalOpen: false } } })Suspense
Suspense is a component with slots. Before display content is fully rendered, the alternate content is displayed to occupy the place. If it’s a asynchronous component, Suspense will wait for the components and use onErrorCaptured to capture the error
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26<template>
<h1>{{ result }}</h1>
</template>
<script lang="ts">
import { defineComponent } from "vue";
export default defineComponent({
setup() {
//Suspense needs to return a Promise
return new Promise((resolve) => {
setTimeout(() => {
return resolve({
result: "10000",
});
}, 3000);
});
},
});
</script>
<Suspense>
<template #default>
<async-show />
</template>
<template #fallback>
Loading...
</template>
</Suspense>
Custom Renderer API
Our template code will be converted into the html code through createApp of Vue. Also you can use this ability to render some other things what you need through Vue’s Custom Renderer API
1 | import { createRenderer } from "@vue/runtime-core"; |
The differences of lifecycle
Vue2 | Vue3 |
---|---|
beforeCreate | setup |
created | setup |
beforeMount | onBeforeMount |
mounted | onMounted |
beforeUpdate | onBeforeUpdate |
updated | onUpdated |
beforeDestroy | onBeforeDestroy |
destroyed | onDestroyed |
errorCaptured | onErrorCaptured |
Responsive
1 | // Vue3 Responsive principle |
script setup
https://github.com/vuejs/rfcs/blob/master/active-rfcs/0040-script-setup.md
Proxy & Reflect
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Proxy
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Reflect