我的理解是,只要有一些 DOM 操作,比如插入 DOM 元素,就會觸發回流,并且很可能接著是重繪。如果我錯了,請糾正我。參考MDN Web 檔案,
該window.requestAnimationFrame()方法告訴您要執行的影片,并請求瀏覽器呼叫指定的函式來更新下一個重繪之前,影片中的瀏覽器
requestAnimationFrame(又名 aAF)回呼在瀏覽器即將重繪之前被呼叫。那么這是否意味著如果我們以某種方式設法在這個 rAF 中進行 DOM 操作(編輯:并在最后將另一個 rAF 排入佇列)每次都會觸發回流并因此重繪,我們將陷入無限回圈而不實際渲染任何東西螢屏上。
或者,一旦瀏覽器決定進行重繪,它是否會堅持下去并在下一次重繪中應用 RAF 回呼中發生的任何更新?
uj5u.com熱心網友回復:
每當有一些 DOM 操作(例如插入 DOM 元素)時,都會觸發回流,并且很可能隨后是重繪
繪制動作是異步發生的,所以“觸發”應該這樣理解。首先,您的 JavaScript 代碼將在實際發生之前完成。
如果我們以某種方式設法在這個 rAF 中執行 DOM 操作(編輯:并在最后將另一個 rAF 排入佇列)每次都會觸發回流并因此重繪,我們將陷入無限回圈,而實際上不會在螢屏上渲染任何內容。
重繪的需求不斷累積,無法同步滿足。首先,您的代碼必須完成,直到呼叫堆疊為空。所以這里沒有無限回圈。
或者,一旦瀏覽器決定進行重繪,它是否會堅持下去并在下一次重繪中應用 RAF 回呼中發生的任何更新?
是的。當呼叫 RAF 回呼時,該代碼獲得了對 DOM 進行更新的最后機會,這可能會進一步積累繪制的需求。如果在該回呼中您還在 RAF 上注冊了另一個回呼,它不會在那個時候執行,但稍后:瀏覽器將在下一次準備它的重繪任務——所以不是當前的。
簡化示例
假設您有以下代碼:
requestAnimationFrame(update);
myElement.style.backgroundColor = "silver"; // This queues a need for repaint
function update() {
// This queues a need for repaint
myElement.style.width = Math.floor(Math.random() * 100) "px";
requestAnimationFrame(update);
}
當它執行時,我們得到以下序列:
update注冊為回呼- 背景變化安排需要重新粉刷
- 呼叫堆疊變空
- 瀏覽器開始它的重繪作業,但考慮到有一個已注冊的回呼。所以它洗掉了這個注冊(因為它應該只運行一次)并
update在做任何其他事情之前執行。 - 寬度變化安排需要重新繪制。更改串列現在包括背景更改和此寬度更改以及已計算的任何級聯效果。(如何表示取決于瀏覽器)
- 該
update函式再次注冊為回呼。 - 瀏覽器現在檢查它需要做什么作為這個重繪作業的一部分,并執行所有需要的操作來可視化背景和寬度變化的效果。
- 油漆作業結束。剩下的就是注冊的
update回呼。 - 當瀏覽器執行下一個繪制周期時,我們從第 4 步重新開始,但現在不再有排隊的背景更改。其余的將是相同的程序。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/363592.html
標籤:javascript dom 重新粉刷 请求动画帧 回流
