衣食父母-瀏覽器

我以爲文章題目起的挺現實,在BS大行其道的今天,瀏覽器做爲一款window軟件已是不少程序員兄弟的衣食父母,因此瞭解一下瀏覽器是很必要的。javascript

一、背景

做爲前端程序員必定要好奇從地址欄輸入地址後到底發生了什麼css

主流瀏覽器

IE、Firefox、Safari、Chrome、Opera五你們族, Firefox、Chrome是開源的徹底開源的,safari部分開源html

瀏覽器的主要構成

用戶界面、瀏覽器引擎、渲染引擎、網絡、js解釋器、UI後端、數據存儲,google爲每一個tab頁分一個渲染引擎,
注:瀏覽器引擎和渲染引擎的區別
(1) 瀏覽器引擎是一個主進程、用來管理渲染引擎所在的進程,渲染引擎對應的進程可能只屬於一個tab頁(chrome),而瀏覽器進程屬於整個瀏覽器
(2) 渲染引擎沒有訪問操做系統的權限(文件、網絡、設備)而瀏覽器引擎有,這樣的目的是有惡意網站時不會損害整個瀏覽器或者操做系統
(3) 當用戶在地址欄輸入網址請求網頁時,渲染引擎向瀏覽器引擎發出請求:依次調用網絡獲取資源,請求的資源到達後,瀏覽器引擎把資源傳給渲染前端

渲染引擎,渲染引擎將獲取的資源進行解析(html css js),有一些組件(佈局進程就屬於其中的某個組件)格式化後傳給瀏覽器引擎,瀏覽器在界面中將界面呈現出來
渲染引擎

渲染引擎有兩種Mozilla和webkit,熟悉css的同窗可能感受這倆外國字挺熟悉,對啊css兼容性的屬性都會加這倆前綴,渲染引擎就是將請求的資源在瀏覽器中呈現出來java

渲染主流程

首先是獲取請求的文檔,文檔由8kb的數據塊構成,8kb的大小是由tcp缺省緩衝區的大小決定的。構建成dom樹->構建render樹->佈局render樹->繪製render樹。c++

(1) 渲染引擎從瀏覽器引擎獲取html文檔後開始解析,進行詞法分析(將輸入分紅能夠理解的單詞)和語法分析(對應語言的語義規則,描述文檔內容),最終根據文檔標籤構建一棵DOM樹(能夠理解成c++的一種數據結構),解析過程若是碰到了行內、內聯、外聯的css,對應的子進程着手cssom樹的構建(能夠理解成c++的一種數據結構,描述樣式規則),因爲是兩個進程因此沒有阻塞的問題,若是解析過程當中碰到了javascript,那麼DOM,而且javascript的執行須要等到cssom構建完畢,下一步構建渲染樹是須要兩個樹都是在完成構建的狀態。程序員

(2) 此時要構建渲染樹了,先從DOM樹的根節點開始逐層遍歷,而後依次在cssom中找到對應的樣式併合併到渲染樹,若是碰到了隱藏樣式那麼
直接在渲染樹種忽略。web

(3) 對渲染樹進行'佈局',以前的全部操做都沒涉及瀏覽器窗口,他們就是在這個階段聯繫起來的,這樣渲染樹才能適應不一樣大小的窗口,這時全部的位置和尺寸都被轉換爲像素(px)chrome

(4) 最後是將佈局樹轉換格式傳給瀏覽器引擎,在瀏覽器窗口繪製。後端

二、css阻塞

從上文中咱們知道css是阻塞的也是非阻塞的,阻塞渲染樹的構建,可是對於dom樹的構建是不阻塞的。若是在構建渲染樹時是不阻塞的會發生什麼,咱們會看到'純html'沒有任何樣式,這樣是不友好的,可是某些時候咱們確實想讓它是不阻塞的,好比涉及打印的樣式,在特定大屏上的樣式,由於他們對渲染的影響比較小,此時能夠採用媒體屬性(media)

<link href="style.css" rel="stylesheet">
<link href="print.css" rel="stylesheet" media="print">
<link href="style.css"    rel="stylesheet" media="all">
<link href="portrait.css" rel="stylesheet" media="orientation:portrait">
<link href="other.css" rel="stylesheet" media="(min-width: 40em)">

注: 不阻塞不是不下載,只是在首次合成渲染樹時不受它的阻塞

三、javascript阻塞

從衣食父母-瀏覽器中咱們知道javascript腳本的執行是會阻塞DOM樹的構建的,而且在cssom構建完畢前中止執行,這樣會有很大的性能開銷,有沒有不阻塞的方法呢?
一、外部js異步加載

<script src="app.js" async></script>

二、 內聯js異步執行

function h () {
    console.log(document.querySelectorAll('h1'))
}
setTimeout(h, 0)
相關文章
相關標籤/搜索