瀏覽器的工作原理

1. 影響瀏覽器渲染方式的文檔模式

每個瀏覽器都有自己的頁面渲染引擎蔑滓。渲染引擎包括兩部分:一部分負責 HTML郊酒、CSS 代碼的解析(渲染引擎遇绞,如 blink 引擎 or 內(nèi)核),一部分負責 JavaScript 代碼的解析(JavaScript 引擎燎窘,如 V8 引擎)摹闽。瀏覽器的渲染模式(以何種文檔模式進行渲染)主要對 CSS 解析有影響(也對腳本有一些影響)。不同的渲染模式褐健,在 CSS 解析上存在差異付鹿,比如對盒模型的處理。
不同的渲染模式是歷史遺留問題造成的蚜迅。早期 W3C 沒統(tǒng)一標準舵匾,瀏覽器生產(chǎn)商自己決定頁面如何渲染;標準出來后谁不,現(xiàn)有瀏覽器渲染肯定存在與標準不同的地方坐梯。為了兼容,就出現(xiàn)了兩種瀏覽器渲染模式(IE 最早提出)刹帕,正統(tǒng)叫法為文檔模式(Document Mode)(如果文檔是按照標準編寫的吵血,瀏覽器采用標準渲染模式;如果文檔并沒有按照標準編寫偷溺,那么瀏覽器以怪異模式渲染)蹋辅。此外,還有第三種模式—近標準模式挫掏。那么瀏覽器又該如何知道文檔有沒有按照標準編寫呢晕翠?實際上瀏覽器在渲染頁面之前會檢查兩個內(nèi)容,一個是頁面是否有 DOCTYPE 信息砍濒,另外一個是頁面是否有 x-ua-compatible 信息淋肾。DOCTYPE 告訴瀏覽器:我的文檔是哪種模式,你確定后爸邢,就按這種模式渲染樊卓;如果沒有這個頭信息,瀏覽器就按怪異模式渲染杠河。x-ua-compatible 是 IE8 的一個專有<meta>屬性碌尔,可以指定瀏覽器以怎樣的模式進行渲染。
注意:瀏覽器模式和瀏覽器渲染模式是兩個概念券敌,前者可以理解為IE瀏覽器中特有的概念唾戚,后者在本文中就是指文檔模式。

2. HTML 文檔的解析過程

當用戶在瀏覽器鍵入某網(wǎng)站地址待诅,網(wǎng)站首頁文檔 index.html 加載完成后叹坦,瀏覽器開始解析 HTML。下文根據(jù)不同的 HTML 資源結(jié)構(gòu)分析解析過程卑雁。

2.1 純 HTML 文檔募书,無 CSS 和腳本

如果 HTML 文檔中只有 HTML绪囱,沒有 CSS 和腳本的話,問題極其簡單莹捡。瀏覽器解析 HTML鬼吵,構(gòu)建 DOM 樹,DOM 樹構(gòu)建完成后(觸發(fā) DOMContentLoaded 事件)篮赢,構(gòu)建 render 樹齿椅,接著布局和繪制像素。

2.2 包含內(nèi)聯(lián)樣式和內(nèi)聯(lián)腳本的 HTML 文檔

如果 HTML 文檔中存在內(nèi)聯(lián)樣式和腳本启泣,這個時候涣脚,問題變得稍微復(fù)雜一些。瀏覽器解析 HTML种远,構(gòu)建 DOM 樹涩澡,當解析到<style>標簽時顽耳,樣式信息開始被解析坠敷,CSSOM 被構(gòu)建,但是它并不會影響到 HTML 的解析和 DOM 樹的構(gòu)建射富。當 HTML 解析到<script>標簽時膝迎,因為腳本有可能改變 DOM 內(nèi)容,所以 HTML 的解析必須等到腳本執(zhí)行完畢后再繼續(xù)胰耗。腳本又有可能操作 CSSOM 限次,所以腳本必須等到 CSS 解析完畢后才能執(zhí)行。確保此刻 CSS 解析完成柴灯,腳本被交到 JS 引擎手里卖漫,由 JS 引擎執(zhí)行。當腳本執(zhí)行完畢赠群,HTML 繼續(xù)解析羊始,直到全部 HTML 解析完畢,DOM 樹構(gòu)建完成(觸發(fā) DOMContentLoaded 事件)查描。
注意:DOMContentLoaded 事件只和 HTML 的加載和解析有關(guān)突委,一旦 HTML 解析完成,這個事件就會被觸發(fā)冬三,不管此時還有沒有CSS的解析匀油、圖片的下載或者異步腳本的加載和執(zhí)行。DOM 樹一旦構(gòu)建完成勾笆,就會開始構(gòu)建 render 樹敌蚜,并不管 CSS 是否解析完畢。如果構(gòu)建 render 樹的時候窝爪,CSS 還沒有解析完成钝侠,那么 render 樹會用占位符代替應(yīng)該有的 CSSOM 節(jié)點该园,當該節(jié)點加載解析好后,再重新計算樣式帅韧。
但是同步腳本的執(zhí)行會阻塞 HTML 的解析里初,從而會影響到 DOMContentLoaded 事件的觸發(fā)。同時又要注意忽舟,CSS 會阻塞 JS 腳本的執(zhí)行双妨,從而間接影響到 HTML 的解析和 DOMContentLoaded 事件的觸發(fā)。

2.3 包含外部 CSS 和腳本的 HTML 文檔

如果 HTML 文檔中存在外聯(lián)樣式表和腳本叮阅,問題變得更復(fù)雜一點刁品。HTML 文檔加載完成后,瀏覽器首先掃描 HTML 文檔,查看有哪些外部資源需要啟動 network operation 來請求資源,并在 HTML 解析的同時零聚,發(fā)送所有的請求察纯。CSS 資源加載完畢后,會立即開始解析構(gòu)建 CSSOM替久。(同步腳本加載完畢后,并不能立刻執(zhí)行。)當 HTML 解析到<script>標簽拌汇,先確認腳本加載完畢了沒,如果沒弊决,那得等噪舀;如果加載好了,還得看 CSS 解析好了沒飘诗。如果沒与倡,那還得等;如果 CSS 解析好了昆稿,那就能把腳本交給 JS 引擎去執(zhí)行了纺座。當 JS 執(zhí)行完畢,HTML 繼續(xù)解析貌嫡,DOM 繼續(xù)構(gòu)建比驻,直到全部構(gòu)建完成,DOMContentLoaded 事件被觸發(fā)岛抄。緊接著别惦,就是構(gòu)建 render 樹。
如果腳本有async屬性夫椭,問題就又不一樣了掸掸。async屬性默認該腳本不會影響到 DOM 內(nèi)容,所以只要腳本下載完成,(相關(guān))CSS 解析完畢扰付,腳本立刻執(zhí)行堤撵,不用等著 HTML 解析到<script>標簽再開始執(zhí)行。同樣羽莺,HTML 也不會等著腳本執(zhí)行完畢再解析实昨。仿佛兩者看不到對方,只管做自己的事情就行了盐固。

3. JS 解釋器的工作原理

上文提到瀏覽器在解析 HTML 文檔的時候荒给,會把腳本交給 JS 引擎執(zhí)行,那么 JS 引擎是如何執(zhí)行腳本(evaluating script)的呢刁卜?

3.1 掃描全局變量志电,確定所有已聲明的變量或函數(shù)名

你如果利用 chrome 控制臺調(diào)試 JS 代碼,這個過程是看不到的蛔趴,但確實存在挑辆。JS 解釋器對腳本進行全局掃描,結(jié)束后得到全局環(huán)境中的變量對象孝情,此過程發(fā)生了變量聲明提升和函數(shù)聲明提升鱼蝉。所有變量都沒被賦值,其值為 undefined咧叭;函數(shù)聲明提升還包括了函數(shù)體的提升蚀乔。下圖是個例子:

全局環(huán)境中的變量對象

備注:你可能會好奇上面這個圖是怎么回事烁竭,這里簡要概述一下:黃色區(qū)塊表示JS執(zhí)行環(huán)境菲茬,白色表格代表變量對象鍵值對模型,表格左列為全局變量(變量對象中的key)派撕,說明當前全局環(huán)境中共有model婉弹、octopuscatViewcatListView四個變量终吼。
以后會專門寫一篇文章介紹JS執(zhí)行時的內(nèi)存模型镀赌,幫助大家形象理解JS代碼的運行機制,從而有助于理解作用域际跪、執(zhí)行環(huán)境商佛、this指向、閉包姆打、繼承良姆、原型鏈等抽象概念。

3.2 順序執(zhí)行所有語句

當 JS 解釋器知道整個文件中都有哪些聲明好的全局變量或函數(shù)后幔戏,就會開始順序執(zhí)行文件中的語句玛追,當然是從第一行開始。如果是賦值語句,就執(zhí)行賦值操作痊剖;如果是函數(shù)調(diào)用語句韩玩,就執(zhí)行函數(shù)調(diào)用。
下圖是 debugger 剛開始時變量的情況陆馁,很明顯找颓,剛剛被 JS 解釋器點過名,還沒有開始執(zhí)行賦值操作叮贩。

變量聲明提升

當解釋器移動到下一行代碼時叮雳,這個變量也就被賦值,存儲了數(shù)據(jù)妇汗。在本例中這個數(shù)據(jù)是個對象類型帘不,有兩個屬性,其中一個是數(shù)組杨箭,另一個是空值寞焙。

變量賦值操作

腳本的最后是函數(shù)調(diào)用語句:

函數(shù)調(diào)用

JS 解析器執(zhí)行到這里,準備調(diào)用 octopusinit方法互婿。
當所有的語句執(zhí)行完畢后捣郊,JS 解釋器任務(wù)結(jié)束,主導(dǎo)權(quán)交到 HTML 解析器手中慈参,瀏覽器繼續(xù)解析 HTML 文檔呛牲。
從上述過程,我們能看出瀏覽器解析渲染 HTML 文檔是單線程的驮配,除了發(fā)送外部資源請求的操作娘扩。

4. 總結(jié)

瀏覽器的工作原理是網(wǎng)站性能優(yōu)化的基礎(chǔ)知識。CSS 不會阻塞 HTML 的解析壮锻,但是會阻塞渲染琐旁,CSS 的解析會阻塞腳本的執(zhí)行,而腳本會阻塞 HTML 的解析猜绣。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末灰殴,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子掰邢,更是在濱河造成了極大的恐慌牺陶,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,482評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件辣之,死亡現(xiàn)場離奇詭異掰伸,居然都是意外死亡,警方通過查閱死者的電腦和手機召烂,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評論 2 382
  • 文/潘曉璐 我一進店門碱工,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事怕篷±荩” “怎么了?”我有些...
    開封第一講書人閱讀 152,762評論 0 342
  • 文/不壞的土叔 我叫張陵廊谓,是天一觀的道長梳猪。 經(jīng)常有香客問我,道長蒸痹,這世上最難降的妖魔是什么春弥? 我笑而不...
    開封第一講書人閱讀 55,273評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮叠荠,結(jié)果婚禮上匿沛,老公的妹妹穿的比我還像新娘。我一直安慰自己榛鼎,他們只是感情好逃呼,可當我...
    茶點故事閱讀 64,289評論 5 373
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著者娱,像睡著了一般抡笼。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上黄鳍,一...
    開封第一講書人閱讀 49,046評論 1 285
  • 那天推姻,我揣著相機與錄音,去河邊找鬼框沟。 笑死藏古,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的街望。 我是一名探鬼主播校翔,決...
    沈念sama閱讀 38,351評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼弟跑,長吁一口氣:“原來是場噩夢啊……” “哼灾前!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起孟辑,我...
    開封第一講書人閱讀 36,988評論 0 259
  • 序言:老撾萬榮一對情侶失蹤哎甲,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后饲嗽,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體炭玫,經(jīng)...
    沈念sama閱讀 43,476評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,948評論 2 324
  • 正文 我和宋清朗相戀三年貌虾,在試婚紗的時候發(fā)現(xiàn)自己被綠了吞加。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,064評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖衔憨,靈堂內(nèi)的尸體忽然破棺而出叶圃,到底是詐尸還是另有隱情,我是刑警寧澤践图,帶...
    沈念sama閱讀 33,712評論 4 323
  • 正文 年R本政府宣布掺冠,位于F島的核電站,受9級特大地震影響码党,放射性物質(zhì)發(fā)生泄漏德崭。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,261評論 3 307
  • 文/蒙蒙 一揖盘、第九天 我趴在偏房一處隱蔽的房頂上張望眉厨。 院中可真熱鬧,春花似錦兽狭、人聲如沸缺猛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽荔燎。三九已至,卻和暖如春销钝,著一層夾襖步出監(jiān)牢的瞬間有咨,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評論 1 262
  • 我被黑心中介騙來泰國打工蒸健, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留座享,地道東北人。 一個月前我還...
    沈念sama閱讀 45,511評論 2 354
  • 正文 我出身青樓似忧,卻偏偏與公主長得像渣叛,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子盯捌,可洞房花燭夜當晚...
    茶點故事閱讀 42,802評論 2 345

推薦閱讀更多精彩內(nèi)容