国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

掌握瀏覽器重繪(repaint)重排(reflow))-前端進階

nifhlheimr / 1053人閱讀

摘要:就如上面的概念一樣,單單改變元素的外觀,肯定不會引起網頁重新生成布局,但當瀏覽器完成重排之后,將會重新繪制受到此次重排影響的部分。因為隊列中,可能會有影響到這些值的操作,為了給我們最精確的值,瀏覽器會立即重排重繪。

很多人都知道要減少瀏覽器的重排和重繪,但對其中的具體原理以及如何具體操作并不是很了解,當突然提起這個話題的時候,還是會一臉懵逼。希望大家可以耐著性子閱讀本文,仔細琢磨,徹底掌握這個知識點!

博客、前端積累文檔、公眾號、GitHub
網頁生成過程:

HTML被HTML解析器解析成DOM 樹

css則被css解析器解析成CSSOM 樹

結合DOM樹和CSSOM樹,生成一棵渲染樹(Render Tree)

生成布局(flow),即將所有渲染樹的所有節點進行平面合成

將布局繪制(paint)在屏幕上

第四步和第五步是最耗時的部分,這兩步合起來,就是我們通常所說的渲染

網上找了一張圖片,我加了注釋會更直觀一些:

渲染:

網頁生成的時候,至少會渲染一次

在用戶訪問的過程中,還會不斷重新渲染

重新渲染需要重復之前的第四步(重新生成布局)+第五步(重新繪制)或者只有第五個步(重新繪制)。

重排比重繪大:

大,在這個語境里的意思是:誰能影響誰?

重繪:某些元素的外觀被改變,例如:元素的填充顏色

重排:重新生成布局,重新排列元素。

就如上面的概念一樣,單單改變元素的外觀,肯定不會引起網頁重新生成布局,但當瀏覽器完成重排之后,將會重新繪制受到此次重排影響的部分

比如改變元素高度,這個元素乃至周邊dom都需要重新繪制。

也就是說:"重繪"不一定會出現"重排","重排"必然會出現"重繪"

重排(reflow): 概念:

當DOM的變化影響了元素的幾何信息(DOM對象的位置和尺寸大小),瀏覽器需要重新計算元素的幾何屬性,將其安放在界面中的正確位置,這個過程叫做重排。

重排也叫回流,重排的過程以下面這種理解方式更清晰一些:

回流就好比向河里(文檔流)扔了一塊石頭(dom變化),激起漣漪,然后引起周邊水流受到波及,所以叫做回流
常見引起重排屬性和方法

任何會改變元素幾何信息(元素的位置和尺寸大小)的操作,都會觸發重排,下面列一些栗子:

添加或者刪除可見的DOM元素;

元素尺寸改變——邊距、填充、邊框、寬度和高度

內容變化,比如用戶在input框中輸入文字

瀏覽器窗口尺寸改變——resize事件發生時

計算 offsetWidth 和 offsetHeight 屬性

設置 style 屬性的值

常見引起重排屬性和方法
width height margin padding
display border position overflow
clientWidth clientHeight clientTop clientLeft
offsetWudth offsetHeight offsetTop offsetLeft
scrollWidth scrollHeight scrollTop scrollLeft
scrollIntoView() scrollTo() getComputedStyle()
getBoundingClientRect() scrollIntoViewIfNeeded()
重排影響的范圍:

由于瀏覽器渲染界面是基于流失布局模型的,所以觸發重排時會對周圍DOM重新排列,影響的范圍有兩種:

全局范圍:從根節點html開始對整個渲染樹進行重新布局。

局部范圍:對渲染樹的某部分或某一個渲染對象進行重新布局

全局范圍重排


  

hello

Name:BDing

male
  1. coding
  2. loving

當p節點上發生reflow時,hello和body也會重新渲染,甚至h5和ol都會收到影響。

局部范圍重排:

用局部布局來解釋這種現象:把一個dom的寬高之類的幾何信息定死,然后在dom內部觸發重排,就只會重新渲染該dom內部的元素,而不會影響到外界。

盡可能的減少重排的次數、重排范圍:

重排需要更新渲染樹,性能花銷非常大:

它們的代價是高昂的,會破壞用戶體驗,并且讓UI展示非常遲緩,我們需要盡可能的減少觸發重排的次數。

重排的性能花銷跟渲染樹有多少節點需要重新構建有關系:

所以我們應該盡量以局部布局的形式組織html結構,盡可能小的影響重排的范圍。

而不是像全局范圍的示例代碼一樣一溜的堆砌標簽,隨便一個元素觸發重排都會導致全局范圍的重排。

重繪(Repaints):

概念

當一個元素的外觀發生改變,但沒有改變布局,重新把元素外觀繪制出來的過程,叫做重繪。

常見的引起重繪的屬性:

color border-style visibility background
text-decoration background-image background-position background-repeat
outline-color outline outline-style border-radius
outline-width box-shadow background-size
瀏覽器的渲染隊列:

思考以下代碼將會觸發幾次渲染?

div.style.left = "10px";
div.style.top = "10px";
div.style.width = "20px";
div.style.height = "20px";

根據我們上文的定義,這段代碼理論上會觸發4次重排+重繪,因為每一次都改變了元素的幾何屬性,實際上最后只觸發了一次重排,這都得益于瀏覽器的渲染隊列機制

當我們修改了元素的幾何屬性,導致瀏覽器觸發重排或重繪時。它會把該操作放進渲染隊列,等到隊列中的操作到了一定的數量或者到了一定的時間間隔時,瀏覽器就會批量執行這些操作。

強制刷新隊列:
div.style.left = "10px";
console.log(div.offsetLeft);
div.style.top = "10px";
console.log(div.offsetTop);
div.style.width = "20px";
console.log(div.offsetWidth);
div.style.height = "20px";
console.log(div.offsetHeight);

這段代碼會觸發4次重排+重繪,因為在console中你請求的這幾個樣式信息,無論何時瀏覽器都會立即執行渲染隊列的任務,即使該值與你操作中修改的值沒關聯。

因為隊列中,可能會有影響到這些值的操作,為了給我們最精確的值,瀏覽器會立即重排+重繪

強制刷新隊列的style樣式請求

offsetTop, offsetLeft, offsetWidth, offsetHeight

scrollTop, scrollLeft, scrollWidth, scrollHeight

clientTop, clientLeft, clientWidth, clientHeight

getComputedStyle(), 或者 IE的 currentStyle

我們在開發中,應該謹慎的使用這些style請求,注意上下文關系,避免一行代碼一個重排,這對性能是個巨大的消耗

重排優化建議

就像上文提到的我們要盡可能的減少重排次數、重排范圍,這樣說很泛,下面是一些行之有效的建議,大家可以參考一下。

1. 分離讀寫操作
div.style.left = "10px";
div.style.top = "10px";
div.style.width = "20px";
div.style.height = "20px";
console.log(div.offsetLeft);
console.log(div.offsetTop);
console.log(div.offsetWidth);
console.log(div.offsetHeight);

還是上面觸發4次重排+重繪的代碼,這次只觸發了一次重排:

在第一個console的時候,瀏覽器把之前上面四個寫操作的渲染隊列都給清空了。剩下的console,因為渲染隊列本來就是空的,所以并沒有觸發重排,僅僅拿值而已。

2. 樣式集中改變
div.style.left = "10px";
div.style.top = "10px";
div.style.width = "20px";
div.style.height = "20px";

雖然現在大部分瀏覽器有渲染隊列優化,不排除有些瀏覽器以及老版本的瀏覽器效率仍然低下:

建議通過改變class或者csstext屬性集中改變樣式

// bad
var left = 10;
var top = 10;
el.style.left = left + "px";
el.style.top  = top  + "px";
// good 
el.className += " theclassname";
// good
el.style.cssText += "; left: " + left + "px; top: " + top + "px;";
3. 緩存布局信息
// bad 強制刷新 觸發兩次重排
div.style.left = div.offsetLeft + 1 + "px";
div.style.top = div.offsetTop + 1 + "px";

// good 緩存布局信息 相當于讀寫分離
var curLeft = div.offsetLeft;
var curTop = div.offsetTop;
div.style.left = curLeft + 1 + "px";
div.style.top = curTop + 1 + "px";
4. 離線改變dom

隱藏要操作的dom

在要操作dom之前,通過display隱藏dom,當操作完成之后,才將元素的display屬性為可見,因為不可見的元素不會觸發重排和重繪。

dom.display = "none"
// 修改dom樣式
dom.display = "block"

通過使用DocumentFragment創建一個dom碎片,在它上面批量操作dom,操作完成之后,再添加到文檔中,這樣只會觸發一次重排。

復制節點,在副本上工作,然后替換它!

5. position屬性為absolute或fixed

position屬性為absolute或fixed的元素,重排開銷比較小,不用考慮它對其他元素的影響

6. 優化動畫

可以把動畫效果應用到position屬性為absolute或fixed的元素上,這樣對其他元素影響較小

動畫效果還應犧牲一些平滑,來換取速度,這中間的度自己衡量:

比如實現一個動畫,以1個像素為單位移動這樣最平滑,但是reflow就會過于頻繁,大量消耗CPU資源,如果以3個像素為單位移動則會好很多。

啟用GPPU加速

此部分來自優化CSS重排重繪與瀏覽器性能

GPU(圖像加速器):

GPU 硬件加速是指應用 GPU 的圖形性能對瀏覽器中的一些圖形操作交給 GPU 來完成,因為 GPU 是專門為處理圖形而設計,所以它在速度和能耗上更有效率。

GPU 加速通常包括以下幾個部分:Canvas2D,布局合成, CSS3轉換(transitions),CSS3 3D變換(transforms),WebGL和視頻(video)。

/*
 * 根據上面的結論
 * 將 2d transform 換成 3d
 * 就可以強制開啟 GPU 加速
 * 提高動畫性能
 */
div {
  transform: translate3d(10px, 10px, 0);
}
結語

重排也是導致DOM腳本執行效率低的關鍵因素之一,重排與重繪作為大廠經常出現的面試題,并且涉及的性能優化,這是前端必須掌握的基本概念/技能之一(敲黑板!)。

重排會不斷觸發這是不可避免的,但我們在開發時,應盡量按照文中的建議來組織代碼,這種優化,需要平時有意識的去做,一點一滴的去做,希望大家重視一下。

希望看完的朋友可以點個喜歡/關注,您的支持是對我最大的鼓勵。

博客、前端積累文檔、公眾號、GitHub

以上2018.12.17

參考資料:

網頁性能管理詳解

優化CSS重排重繪與瀏覽器性能

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/100349.html

相關文章

  • HTML&&CSS基礎知識點整理

    摘要:并減少對樣式的請求。缺點暴露了模塊成員,外部可以修改模塊內部狀態。所有依賴這個模塊的語句,都定義在一個回調函數中,等到加載完成之后,這個回調函數才會運行。 HTML&&CSS基礎知識點整理 一、WEB標準:一系列標準的集合 1. 結構(Structure):html 語言:XHTML[可擴展超文本標識語言]和XML[可擴展標記語言] 2. 表現(Preasentation):css...

    Jeff 評論0 收藏0
  • HTML&&CSS基礎知識點整理

    摘要:并減少對樣式的請求。缺點暴露了模塊成員,外部可以修改模塊內部狀態。所有依賴這個模塊的語句,都定義在一個回調函數中,等到加載完成之后,這個回調函數才會運行。 HTML&&CSS基礎知識點整理 一、WEB標準:一系列標準的集合 1. 結構(Structure):html 語言:XHTML[可擴展超文本標識語言]和XML[可擴展標記語言] 2. 表現(Preasentation):css...

    lindroid 評論0 收藏0
  • 前端工程師手冊】學習回流和重reflowrepaint

    摘要:重繪元素做了一些不影響排版的改變,比如背景色下劃線等等,只需要重新繪制的過程,叫做重繪。顯然回流帶來的代價大于重繪,因為重繪僅僅是重新畫一遍元素而已,但是重繪是重新計算重新畫。不然這會導致大量地讀寫這個結點的屬性。 瀏覽器的大概工作流程 以普通的HTML頁面為例: 解析HTML文檔,生成dom樹 解析css產生css規則樹 解析JavaScript,通過DOM-API來操作dom樹和...

    liuyix 評論0 收藏0
  • 前端工程師手冊】學習回流和重reflowrepaint

    摘要:重繪元素做了一些不影響排版的改變,比如背景色下劃線等等,只需要重新繪制的過程,叫做重繪。顯然回流帶來的代價大于重繪,因為重繪僅僅是重新畫一遍元素而已,但是重繪是重新計算重新畫。不然這會導致大量地讀寫這個結點的屬性。 瀏覽器的大概工作流程 以普通的HTML頁面為例: 解析HTML文檔,生成dom樹 解析css產生css規則樹 解析JavaScript,通過DOM-API來操作dom樹和...

    fish 評論0 收藏0
  • 瀏覽器渲染的那些事(三)

    摘要:瀏覽器會對發生變化的呈現器以及其子代標注為,表示需要進行標記分為兩種和。異步和同步異步,簡單來說,就是指瀏覽器為了盡可能減少和的操作,而將這些操作積攢起來,再統一做一次。 終于到了布局的部分了! 布局 當渲染對象被創建并添加到樹中,是沒有位置和大小的,計算這些值的過程稱為layout或reflow。布局是一個遞歸過程,由根渲染對象開始,對應html文檔元素,布局繼續遞歸的通過一些或所有...

    ralap 評論0 收藏0

發表評論

0條評論

nifhlheimr

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<