Mind mapping
preface
In the last section, we implemented the process that the page would automatically trigger the update when we changed the attribute value. In this section, we need to consider that we can avoid rendering multiple times when we modify the same attribute for many times, so we adopted the process of asynchronously updating the page internally.
The body of the
For example,
var vm = new Vue({
el: '#app'.data: {
name: 'Ming'.age: 20
}
})
vm.name = 'morning'
vm.name = 'morning 1'
vm.name = 'morning 2'
vm.name = 'morning 3'
Copy the code
watcher.js
update() {
// Will be updated several times
this.get()
}
Copy the code
We can see that the function to re-render the page has been executed four times,vue
In order to consider the performance of the page at the time of implementation, it has done some internal optimization. Let’s take a look.
Batch asynchronous rendering
watcher.js
class Watcher {
/ /...
update() {
// Will be updated several times
queueWatcher(this)}run() {
console.log('update')
this.get()
}
}
Copy the code
+scheduler.js
import { nextTick } from ".. /utils"
let queue = [] // Store the watcher to update
let has = {} // Check for duplicate watcher
let pending = false
function flushSchedulerQueue() {
queue.forEach(watcher= > watcher.run())
queue = []
has = {}
pending = false
}
export function queueWatcher(watcher) {
let id = watcher.id
if (has[id] === undefined) {
has[id] = true
queue.push(watcher)
if(! pending) { nextTick(flushSchedulerQueue) pending =true}}}Copy the code
$nextTick
init.js
Vue.prototype.$nextTick = nextTick
Copy the code
Vm.$nextTink with asynchronous updates in a microtask
util.js
// We used to start a promise microtask for each asynchronous update. Now we need to optimize for multiple asynchronous updates to start only one microtask
let callbacks = []
let waiting = false
// The synchronization code is executed only after it is completed.
function flushCallbacks() {
callbacks.forEach(fn= > fn())
callbacks = []
waiting = false
}
export function nextTick(fn) {
callbacks.push(fn)
if(! waiting) {Promise.resolve().then(flushCallbacks)
waiting = true}}// nextTick() is a promise then()
Copy the code
summary
This section mainly deals with the asynchronous update after the object property changes, and the next section mainly writes the dependency collection of arrays.
Links to a series of articles (constantly updated…)
Vue source exploration (a) responsive principle
Vue source exploration (two) template compilation
A preliminary study of Vue source code (3) Single component mount (rendering)
Vue source exploration (four) dependent (object) collection process
Object asynchronous update nextTick()