前端——全端知識體系總結
參考書籍《了不起的JavaScript工程師》、《前端架構從入門到微前端》、《前端工程化體系設計與實踐》,寫此博客記錄重要知識點,一來自己以後能以此作爲知識點回顧,二來希望分享給其他有需要的前端同行。
注:本文章所有文字與代碼均爲手敲,如若發現錯誤,一切以實際情況爲準,請自行辨別,歡迎在文章下方留言指錯。
Web頁面與多頁應用
DOM樹渲染流程
瀏覽器在收到服務器端發來的Html文檔之後,會根據標籤之間的嵌套結構,通過詞法、語法分析將其解析成一棵DOM數。以下面一段代碼爲例:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" >
<title>Document</title>
</head>
<body>
<p>hello Dom</p>
<ul>
<li>first</li>
<li>second</li>
<li class="last">last</li>
</ul>
</body>
</html>
瀏覽器在解析上面的Html代碼之後會生成如下圖
在這個過程中有兩個重要因素會影響生成DOM樹的時間——標籤數量和嵌套層級。
標籤數量越多,相應的解析時間就越長。
同樣的標籤數量標籤層級越多,解析時間越長!
接下來是CSSOM構建:
body { font-size: 12px }
p { font-weight: light }
span { color: blue }
p span { display: none }
css雖然本身不像HTML文件一樣呈現出明顯的層級結構,但也可以按照其樣式規則中的選擇器嵌套關係來構造樹形結構
需要注意的是實際在瀏覽器中還會包含瀏覽器的默認樣式,而我們編寫的樣式只是對默認樣式的替換
接下來說說css的匹配機制
<style>
div p span.last{
color: red;
}
</style>
<div class="wrap list">
<p><span>first</span><span>item</span></p>
<p><span>second</span><span>item</span></p>
<p><span>last</span><span class="last">item</span></p>
</div>
從左到右匹配:
- 找到第一個div元素
- 找到子元素中第2個p元素
- 找到子元素中的第1個span元素,樣式選擇器不匹配,回溯到p元素
- 找到子元素中的第2個span元素,樣式選擇器不匹配,此時p元素已無子元素,回溯到父元素div
- 找到子元素中第2個p元素
- 找到子元素中的第1個span元素,樣式選擇器不匹配,回溯到p元素
- 找到子元素中的第2個span元素,樣式選擇器不匹配,此時p元素已無子元素,回溯到父元素div
- 找到子元素中的第3個p元素
- 找到子元素中的第1個span元素,樣式選擇器不匹配,回溯到p元素
- 找到子元素中的第2個span元素,樣式選擇器匹配,匹配完成。
從右到左匹配
- 找到div元素,標籤選擇器span不匹配,繼續往下找
- 知道找到最後一個span元素,標籤和類選擇器匹配,繼續網上匹配
- 找到父元素p,標籤樣式匹配,找到父元素div,標籤樣式匹配,匹配完成
從上面的匹配過程中我們不難看出,如果按照從左到右的匹配模式,那麼會產生大量的回溯操作,所以瀏覽器選擇了從右到左的選擇器匹配方式。
瞭解了瀏覽器匹配CSS的方式之後,我們需要注意的是,在選擇器的右邊儘量使用具有唯一性的選擇器,而不要使用標籤選擇器這類容易匹配的選擇器!
現在總結一下渲染頁面的大致流程:
- 解析HTML標籤並生成DOM樹
- 解析CSS規則並生成CSSOM樹
- 將DOM樹與CSSOM樹合併成一個渲染樹
- 根據渲染樹進行佈局
- 對渲染樹上的節點進行繪製
下面是流程圖:
// TODO
接下來我們思考一個重要的問題:如何寫出高性能的代碼(寫代碼),類似於常說的前端如何進行性能優化(碰到已經寫好的代碼怎麼優化)?
當然前端的性能優化不只涉及渲染引擎,就渲染引擎而言,我們至少可以做到一下幾點。
1. 避免編寫複雜的DOM結構,減少DOM層級,從而可以加快DOM樹的構建。
2. 避免寫出複雜的CSS樣式,從而可以加快CSSOM樹的構建。
3. 避免在選擇器右邊使用通用選擇器,加快瀏覽器匹配樣式規則的速度。
4. 修改樣式的時候避免引起重新佈局。
JavaScript引擎
瀏覽器給JavaScript引擎注入了兩件強大的武器:BOM(瀏覽器對象模型)和DOM(文檔對象模型),讓他不但能解釋執行JavaScript代碼,同時能操作瀏覽窗口和內容樹
整個渲染流程大致如下:
從上圖可以看到,如果JS請求或執行時間過長,或由於網絡原因造成下載JS文件的時間過程,那麼瀏覽器會長時間處於白屏狀態,從而造成較差的用戶體驗。