vue為什麼是非同步渲染

2022-12-21 14:00:29

原因:可以提升效能。如果不採用非同步更新,那麼每次更新資料都會對當前元件進行重新渲染;所以為了效能考慮,Vue會在本輪資料更新後,再去非同步更新檢視,而不是每當有資料更新,就立即更新檢視。

本教學操作環境:windows7系統、vue3版,DELL G3電腦。

1、nextTick()的原理及作用

nextTick確保我們所操作的DOM是更新之後的。

(1)應用場景在檢視更新之後,基於新的檢視進行操作。

  • 在資料變化後執行的某個操作,而這個操作需要使用隨資料變化而變化的DOM結構的時候,這個操作就需要放在nextTick()的回撥函數中。
  • 如果在created()勾點進行DOM操作,created()中dom還沒有渲染,一定要放在nextTick()的回撥函數中。
  • Vue採用了資料驅動檢視的思想,但是在一些情況下,仍然需要操作DOM。有時候,DOM1的資料發生了變化,而DOM2需要從DOM1中獲取資料,那這時就會發現DOM2的檢視並沒有更新,這時就需要用到了nextTick了。

(2)原理:

  • nextTick 的核心是利用瞭如 Promise 、MutationObserver、setImmediate、setTimeout的原生 JS 方法來模擬對應的微/宏任務的實現;
  • 本質是為了利用 JS的這些非同步回撥任務佇列實現 Vue 框架中自己的非同步回撥佇列;
  • 本質是對JS執行原理事件迴圈的一種應用

nextTick 是典型的將底層JS執行原理應用到具體案例中的範例,引入非同步更新佇列機制的原因∶

如果不採用非同步更新,那麼每次更新資料都會對當前元件進行重新渲染。所以為了效能考慮,Vue 會在本輪資料更新後,再去非同步更新檢視。而不是每當有資料更新,就立即更新檢視。

  • 為了在資料更新操作之後操作DOM,我們可以在資料變化之後立即使用nextTick(callback)
  • nextTick()將回撥延遲到下一個事件迴圈開始時執行, 這樣回撥函數會在DOM更新完成後被呼叫,就可以拿到最新的DOM元素了。

當你設定 vm.someData = 'new value',DOM 並不會馬上更新,而是在非同步佇列被清除,也就是下一個事件迴圈開始時執行更新才會進行必要的DOM更新。

(3) vue的降級策略

Vue 在內部對非同步佇列嘗試使用原生的 Promise.then、MutationObserver setImmediate,如果執行環境不支援,則會採用 setTimeout(fn, 0) 代替,進行降級處理。降級處理的目的都是將flushCallbacks函數放入微任務或者宏任務佇列,等待下一次事件迴圈時來執行

實際重新整理佇列是有可能在本次事件迴圈的微任務中重新整理的,也可能是在下一個事件迴圈中重新整理的。這取決於程式碼當前執行的環境,如若當前執行環境支援promise,那麼nextTick內部實際會用Promise去執行,那麼佇列重新整理就會在本次事件迴圈的微任務中去執行。

優先選擇微任務的原因:微任務中更新佇列是會比在宏任務中更新少一次UI渲染的

2、為何Vue採用非同步渲染

vue是元件級更新元件內有資料變化時,該元件就會更新。例:this.a = 1、this.b=2(同一個watcher)

(1)原因:如果不採用非同步更新,那麼每次更新資料都會對當前元件進行重新渲染。所以為了效能考慮,Vue 會在本輪資料更新後,再去非同步更新檢視。而不是每當有資料更新,就立即更新檢視。

(2)過程:

  • Vue是非同步執行dom更新的,一旦觀察到資料變化,Vue就會開啟一個佇列,然後把在同一個事件迴圈 (event loop) 中 觀察到資料變化的 watcher 推播進這個佇列。

  • 如果這個watcher被觸發多次,只會被推播到佇列一次。這種緩衝行為可以有效的去掉重複資料,避免不必要的計算和Dom操作。

  • 而在下一個事件迴圈時,Vue會清空佇列,並進行必要的DOM更新。

3)原始碼解析:

  • 資料變化時,通過notify通知watcher進行更新操作;

  • 通過subs[i].update依次呼叫watcher的update(未更新檢視);

  • 將watcher放到佇列中,在queueWatcher會根據watcher的id進行去重(多個屬性依賴一個watcher),如果佇列中沒有該watcher就會將該watcher新增到佇列中(未更新檢視);

  • 通過nextTick非同步執行flushSchedulerQueue方法重新整理watcher佇列(更新檢視);

1.png

【相關推薦:、】

以上就是vue為什麼是非同步渲染的詳細內容,更多請關注TW511.COM其它相關文章!