浏览器渲染机制面试_浏览器渲染原理
本文目錄結構
問題
瀏覽器渲染原理
渲染過程
1. 瀏覽器接收到 HTML ?件并轉換為 DOM 樹
當我們打開?個??時,瀏覽器都會去請求對應的 HTML ?件。雖然平時我 們寫代碼時都會分為 JS 、 CSS 、 HTML ?件,也就是字符串,但是計算機 硬件是不理解這些字符串的,所以在?絡中傳輸的內容其實都是 0 和 1 這些字節數據。當瀏覽器接收到這些字節數據以后,它會將這些字節數據轉換為 字符串,也就是我們寫的代碼。
當數據轉換為字符串以后,瀏覽器會先將這些字符串通過詞法分析轉換為標記 ( token ),這?過程在詞法分析中叫做標記化( tokenization )
那么什么是標記呢?這其實屬于編譯原理這?塊的內容了。簡單來說,標記還 是字符串,是構成代碼的最?單位。這?過程會將代碼分拆成?塊塊,并給這 些內容打上標記,便于理解這些最?單位的代碼是什么意思
當結束標記化后,這些標記會緊接著轉換為 Node ,最后這些 Node 會根據 不同 Node 之前的聯系構建為?顆 DOM 樹
以上就是瀏覽器從?絡中接收到 HTML ?件然后?系列的轉換過程 當然,在解析 HTML ?件的時候,瀏覽器還會遇到 CSS 和 JS ?件,這時 候瀏覽器也會去下載并解析這些?件,接下來就讓我們先來學習瀏覽器如何解 析 CSS ?件
2. 將 CSS ?件轉換為 CSSOM 樹
其實轉換 CSS 到 CSSOM 樹的過程和上??節的過程是極其類似的
在這?過程中,瀏覽器會確定下每?個節點的樣式到底是什么,并且這?過程其實是很消 耗資源的。因為樣式你可以??設置給某個節點,也可以通過繼承獲得。在這?過程中, 瀏覽器得遞歸 CSSOM 樹,然后確定具體的元素到底是什么樣式。
如果你有點不理解為什么會消耗資源的話,我這?舉個例?
span {
color: red;
}
div > a > span {
color: red;
}
對于第?種設置樣式的?式來說,瀏覽器只需要找到??中所有的 span 標 簽然后設置顏?,但是對于第?種設置樣式的?式來說,瀏覽器?先需要找到 所有的 span 標簽,然后找到 span 標簽上的 a 標簽,最后再去找到 div 標簽,然后給符合這種條件的 span 標簽設置顏?,這樣的遞歸過程 就很復雜。所以我們應該盡可能的避免寫過于具體的 CSS 選擇器,然后對于 HTML 來說也盡量少的添加?意義標簽,保證層級扁平
3. ?成渲染樹
當我們?成 DOM 樹和 CSSOM 樹以后,就需要將這兩棵樹組合為渲染樹
在這?過程中,不是簡單的將兩者合并就?了。渲染樹只會包括需要顯示的節點和這些節 點的樣式信息,如果某個節點是 display: none 的,那么就不會在渲染樹中顯示。
當瀏覽器?成渲染樹以后,就會根據渲染樹來進?布局(也可以叫做回流),然后調? GPU 繪制,合成圖層,顯示在屏幕上。對于這?部分的內容因為過于底層,還涉及到了硬 件相關的知識,這?就不再繼續展開內容了。
21.2 為什么操作 DOM 慢
想必?家都聽過操作 DOM 性能很差,但是這其中的原因是什么呢?
因為 DOM 是屬于渲染引擎中的東?,? JS ?是 JS 引擎中的東?。當我們通過 JS 操作 DOM 的時候,其實這個操作涉及到了兩個線程之間的通信,那么勢必會帶來?些性 能上的損耗。操作 DOM 次數?多,也就等同于?直在進?線程之間的通信,并且操作 DOM 可能還會帶來重繪回流的情況,所以也就導致了性能上的問題。
經典?試題:插??萬個 DOM,如何實現??不卡頓?
對于這道題?來說,?先我們肯定不能?次性把?萬個 DOM 全部插?,這樣肯定會造成 卡頓,所以解決問題的重點應該是如何分批次部分渲染 DOM 。?部分?應該可以想到通 過 requestAnimationFrame 的?式去循環的插? DOM ,其實還有種?式去解決這個問 題:虛擬滾動( virtualized scroller )。
這種技術的原理就是只渲染可視區域內的內容,?可?區域的那就完全不渲染了,當?戶 在滾動的時候就實時去替換渲染的內容
從上圖中我們可以發現,即使列表很?,但是渲染的 DOM 元素永遠只有那么 ?個,當我們滾動??的時候就會實時去更新 DOM ,這個技術就能順利解決 這道經典?試題
21.3 什么情況阻塞渲染
?先渲染的前提是?成渲染樹,所以 HTML 和 CSS 肯定會阻塞渲染。如果你想渲染的越 快,你越應該降低?開始需要渲染的?件??,并且扁平層級,優化選擇器。
然后當瀏覽器在解析到 script 標簽時,會暫停構建 DOM ,完成后才會從暫停的地?重 新開始。也就是說,如果你想?屏渲染的越快,就越不應該在?屏就加載 JS ?件,這也 是都建議將 script 標簽放在 body 標簽底部的原因。
當然在當下,并不是說 script 標簽必須放在底部,因為你可以給 script 標簽添加 defer 或者 async 屬性。
當 script 標簽加上 defer 屬性以后,表示該 JS ?件會并?下載,但是會放到 HTML 解析完成后順序執?,所以對于這種情況你可以把 script 標簽放在任意位置。
對于沒有任何依賴的 JS ?件可以加上 async 屬性,表示 JS ?件下載和解析不會阻 塞渲染。
21.4 重繪(Repaint)和回流(Reflow)
重繪和回流會在我們設置節點樣式時頻繁出現,同時也會很?程度上影響性 能。重繪是當節點需要更改外觀?不會影響布局的,?如改變 color 就叫稱為重繪
回流是布局或者?何屬性需要改變就稱為回流。
回流必定會發?重繪,重繪不?定會引發回流。回流所需的成本?重繪?的多,改變?節點?的?節點很可能會導致?節點的?系列回流。
以下?個動作可能會導致性能問題:改變 window ??
改變字體
添加或刪除樣式
?字改變
定位或者浮動
盒模型
并且很多?不知道的是,重繪和回流其實也和 Eventloop 有關。當 Eventloop 執?完 Microtasks 后,會判斷 document 是否需要更新,因為瀏覽器是 60Hz 的刷新率,每 16.6ms 才會更新?次。
然后判斷是否有 resize 或者 scroll 事件,有的話會去觸發事件,所以 resize 和scroll 事件也是?少 16ms 才會觸發?次,并且?帶節流功能。
判斷是否觸發了 media query
更新動畫并且發送事件
判斷是否有全屏操作事件
執? requestAnimationFrame 回調
執? IntersectionObserver 回調,該?法?于判斷元素是否可?,可以?于懶加載上,但是兼容性不好 更新界?
以上就是?幀中可能會做的事情。如果在?幀中有空閑時間,就會去執?requestIdleCallback 回調
21.5 減少重繪和回流使? transform 替代 top
.test {
position: absolute;
top: 10px;
width: 100px;
height: 100px;
background: red;
}
setTimeout(() => {
// 引起回流
document.querySelector('.test').style.top = '100px'
}, 1000)
使? visibility 替換 display: none ,因為前者只會引起重繪,后者會引發回流 (改變了布局)
不要把節點的屬性值放在?個循環?當成循環?的變量for(let i = 0; i < 1000; i++) {
// 獲取 offsetTop 會導致回流,因為需要去獲取正確的值
console.log(document.querySelector('.test').style.offsetTop)
}
不要使? table 布局,可能很?的?個?改動會造成整個 table 的重新布局
動畫實現的速度的選擇,動畫速度越快,回流次數越多,也可以選擇使?requestAnimationFrame
CSS 選擇符從右往左匹配查找,避免節點層級過多
將頻繁重繪或者回流的節點設置為圖層,圖層能夠阻?該節點的渲染?為影響別的節點。?如對于 video 標簽來說,瀏覽器會?動將該節點變為圖層。
設置節點為圖層的?式有很多,我們可以通過以下?個常?屬性可以?成新圖層
will-change
video 、 iframe 標簽
更多面試題
如果你想了解更多的前端面試題,請點擊下面進行選擇,這里基本包涵了市場上的所有前端方面的面試題,讓你面試更加順利。
這些題庫還在更新中,如果你有不錯的面試題庫歡迎分享給我,我整理后放上來;人人為我,我為人人,互幫互助,共同提高,祝大家都拿到心儀的Offer!
總結
以上是生活随笔為你收集整理的浏览器渲染机制面试_浏览器渲染原理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python 多进程绑定端口_Pytho
- 下一篇: python 查看已经安装的模块_教你用