為什麼 Vue 不能及時更新視圖,而 React, Angular 卻可以?

場景很簡單,可視區域有限,但是可滾動區域很長。有一個 div 在裡面滾動,div 里還有內容。我希望內容永遠在 div 在可視區域中的部分里居中。demo 見 這裡。原理也很簡單,就是在 onscroll 中計算出正確的 translateY 然後更新上去。

但是 Vue 做同樣的事情,就會產生卡頓(demo 在這裡)。(在 macOS 的 Chrome 上)它的更新似乎是不及時的,導致會渲染出錯誤的幀(如右下角,Text 所在的 div 根本不居中):

這是 Vue 的一個特性嗎?為什麼 React(demo 在這裡)和 Angular(demo 在這裡)都能「正確」渲染?Vue 背後的考量是什麼?

相關 issue:

Styles are not updated in time · Issue #7707 · vuejs/vue


簡單看了一下 感覺是vue 2.5的一個internal break change導致的時序問題

We have changed the implementation of Vue.nextTick to fix a few bugs (related to #6566, #6690). The change involves using a macro task instead of a micro task to defer DOM updates when inside a DOM event handler attached via v-on. This means any Vue updates triggered by state changes inside v-on handlers will be now deferred using a macro task. This may lead to changes in behavior when dealing with native DOM events.

在 JSFiddle 上驗證了下 , 2.4.x 以下是正常的, 2.5.0開始有卡頓

暫時沒有想到乾淨的workaround


可能與Vue的非同步更新隊列有關,

Vue會將變化的數據緩存在隊列中並過濾重複數據,並在下一個事件循環tick中去渲染DOM。 所以說它的視圖更新其實是非同步的,有很短暫的數據緩存導致的延遲,不過一般是不會被覺察到的。這麼做的目的是減少相同數據重複計算引起的不必要的DOM渲染。


頁面卡頓,肯定是用戶的電腦性能不行


貌似沒有出現卡頓啊 能說下你用的版本嗎


Windows Chrome 上沒感覺到卡頓。


試了一下,沒看到卡頓


並沒有看到卡頓。。


推薦閱讀:

vue.js實例項目有木有?
使用vue.js怎麼寫出輪播圖?
在react 、 vue 、ng 這些框架火起來之前,是哪些框架比較火?它們現在怎麼樣了?

TAG:React | Angular | Vuejs |