前言
本系列最開始是為了自己面試準備的.後來發現整理越來越多,差不多有十二萬字元,最後決定還是分享出來給大家.
為了分享整理出來,花費了自己大量的時間,起碼是隻自己用的三倍時間.如果喜歡的話,歡迎收藏,關注我!謝謝!
文章連結
- 前端面試查漏補缺--(一) 防抖和節流
- 前端面試查漏補缺--(二) 垃圾回收機制
- 前端面試查漏補缺--(三) 跨域及常見解決辦法
- 前端面試查漏補缺--(四) 前端本地儲存
- 前端面試查漏補缺--(五) 渲染機制及重繪和迴流
- 前端面試查漏補缺--(六) 瀏覽器快取
- 前端面試查漏補缺--(七) XSS攻擊與CSRF攻擊
- 前端面試查漏補缺--(八) 前端加密
- 前端面試查漏補缺--(九) HTTP與HTTPS
- 前端面試查漏補缺--(十) 前端鑑權
- 前端面試查漏補缺--(十一) 前端軟體架構模式MVC/MVP/MVVM
- 前端面試查漏補缺--(十二) 從輸入URL到看到頁面發生的全過程(含三握手,四揮手詳解)
- 前端面試查漏補缺--(十三) 記憶體洩漏
- 前端面試查漏補缺--(十四) 演算法及排序
- 前端面試查漏補缺--(十五) Event Loop
合集篇:
前端面試查漏補缺--Index篇(12萬字元合集) 包含目前已寫好的系列其他十幾篇文章.後續新增值文章不會再在每篇新增連結,強烈建議議點贊,關注合集篇!!!!,謝謝!~
後續更新計劃
後續還會繼續新增設計模式,前端工程化,專案流程,部署,閉環,vue常考知識點 等內容.如果覺得內容不錯的話歡迎收藏,關注我!謝謝!
求一份內推
目前本人也在準備跳槽,希望各位大佬和HR小姐姐可以內推一份靠譜的武漢 前端崗位!郵箱:bupabuku@foxmail.com.謝謝啦!~
渲染機制
渲染步驟
瀏覽器的渲染機制一般分為以下幾個步驟:
-
- 處理 HTML 並構建 DOM 樹。
-
- 處理 CSS 構建 CSSOM 樹。
-
- 將 DOM 與 CSSOM 合併成一個渲染樹。
-
- 根據渲染樹來佈局,計算每個節點的位置。
-
- 呼叫 GPU 繪製,合成圖層,顯示在螢幕上。
注意:
- 在構建 CSSOM 樹時,會阻塞渲染,直至 CSSOM 樹構建完成。並且構建 CSSOM 樹是一個十分消耗效能的過程,所以應該儘量保證層級扁平,減少過度層疊,越是具體的 CSS 選擇器,執行速度越慢。
- 當 HTML 解析到 script 標籤時,會暫停構建 DOM, 完成後才會從暫停的地方重新開始。也就是說,如果你想首屏渲染的越快,就越不應該在首屏就載入 JS 檔案。並且 CSS 也會影響 JS 的執行,只有當解析完樣式表才會執行 JS,所以也可以認為這種情況下,CSS 也會暫停構建 DOM。
Load 和 DOMContentLoaded 區別
- Load 事件觸發代表頁面中的 DOM,CSS,JS,圖片已經全部載入完畢。
- DOMContentLoaded 事件觸發代表初始的 HTML 被完全載入和解析,不需要等待 CSS,JS,圖片載入。
圖層
一般來說,可以把普通文件流看成一個圖層。特定的屬性可以生成一個新的圖層。不同的圖層渲染互不影響,所以對於某些頻繁需要渲染的建議單獨生成一個新圖層,提高效能。但也不能生成過多的圖層,會引起反作用。
通過以下幾個常用屬性可以生成新圖層
- 3D 變換:
translate3d
、translateZ
will-change
video
、iframe
標籤- 通過動畫實現的
opacity
動畫轉換 position: fixed
重繪(Repaint)和迴流(Reflow)
概念
重繪和迴流是渲染步驟中的一小節,但是這兩個步驟對於效能影響很大。
- 重繪是 當節點需要更改外觀而不會影響佈局的,比如改變 color、background-color、visibility等就叫稱為重繪
- 迴流是 佈局或者幾何屬性需要改變 就稱為迴流。
注意: 迴流必定會發生重繪,重繪不一定會引發迴流。迴流所需的成本比重繪高的多,改變深層次的節點很可能導致父節點的一系列迴流。
會導致迴流的操作:
- 頁面首次渲染
- 瀏覽器視窗大小發生改變
- 元素尺寸或位置發生改變
- 元素內容變化(文字數量或圖片大小等等)
- 元素字型大小變化
- 新增或者刪除可見的
DOM
元素 - 啟用
CSS
偽類(例如::hover
) - 查詢某些屬性或呼叫某些方法
一些常用且會導致迴流的屬性和方法:
clientWidth
、clientHeight
、clientTop
、clientLeft
offsetWidth
、offsetHeight
、offsetTop
、offsetLeft
scrollWidth
、scrollHeight
、scrollTop
、scrollLeft
scrollIntoView()
、scrollIntoViewIfNeeded()
getComputedStyle()
getBoundingClientRect()
scrollTo()
重繪和迴流與Event loop關係
很多人不知道的是,重繪和迴流其實和 Event loop 有關。
- 當 Event loop 執行完 Microtasks 後,會判斷 document 是否需要更新。因為瀏覽器是 60Hz 的重新整理率,每 16ms 才會更新一次。
- 然後判斷是否有
resize
或者scroll
,有的話會去觸發事件,所以resize
和scroll
事件也是至少 16ms 才會觸發一次,並且自帶節流功能。 - 判斷是否觸發了 media query
- 更新動畫並且傳送事件
- 判斷是否有全屏操作事件
- 執行
requestAnimationFrame
回撥 - 執行
IntersectionObserver
回撥,該方法用於判斷元素是否可見,可以用於懶載入上,但是相容性不好 - 更新介面
- 以上就是一幀中可能會做的事情。如果在一幀中有空閒時間,就會去執行
requestIdleCallback
回撥。
減少重繪和迴流
- 使用
translate
替代top
-
使用
visibility
替換display: none
,因為前者只會引起重繪,後者會引發迴流(改變了佈局) -
把 DOM 離線後修改,比如:先把 DOM 給
display:none
(有一次 Reflow),然後你修改 100 次,然後再把它顯示出來 -
不要把 DOM 結點的屬性值放在一個迴圈裡當成迴圈裡的變數
-
不要使用 table 佈局,可能很小的一個小改動會造成整個 table 的重新佈局
-
動畫實現的速度的選擇,動畫速度越快,迴流次數越多,也可以選擇使用
requestAnimationFrame
-
CSS 選擇符從右往左匹配查詢,避免 DOM 深度過深
-
將頻繁執行的動畫變為圖層,圖層能夠阻止該節點回流影響別的元素。比如對於
video
標籤,瀏覽器會自動將該節點變為圖層。
CSS
- 避免使用
table
佈局。 - 儘可能在
DOM
樹的最末端改變class
。 - 避免設定多層內聯樣式。
- 將動畫效果應用到
position
屬性為absolute
或fixed
的元素上。 - 避免使用
CSS
表示式(例如:calc()
)。
JavaScript
- 避免頻繁操作樣式,最好一次性重寫
style
屬性,或者將樣式列表定義為class
並一次性更改class
屬性。 - 避免頻繁操作
DOM
,建立一個documentFragment
,在它上面應用所有DOM操作
,最後再把它新增到文件中。 - 也可以先為元素設定
display: none
,操作結束後再把它顯示出來。因為在display
屬性為none
的元素上進行的DOM
操作不會引發迴流和重繪。 - 避免頻繁讀取會引發迴流/重繪的屬性,如果確實需要多次使用,就用一個變數快取起來。
- 對具有複雜動畫的元素使用絕對定位,使它脫離文件流,否則會引起父元素及後續元素頻繁迴流。
感謝及參考
整篇文章基本都是摘自下面文章,這裡表示感謝!