渲染機制
DOCTYPE的作用
- DTD(文檔定義類型)是一系列的語法規則,用來定義XML或者(X)HTML的文件類型。瀏覽器會使用它來判斷文檔類型,決定用何種協議來解析,以及切換瀏覽器模式
- DOCTYPE是用來聲明文檔類型和DTD規范的,一個主要的用途是文件的合法性驗證。如果文件代碼不合法,那么解析的時候會出一些差錯。
DOCTYPE類型
- HTML5 <!DOCTYPE html>
- HTML 4.01 Strict 嚴格模式 該DTD包含所有HTML元素和屬性,但不包括展示性和棄用的元素
- HTML 4.01 Transitional 傳統模式 該DTD包含所有HTML元素和屬性,
包括展示性和棄用的元素 (比如font)
瀏覽器渲染過程
DOC渲染過程
所以瀏覽器的渲染過程主要包括以下幾步:
- 解析HTML生成DOM樹。
- 解析CSS生成CSSOM規則樹。
- 將DOM樹與CSSOM規則樹合并在一起生成渲染樹。
- 遍歷渲染樹開始布局,計算每個節點的位置大小信息。
- 將渲染樹每個節點繪制到屏幕。
渲染阻塞
當瀏覽器遇到一個 script 標記時,DOM 構建將暫停,直至腳本完成執行,然后繼續構建DOM。每次去執行JavaScript腳本都會嚴重地阻塞DOM樹的構建,如果JavaScript腳本還操作了CSSOM,而正好這個CSSOM還沒有下載和構建,瀏覽器甚至會延遲腳本執行和構建DOM,直至完成其CSSOM的下載和構建。
所以,script 標簽的位置很重要。實際使用時,可以遵循下面兩個原則:
- CSS 優先:引入順序上,CSS 資源先于 JavaScript 資源。
- JS置后:我們通常把JS代碼放到頁面底部,且JavaScript 應盡量少影響 DOM 的構建。
重排reflow
定義
DOM結構中的每個元素都有自己的盒模型,這些都需要瀏覽器根據各種樣式來計算并根據結果將元素放到它該出現的位置,這個過程叫做reflow
觸發reflow
- 當增加、刪除、修改DOM節點的時候,會導致reflow或者repaint
- 當你移動DOM節點,或者搞動畫的時候
- 當你修改CSS樣式的時候
- 當你resize窗口的時候(移動端沒有這個問題),或者滾動的時候
- 當你修改網頁默認字體的時候(這個會出現各種問題)
- 如何觸發reflow應該至少要記住以上兩點以上
重繪repaint
定義
當各種盒子的位置、大小以及其他屬性改動,例如字體大小顏色等都確定下來以后,瀏覽器就把這個元素按照各自的特性繪制了一遍,于是頁面內容就出現了,這個過程叫做repaint
觸發repaint
- DOM改動
- CSS改動
如何盡可能少的進行重繪
將DOM改動或者CSS改動盡可能的一次性改完,不要一次操作分多次進行
例子:
//多次重繪
dom1.style.backgroundColor = 'red'
dom1.style.width= '50px'
dom1.style.height= '50px'
//一次重繪
//CSS
.add{
backgound-color: red;
width: 50px;
heiht: 50px;
}
//JS
dom2.className = 'add'
JS運行機制
JS是單線程的,不可以同時執行多個任務,但是同時也有異步操作。JS會優先執行同步操作,然后同步操作都完成以后再去執行異步操作。
console.log(1)
setTimeout(function() {
console.log(3)
}, 0)
console.log(2)
//輸出順序為 1 2 3 因為setTimeout是一個異步函數
console.log(1)
setTimeout(function() {
console.log(2)
}, 0)
while (true) {
}
//只輸出1然后進入無線循環不輸出2
驗證了所有同步操作完成之前異步操作是不會被執行的。
Event Loop
for(var i = 0;i < 4;i++) {
setTimeout(function() {
console.log(i)
},1000)
}
//輸出四個4
上面這段代碼同時輸出4個4.因為在循環的過程中遇到setTimeout會記住這個函數,但是不會去執行他,然后進入下一輪循環,等到循環結束,setTimeout被放入異步隊列執行。
異步任務
- setTimeout 和 setInterval
- DOM事件
- ES6中的promise
總結
- 了解JS的單線程的概念
- 理解任務隊列
- 理解Event Loop
- 理解哪些語句會放入異步任務隊列
- 理解語句放入異步隊列的時機