日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

细谈页面回流与重绘

發(fā)布時間:2025/3/8 65 豆豆
生活随笔 收集整理的這篇文章主要介紹了 细谈页面回流与重绘 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

你將了解到:

什么是回流 什么是重繪 回流何時發(fā)生 重繪何時發(fā)生 如何避免回流和重繪 復制代碼

帶著上面的問題,我們一探究竟

什么是回流

回流:英文是reflow

當render tree中的一部分(或全部),因為元素的規(guī)模尺寸、布局、隱藏等改變 而需要重新構(gòu)建,這就是回流(reflow) 復制代碼
  • 每個頁面至少回流一次,即頁面首次加載
  • 回流時,瀏覽器會使渲染樹中受到影響的部分失效,并重新構(gòu)造這部分渲染樹
  • 回流完成后,瀏覽器會重新繪制受影響的部分,是重繪過程

什么是重繪

重繪:英文是repaints

當render tree中的一些元素需要更新屬性,而這些屬性只是影響元素的外 觀、風格,而不影響布局(例如:background-color),則稱為重繪(repaints) 復制代碼

特點:回流必將引起重繪,重繪不一定引起回流 回流比重繪的代價更高

回流何時發(fā)生

當頁面布局和幾何屬性改變時就需要回流

下述情況會發(fā)生瀏覽器回流:

(1)添加或者刪除可見的DOM元素; (2)元素位置改變; (3)元素尺寸改變——邊距、填充、邊框、寬度和高度 (4)內(nèi)容改變——比如文本改變或者圖片大小改變而引起的計算值寬度和高度改變; (5)頁面渲染初始化; (6)瀏覽器窗口尺寸改變——resize事件發(fā)生時; 復制代碼let box = document.getElementById("box").style; box.padding = "2px"; // 回流+重繪 box.border = "1px solid red"; // 再一次 回流+重繪 box.fontSize = "14px"; // 回流+重繪 document.getElementById("box").appendChild(document.createTextNode('abc!')); 復制代碼

重繪何時發(fā)生

元素的屬性或者樣式發(fā)生變化。

let box = document.getElementById("box").style; box.color = "red"; // 重繪 box.backgroud-color = "blue"; // 重繪 document.getElementById("box").appendChild(document.createTextNode('abc!')); 復制代碼

因回流的開銷較大,如果每個操作都去回流重繪的話,瀏覽器可能就會受不了。所以很多瀏覽器都會優(yōu)化這些操作。

多次的回流、重繪變成一次回流重繪:

瀏覽器會維護1個隊列,把所有會引起回流、重繪的操作放入這個隊列,等 隊列中的操作到了一定的數(shù)量或者到了一定的時間間隔,瀏覽器就會flush 隊列,進行一個批處理。 復制代碼

但是有時上面的方法會失效,原因是:

有些情況,當請求向瀏覽器請求一些style信息的時候,就會讓瀏覽器強制flush隊列,比如:(1)offsetTop, offsetLeft, offsetWidth, offsetHeight (2) scrollTop/Left/Width/Height (3)clientTop/Left/Width/Height (4)width,height (5)請求了getComputedStyle(), 或者 IE的 currentStyle 復制代碼

當你請求上面的一些屬性的時候,瀏覽器為了給你最精確的值,需要flush隊列,因為隊列中可能會有影響到這些值的操作。即使你獲取元素的布局和樣式信息跟最近發(fā)生或改變的布局信息無關(guān),瀏覽器都會強行刷新渲染隊列。

這樣以來,瀏覽器的優(yōu)化就顯得力不從心,所以我們需要一些方法,盡可能的避免或減少瀏覽器的回流、重繪

如何避免、減少回流和重繪

  • 減少對render tree的操作【合并多次多DOM和樣式的修改】
  • 減少對一些style信息的請求,盡量利用好瀏覽器的優(yōu)化策略
(1)添加css樣式,而不是利用js控制樣式 (2)讓要操作的元素進行“離線處理”,處理完后一起更新當用DocumentFragment進行緩存操作,引發(fā)一次回流和重繪使用display:none技術(shù),只引發(fā)兩次回流和重繪使用cloneNode(true or false)和replaceChild技術(shù),引發(fā)一次回流和重繪 (3)直接改變className,如果動態(tài)改變樣式,則使用cssText(考慮沒有優(yōu)化的瀏覽器)// badelem.style.left = x + "px";elem.style.top = y + "px";// goodelem.style.cssText += ";left: " + x + "px;top: " + y + "px;"; (4)不要經(jīng)常訪問會引起瀏覽器flush隊列的屬性,如果你確實要訪問,利用緩存// badfor (var i = 0; i < len; i++) {el.style.left = el.offsetLeft + x + "px";el.style.top = el.offsetTop + y + "px";}// goodvar x = el.offsetLeft,y = el.offsetTop;for (var i = 0; i < len; i++) {x += 10;y += 10;el.style = x + "px";el.style = y + "px";} (5)讓元素脫離動畫流,減少回流的Render Tree的規(guī)模$("#block1").animate({left:50});$("#block2").animate({marginLeft:50}); (6)將需要多次重排的元素,position屬性設為absolute或fixed,這樣此元素就脫離了文檔流,它的變化不會影響到其他元素。例如有動畫效果的元素就最好設置為絕對定位; (7)避免使用table布局:盡量不要使用表格布局,如果沒有定寬表格一列的寬度由最寬的一列決定,那么很可能在最后一行的寬度超出之前的列寬,引起整體回流造成table可能需要多次計算才能確定好其在渲染樹中節(jié)點的屬性,通常要花3倍于同等元素的時間。 (8)盡量將需要改變DOM的操作一次完成let box = document.getElementById("box").style;// badbox.color = "red"; // 重繪box.size = "14px"; // 回流、重繪// goodbox.bord = '1px solid red' (9)盡可能在DOM樹的最末端改變class,盡可能在DOM樹的里面改變class(可以限制回流的范圍) (10)IE中避免使用JavaScript表達式 復制代碼

參考資料:

  • 前端進階(二)重繪和回流
  • 重繪與回流
  • 頁面的重繪與回流,以及如何優(yōu)化

轉(zhuǎn)載于:https://juejin.im/post/5c87bd375188257e3e47fdc5

總結(jié)

以上是生活随笔為你收集整理的细谈页面回流与重绘的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。