一,瀏覽器的基本結構
瀏覽器內核是瀏覽器最核心的組成部分——渲染引擎
HTML和CSS內容會被渲染引擎解析並渲染到屏幕上
在控制檯輸入命令 navigator.userAgent 後能看見瀏覽器相關的信息
二,瀏覽器內核
主流瀏覽器 | Chrome | IE | Edge | FireFox | Opera | Safari |
---|---|---|---|---|---|---|
渲染引擎 | Webkit | Trident | Webkit | Gecko | Webkit | Webkit |
三,渲染流程
(1)解析HTML標籤並生成DOM樹
(2)解析CSS規則並生成CSSDOM樹
(3)將DOM樹與CSSOM樹合併爲一個渲染樹
(4)根據渲染樹來進行佈局
(5)對渲染樹上的節點進行繪製
(1)構建DOM樹
DOM全稱Document Object Model
當服務器將HTML文檔發送到瀏覽器後,瀏覽器會根據標籤之間的嵌套結構,基於語法,分析其並解析爲一棵DOM樹
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>DOM樹</title>
</head>
<body>
<div>
<div>
<p></p>
<img/>
</div>
<ul>
<li></li>
<li></li>
<li></li>
</ul>
</div>
</body>
標籤數據越多,解析時間越長
(2)構建CSSOM樹
CSSOM全稱 Cascade Style Sheet Object Model
平時我們編寫的CSS文件裏面的自定義代碼,是對默認樣式的替換。 默認樣式一般表現在ul這類標籤,當你寫了一個ul列表時,整個ul在渲染完成後,會自動相對左側有40px的距離,這是因爲ul的默認距離爲相對左側有40px,我們只要寫margin-left:-40px即可抵消其默認樣式
(3)執行渲染
瀏覽器將CSS樣式依附到DOM樹上,是按照從右到左匹配的規則。怎麼理解這個?
比如:
<div><span>1</span><span>2</span></div>
上面這個代碼,如果對其進行css樣式編寫,在渲染的時候找到div標籤後,會先從內容爲2的span標籤往內容爲1的span標籤進行渲染,這樣做的好處是,減少翻來覆去查找匹配的渲染次數,節省性能,防止css從左往右渲染產生的回溯操作(什麼是回溯,比如你定義了全部span爲紅色,然後定義最後一個span爲藍色,如果是從左往右,會先讓全部變成藍色後再讓最後一個變成紅色)。
所以在平時寫代碼的時候,能以最短的代碼找到dom點最好,不要寫太複雜的代碼徒增了瀏覽器渲染查找標籤的工作,從而避免影響性能
寫頁面的時候特別注意的規則:在對元素樣式進行修改的時候,儘量避免對頁面佈局進行重排,因爲重排後的佈局會觸發新的dom樹繪製,從而耗費性能,css中有兩個屬性就是鮮明的對比,一個是margin-left,一個是translate。前者如果在頁面渲染完成後改變,會導致頁面重排,但是後者不會,後者不會
四,Javascript加載
javascript引擎是用於解析和執行js代碼的單線程程序,js的加載主要有兩種方式:串行和異步
串行
js是串行的,在同一時間以單線程的方式操作DOM,執行邏輯運算,CSS的渲染和JS引擎會互相阻塞進行。
爲什麼要一般把js文件的引入標籤放在html文件底部?
因爲阻塞加載的行爲,如果一開始就在頁面頭部引入js文件,當js文件容量很大的時候,下載js的代碼時間會過長,頁面會一直等待js加載完成後纔開始css的渲染,這樣會導致頁面存在一定的空白期,用戶等待時間一般超過4s就會離開網站,從而導致我們用戶流失。所以一般先等html,css渲染排版好後開始js的渲染,來加快頁面加載出來的速度
異步
(1)defer 會將執行js的操作延後,等待HTML解析完成後才執行
代碼舉例如下 :
<script src="example.js" defer></script>
(2)async 能實現併發請求js,如果請求速度快於其他文件,會在其他文件請求完成前執行
代碼舉例如下 :
<script src="example.js" async></script>