十三:DOM的回流重繪

傳統操作DOM消耗性能的原因:DOM的回流(重排)和重繪
  • 回流:當頁面的布局或者幾何信息發生變化,瀏覽器可能需要重新創建DOM樹或者重新計算每一個元素在視口中的位置和大小(重新Layout),重新計算完成后,讓瀏覽器重新渲染
    • 回流必然會引發重繪
    • DOM元素的增刪改導致的DOM結構變化
    • DOM的樣式(例如:大小或者位置等)發生改變
    • 瀏覽器窗口大小改變(視口改變)
    • 頁面第一次加載必然會有一次回流
  • 重繪
    • 元素樣式發生改變,但是幾何信息和結構信息沒有改變,此時不需要回流,只需要瀏覽器把改變的元素重新渲染即可( color / background-color等)

需求:向#box盒子中動態插入5個span

// 當前代碼會引發5次回流
for (let i = 1; i <= 5; i++) {
    let span = document.createElement('span');
    span.innerHTML = i;
    box.appendChild(span);

優化思路:

  • createDocumentFragment 文檔碎片
let frag = document.createDocumentFragment();
for (let i = 1; i <= 5; i++) {
    let span = document.createElement('span');
    span.innerHTML = i;
    frag.appendChild(span);
}
box.appendChild(frag);
frag = null;
  • 字符串拼接
let str = ``;
for (let i = 1; i <= 5; i++) {
    str += `<span>${i}</span>`;
}
box.innerHTML = str;
現代瀏覽器為了減少樣式更改所引發的回流,都新增了“瀏覽器的渲染隊列”機制
  • 上一行代碼是修改元素的樣式,此時并沒有直接通知瀏覽器去渲染,首先把它放置在瀏覽器渲染隊列中,繼續向下執行,把執行中遇到的修改樣式的操作全部放置到瀏覽器的渲染隊列中
  • 如果不在有修改樣式的操作,或者遇到了獲取樣式的操作(盒子模型或者獲取樣式),則中斷向隊列中存放的操作,把現有的先渲染一次(引發一次回流),繼續向下執行代碼 = >我們應該“讀寫分離”:把設置樣式和獲取樣式的操作分離開
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容