整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          6、怎么理解回流跟重繪?什么場景下會觸發?

          6、怎么理解回流跟重繪?什么場景下會觸發?


          • 流:布局引擎會根據各種樣式計算每個盒子在頁面上的大小與位置
          • 重繪:當計算好盒模型的位置、大小及其他屬性后,瀏覽器根據每個盒子特性進行繪制

          聊一下

          小時候最喜歡玩4399小游戲了,放學回家麻溜地打開電腦開始4399之旅。那么當我輸入4399.com到頁面加載完畢,這之間究竟發生了點什么事呢?

          輸入4399.com

          瀏覽器加載到資源

          我們輸入4399.com,按下回車的那一瞬間,命運的齒輪開始轉動

          眾所周知,我們的每一個頁面都是由html、css組成的,所以你可以理解以下過程:

          1. 瀏覽器解析html代碼,生成一個DOM樹
          2. 瀏覽器解析css代碼,生成一個CSSOM樹
          3. 將DOM樹和CSSOM樹結合,去除不可見的元素,生成 Render Tree
          4. 計算布局(回流|重排),根據Render Tree 進行布局的計算,得到每一個節點的幾何信息
          5. 繪制頁面(重繪),GPU根據布局信息繪制

          當頁面重繪完畢后,我們就可以看到4399首頁頁面了

          在上面的流程中,我們可以看到回流和重繪,那么什么是回流,什么又是重繪?

          回流

          1. 什么是回流?
          • 瀏覽器計算頁面布局的過程叫做回流

          在上面提到,在生成Render Tree以后開始計算頁面布局,此時發生的就是回流。我們的屏幕上有許多個物理發光點,在這里就是要計算要讓哪個發光點亮起來,但是此時僅計算而已,要讓屏幕亮起來,還得交給接下來的重繪

          1. 什么時候發生回流
          • 當一個容器的幾何數學發生變更時,頁面會發生回流
          • 1> 改變窗口的尺寸
          • 2> 改變元素的尺寸
          • 3> 增加或者刪除可見元素
          • 4> 頁面初次渲染
          • 5> ...

          重繪

          1. 什么是重繪
          • 將已經計算好布局的容器在屏幕上展現出來

          在回流中,我們已經計算好了要讓哪些發光點亮起來,在重繪中進行的操作就是讓發光點亮起來

          1. 什么時候發生重繪
          • 元素的非幾何屬性變化時,會發生重繪
          • 1> 修改背景顏色
          • 2> 修改背景圖片
          • 3> 修改邊框顏色
          • 4> 修改字體顏色

          理解回流和重繪

          回流主要是時刻注意屏幕上的幾何圖形的變化

          例如,當屏幕上的矩形變成圓形的時候,屏幕上物理發光點的數量和位置肯定要發生變化,此時發生回流, 那么發生重繪嗎?當然,物理發光點的變化肯定會發生重繪的,有些發光點要亮起來,有些要暗下去...

          重繪主要是觀察物理發光點的變化

          此時,我們的物理發光點的位置沒有改變,但是顏色改變,所以只觸發了重繪,而并沒有回流

          總結:

          回流一定重繪,重繪不一定回流

          瀏覽器的優化策略

          由于回流和重繪涉及對頁面進行重新計算和繪制,因此它們可能會消耗大量的計算資源和時間。這可能導致頁面加載速度變慢、頁面響應性能下降,甚至導致卡頓和不流暢的用戶體驗。

          優化策略的目的是減少不必要的回流和重繪,從而提高頁面的性能和用戶體驗。

          當代瀏覽器都有一個渲染隊列機制,當我們改變一個元素的樣式 從而導致瀏覽器需要回流時,這個操作會進入渲染隊列,然后瀏 覽器繼續往下執行代碼,如果還有相同行為,繼續進入隊列,直到 下面沒有樣式修改,瀏覽器會批量化渲染隊列中的回流過程,這只 發生一次回流

          簡而言之,就是一下把所有的回流全都存起來,直到隊列滿了,或者碰到一些要強制執行隊列的東西才開始執行隊列中的回流

          哪些屬性會導致渲染隊列強制執行呢?

          讀取容器幾何信息:

          offsetTop,offsetLeft,offsetWidth,offsetHeight

          clientWidth,clienLeft,clientHeight,clientTop

          ScrollHeight,ScrollTop,ScrollWidth,ScrollLedt

          以上這些屬性全部都會導致瀏覽器的渲染隊列強制執行(當渲染隊列中沒東西時,不觸發回流)

          字節面試題

          以下這段代碼,發生幾次回流?

          <!DOCTYPE html>
          <html lang="en">
          <head>
          <meta charset="UTF-8">
          <meta name="viewport" content="width=device-width, initial-scale=1.0">
          <title>Document</title>
          </head>
          <body>
          <div id="app"></div>
          <script>
          let el=document.getElementById('app')
          el.style.width=(el.offsetWidth + 1) + 'px'
          el.style.width=1 + 'px'
          </script>
          </body>
          </html>

          答案是一次回流

          當運行到el.style.width=(el.offsetWidth + 1) + 'px'時,由于遇到el-offsetWidth,讀取了容器的幾何信息,所以強制執行渲染隊列,但是此時渲染隊列中啥也沒有...于是不執行。

          然后讓el.style.width=(el.offsetWidth + 1) + 'px',此時這段回流往渲染隊列里存入,繼續向下走

          el.style.width=1 + 'px'樣式改變,此次回流往渲染隊列中加入,再向下走,發現沒有回流了,于是開始執行渲染隊列,一次執行完畢,發生一次回流...

          結尾

          分享完畢~~


          作者:滾去睡覺
          鏈接:https://juejin.cn/post/7322723692743573514

          面的繪制時間(paint time)是每一個前端開發都需要關注的的重要指標,它決定了你的頁面流暢程度。而如何去觀察頁面的繪制時間,找到性能瓶頸,可以借助Chrome的開發者工具。



          回流與重繪

          1. 當render tree中的一部分(或全部)因為元素的規模尺寸,布局,隱藏等改變而需要重新構建。這就稱為回流(reflow)。每個頁面至少需要一次回流,就是在頁面第一次加載的時候。在回流的時候,瀏覽器會使渲染樹中受到影響的部分失效,并重新構造這部分渲染樹,完成回流后,瀏覽器會重新繪制受影響的部分到屏幕中,該過程成為重繪。

          2. 當render tree中的一些元素需要更新屬性,而這些屬性只是影響元素的外觀,風格,而不會影響布局的,比如background-color。則就叫稱為重繪。

          注意:回流必將引起重繪,而重繪不一定會引起回流。

          回流何時發生:

          當頁面布局和幾何屬性改變時就需要回流。下述情況會發生瀏覽器回流:

          1. 頁面渲染初始化;
          2. 調整窗口大小(Resizing the window),瀏覽器窗口尺寸改變——resize事件發生時
          3. 增加或者移除樣式表(Adding or removing a stylesheet)
          4. 元素位置改變、元素尺寸改變——width/height/padding/border/margin
          5. 內容改變——比如文本改變或者圖片大小改變而引起的計算值寬度和高度改變;
          6. 改變字體(Changing the font)
          7. 激活 CSS 偽類,比如 :hover (IE 中為兄弟結點偽類的激活)(Activation of CSS pseudo classes such as :hover (in IE the activation of the pseudo class of a sibling))
          8. 操作 class 屬性(Manipulating the class attribute)
          9. 腳本操作 DOM(A script manipulating the DOM),添加或者刪除可見的DOM元素;
          10. 計算 offsetWidth 和 offsetHeight 屬性(Calculating offsetWidth and offsetHeight)
          11. 設置 style 屬性的值 (Setting a property of the style attribute)

          這么多,分類整理記憶下:

          js請求以下style信息時,觸發回流(瀏覽器會立刻清空隊列:)

          • clientWidth、clientHeight、clientTop、clientLeft
          • offsetWidth、offsetHeight、offsetTop、offsetLeft
          • scrollWidth、scrollHeight、scrollTop、scrollLeft
          • width、height
          • getComputedStyle()
          • getBoundingClientRect()

          css中如下屬性,觸發回流

          • width/height/padding/border/margin
          • font/line-height/font-weight/
          • postion/display/float/clear/

          js操作DOM,修改class屬性,修改樣式表,修改文檔內容,修改元素計算樣式

          讓我們看看下面的代碼是如何影響回流和重繪的:

          ar s=document.body.style;
          s.padding="2px"; // 回流+重繪
          s.border="1px solid red"; // 再一次 回流+重繪
          s.color="blue"; // 再一次重繪
          s.backgroundColor="#ccc"; // 再一次 重繪
          s.fontSize="14px"; // 再一次 回流+重繪
          // 添加node,再一次 回流+重繪
          document.body.appendChild(document.createTextNode('abc!'));

          然而這些都是意淫:那么

          怎么監控重繪回流

          chorme 按下:f12,然后按下 esc……

          但是,我按了沒有 readering

          那是你沒有勾選啊,console 旁邊有三點是不是,點擊,然后勾選,rendering……

          以上5個選項的意思如下:

          1. Show paint rectangles 顯示繪制矩形
          2. Show composited layer borders 顯示層的組合邊界(注:藍色的柵格表示的是分塊)
          3. Show FPS meter 顯示FPS幀頻
          4. Enable continuous page repainting 開啟持續繪制模式 并 檢測頁面繪制時間
          5. Show potential scroll bottlenecks 顯示潛在的滾動瓶頸。


          優化重繪回流

          CSS


          • 避免使用table布局。
          • 盡可能在DOM樹的最末端改變class。
          • 避免設置多層內聯樣式。
          • 將動畫效果應用到position屬性為absolute或fixed的元素上。
          • 避免使用CSS表達式(例如:calc())。


          JavaScript


          • 避免頻繁操作樣式,最好一次性重寫style屬性,或者將樣式列表定義為class并一次性更改class屬性。
          • 避免頻繁操作DOM,創建一個documentFragment,在它上面應用所有DOM操作,最后再把它添加到文檔中。
          • 也可以先為元素設置display: none,操作結束后再把它顯示出來。因為在display屬性為none的元素上進行的DOM操作不會引發回流和重繪。
          • 避免頻繁讀取會引發回流/重繪的屬性,如果確實需要多次使用,就用一個變量緩存起來。
          • 對具有復雜動畫的元素使用絕對定位,使它脫離文檔流,否則會引起父元素及后續元素頻繁回流。基本原則就是,把動畫元素用position:absolute踢出文檔流,這樣R&R就限制在了absolute元素的子節點。告訴瀏覽器,我這塊結構跟其他的單獨渲染,不要攪和全頁面了。


          參看文章:

          回流與重繪:CSS性能讓JavaScript變慢?






          轉載本站文章《chrome對頁面重繪和回流以及優化進行優化》,
          請注明出處:https://www.zhoulujun.cn/html/webfront/browser/webkit/2016_0506_7820.html


          主站蜘蛛池模板: 国产伦精品一区二区三区免费下载| 亚洲一区二区三区AV无码| 中文字幕乱码一区久久麻豆樱花| 福利一区二区三区视频午夜观看| a级午夜毛片免费一区二区| 久久精品国产AV一区二区三区| 国产日韩AV免费无码一区二区| 久久久久久人妻一区精品| 国产高清在线精品一区| 国产视频一区在线播放| 清纯唯美经典一区二区| 亚洲精品国产suv一区88| 男人免费视频一区二区在线观看| 久久99久久无码毛片一区二区| 日韩免费无码一区二区三区| 精品少妇人妻AV一区二区 | 红杏亚洲影院一区二区三区| 中文字幕一区二区三区在线播放| 亚洲AV综合色一区二区三区| 国产精品一区视频| 鲁大师成人一区二区三区| 欧洲无码一区二区三区在线观看| 成人无码精品一区二区三区| 国产午夜精品一区二区| 亚洲一区二区三区精品视频| 濑亚美莉在线视频一区| 成人区精品人妻一区二区不卡| 久久久精品人妻一区二区三区蜜桃| 日本一区二区三区不卡在线视频| 无码一区二区三区| 日韩美一区二区三区| 亚洲国产精品无码第一区二区三区 | 国产精品一区二区久久精品无码| 无码人妻AⅤ一区二区三区| 夜夜高潮夜夜爽夜夜爱爱一区| 无码国产伦一区二区三区视频| 国产福利一区二区精品秒拍| 久久精品一区二区三区AV| 农村人乱弄一区二区| 精品人妻一区二区三区四区| 曰韩人妻无码一区二区三区综合部|