瀏覽器面試——js加載

瀏覽器的主要功能是將用戶選擇的web資源呈現(xiàn)出來筋栋,它需要從服務(wù)器請求資源零远,并將其顯示在瀏覽器窗口中苗分,資源的格式通常是HTML,也包括PDF牵辣、image及其他格式摔癣。用戶用URI來指定所請求資源的位置,在網(wǎng)絡(luò)一章有更多討論纬向。

HTML和CSS規(guī)范中規(guī)定了瀏覽器解釋html文檔的方式择浊,由W3C組織對這些規(guī)范進(jìn)行維護(hù)。


瀏覽器的主要構(gòu)成(High Level Structure)

  1. 用戶界面 - 包括地址欄逾条、后退/前進(jìn)按鈕琢岩、書簽?zāi)夸浀龋簿褪悄闼吹降某擞脕盹@示你所請求頁面的主窗口之外的其他部分师脂。

  2. 瀏覽器引擎 - 用來查詢及操作渲染引擎的接口担孔。

  3. 渲染引擎 - 用來顯示請求的內(nèi)容,例如吃警,如果請求內(nèi)容為html糕篇,它負(fù)責(zé)解析html及css,并將解析后的結(jié)果顯示出來酌心。

  4. 網(wǎng)絡(luò) - 用來完成網(wǎng)絡(luò)調(diào)用娩缰,例如http請求,它具有平臺(tái)無關(guān)的接口谒府,可以在不同平臺(tái)上工作拼坎。

  5. UI后端 - 用來繪制類似組合選擇框及對話框等基本組件,具有不特定于某個(gè)平臺(tái)的通用接口完疫,底層使用操作系統(tǒng)的用戶接口泰鸡。

  6. JS解釋器 - 用來解釋執(zhí)行JS代碼。

  7. 數(shù)據(jù)存儲(chǔ) - 屬于持久層壳鹤,瀏覽器需要在硬盤中保存類似cookie的各種數(shù)據(jù)盛龄,HTML5定義了web database技術(shù),這是一種輕量級完整的客戶端存儲(chǔ)技術(shù)


渲染引擎:

渲染引擎的職責(zé)就是渲染,即在瀏覽器窗口中顯示所請求的內(nèi)容余舶。

Firefox啊鸭、Chrome和Safari是基于兩種渲染引擎構(gòu)建的,F(xiàn)irefox使用Geoko——Mozilla自主研發(fā)的渲染引擎匿值,Safari和Chrome都使用webkit赠制。

?渲染引擎首先通過網(wǎng)絡(luò)獲得所請求文檔的內(nèi)容,下面是渲染引擎在取得內(nèi)容之后的基本流程:

  解析html以構(gòu)建dom樹 -> 構(gòu)建render樹 -> 布局render樹 -> 繪制render樹

Render樹構(gòu)建好了之后挟憔,將會(huì)執(zhí)行布局過程钟些,它將確定每個(gè)節(jié)點(diǎn)在屏幕上的確切坐標(biāo)。

再下一步就是繪制绊谭,即遍歷render樹政恍,并使用UI后端層繪制每個(gè)節(jié)點(diǎn)。

值得注意的是达传,這個(gè)過程是逐步完成的篙耗,為了更好的用戶體驗(yàn),渲染引擎將會(huì)盡可能早的將內(nèi)容呈現(xiàn)到屏幕上宪赶,并不會(huì)等到所有的html都解析完成之后再去構(gòu)建和布局render樹鹤树。它是解析完一部分內(nèi)容就顯示一部分內(nèi)容,同時(shí)逊朽,可能還在通過網(wǎng)絡(luò)下載其余內(nèi)容罕伯。

Webkit中元素的定位稱為布局,而Gecko中稱為回流叽讳。


hmtl不能被一般的自頂向下或自底向上的解析器所解析追他。

原因是:

  1. 這門語言本身的寬容特性

  2. 瀏覽器對一些常見的非法html有容錯(cuò)機(jī)制

  3. 解析過程是往復(fù)的,通常源碼不會(huì)在解析過程中發(fā)生改變岛蚤,但在html中邑狸,腳本標(biāo)簽包含的“document.write”可能添加標(biāo)簽,這說明在解析過程中實(shí)際上修改了輸入涤妒。

瀏覽器為html定制了專屬的解析器单雾。


瀏覽器對js腳本的解析

script標(biāo)簽每次出現(xiàn)都會(huì)霸道的讓頁面等待腳本的解析和執(zhí)行,同樣她紫,當(dāng)使用script的src屬性加載頁面時(shí)硅堆,瀏覽器必須先花時(shí)間下載外鏈文件中的代碼,然后解析并執(zhí)行贿讹。在這個(gè)過程中渐逃,頁面渲染和用戶交互是完全被阻塞的。

瀏覽器之所以產(chǎn)生這樣的行為民褂,是因?yàn)楫?dāng)前HTML頁面無從知曉JS的動(dòng)作:JS可能會(huì)向document里添加內(nèi)容茄菊、引入其它元素疯潭、甚至關(guān)閉標(biāo)簽。

所以瀏覽器會(huì)先(下載和)執(zhí)行JS代碼面殖,然后才解析和渲染頁面竖哩。


js加載優(yōu)化

想要使頁面得到更快的渲染,一是優(yōu)化腳本的執(zhí)行速度脊僚,例如使用觀察者模式減少初始化代碼的執(zhí)行數(shù)量相叁,這并不在這篇文章的闡述范圍之內(nèi)。請牢記吃挑,默認(rèn)狀態(tài)下钝荡,所有的腳本必須被執(zhí)行后街立,頁面才會(huì)開始渲染舶衬。即在瀏覽器解析頁面之前,須先讀取并執(zhí)行腳本赎离。我們現(xiàn)在試著對腳本的下載過程進(jìn)行優(yōu)化逛犹。

現(xiàn)代瀏覽器都允許并行下載JS文件但JS文件的下載過程仍然會(huì)阻塞其他比如圖片資源的下載梁剔。盡管JS文件的下載并不會(huì)相互影響虽画,但是瀏覽器會(huì)等待全部的JS代碼下載完成才執(zhí)行之。

1. 優(yōu)化JS的首要規(guī)則:將腳本放在底部

這樣做可以防止腳本代碼的下載與執(zhí)行阻塞頁面其它資源荣病,比如圖片的下載(下載往往需要更多的時(shí)間)码撰,以盡量減少對整個(gè)頁面下載的影響

如果把腳本文件放在頭部个盆,那么需要等到所有腳本下載并執(zhí)行完畢后才能下載圖片等其他資源脖岛,這是多么的可怕啊。但如果我們把腳本放在body標(biāo)簽的尾部颊亮,則可以是其它資源的下載和腳本的下載與執(zhí)行并發(fā)進(jìn)行柴梆,能夠大大加快頁面的下載速度。

2. 減少script標(biāo)簽的數(shù)量终惑,減少延時(shí)

3. 不要把內(nèi)嵌腳本緊跟在link標(biāo)簽后面

這樣做會(huì)導(dǎo)致頁面阻塞去等待樣式表的下載绍在,因?yàn)樾枰_保內(nèi)嵌腳本在執(zhí)行時(shí)能獲得最準(zhǔn)確的樣式信息。

4. 減少外鏈腳本文件的數(shù)量——將多個(gè)外鏈JS文件合并成一個(gè)以減少HTTP開銷


無阻塞的腳本

無阻塞腳本意味著腳本的下載和執(zhí)行不阻塞其他資源的下載和頁面的解析雹有。

可以通過設(shè)置script標(biāo)簽的defer和async屬性使其擁有不阻塞的特性偿渡,它們僅對外部鏈接的script有效。?

帶有async或者defer的script都會(huì)立刻下載并不阻塞頁面解析霸奕,它們的不同之處在于script執(zhí)行的時(shí)機(jī)卸察。

(1)defer:

1、如果有多個(gè)設(shè)置了defer的script標(biāo)簽存在铅祸,則會(huì)按照順序執(zhí)行所有的script坑质;

2合武、defer 與 DOMContentLoaded

如果 script 標(biāo)簽中包含 defer,那么這一塊腳本將不會(huì)影響 HTML 文檔的解析涡扼,而是等到 HTML 解析完成后才會(huì)執(zhí)行稼跳。而 DOMContentLoaded 只有在 defer 腳本執(zhí)行結(jié)束后才會(huì)被觸發(fā)。 所以這意味著什么呢吃沪?HTML 文檔解析不受影響汤善,等 DOM 構(gòu)建完成之后 defer 腳本執(zhí)行,但腳本執(zhí)行之前需要等待 CSSOM 構(gòu)建完成票彪。在 DOM红淡、CSSOM 構(gòu)建完畢,defer 腳本執(zhí)行完成之后降铸,DOMContentLoaded 事件觸發(fā)在旱。

contextload改為DOMContentLoad

(2)async:

1、async的執(zhí)行推掸,并不會(huì)按著script在頁面中的順序來執(zhí)行桶蝎,而是誰先加載完誰執(zhí)行。

2谅畅、async 與 DOMContentLoaded

如果 script 標(biāo)簽中包含 async登渣,則 HTML 文檔構(gòu)建不受影響,解析完畢后毡泻,DOMContentLoaded 觸發(fā)胜茧,而不需要等待 async 腳本執(zhí)行、樣式表加載等等仇味。

(3)defer和async的區(qū)別:

(1)defer?和?async?在網(wǎng)絡(luò)讀壬胪纭(下載)這塊兒是一樣的,都是異步的(相較于 HTML 解析)

(2)它倆的差別在于腳本下載完之后何時(shí)執(zhí)行邪铲,顯然?defer?是最接近我們對于應(yīng)用腳本加載和執(zhí)行的要求的

(3)關(guān)于?defer芬位,此圖未盡之處在于它是按照加載順序執(zhí)行腳本的,這一點(diǎn)要善加利用

(4)async?則是一個(gè)亂序執(zhí)行的主带到,反正對它來說腳本的加載和執(zhí)行是緊緊挨著的昧碉,所以不管你聲明的順序如何,只要它加載完了就會(huì)立刻執(zhí)行

仔細(xì)想想揽惹,async?對于應(yīng)用腳本的用處不大被饿,因?yàn)樗耆豢紤]依賴(哪怕是最低級的順序執(zhí)行),不過它對于那些可以不依賴任何腳本或不被任何腳本依賴的腳本來說卻是非常合適的搪搏,最典型的例子:Google Analytics


注意:帶有defer屬性的腳本執(zhí)行也不一定按照順序執(zhí)行狭握,有風(fēng)險(xiǎn)!7枘纭论颅!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末哎垦,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子恃疯,更是在濱河造成了極大的恐慌漏设,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,723評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件今妄,死亡現(xiàn)場離奇詭異郑口,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)盾鳞,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,485評論 2 382
  • 文/潘曉璐 我一進(jìn)店門犬性,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人腾仅,你說我怎么就攤上這事乒裆。” “怎么了攒砖?”我有些...
    開封第一講書人閱讀 152,998評論 0 344
  • 文/不壞的土叔 我叫張陵缸兔,是天一觀的道長日裙。 經(jīng)常有香客問我吹艇,道長,這世上最難降的妖魔是什么昂拂? 我笑而不...
    開封第一講書人閱讀 55,323評論 1 279
  • 正文 為了忘掉前任受神,我火速辦了婚禮,結(jié)果婚禮上格侯,老公的妹妹穿的比我還像新娘鼻听。我一直安慰自己,他們只是感情好联四,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,355評論 5 374
  • 文/花漫 我一把揭開白布撑碴。 她就那樣靜靜地躺著,像睡著了一般朝墩。 火紅的嫁衣襯著肌膚如雪醉拓。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,079評論 1 285
  • 那天收苏,我揣著相機(jī)與錄音亿卤,去河邊找鬼。 笑死鹿霸,一個(gè)胖子當(dāng)著我的面吹牛排吴,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播懦鼠,決...
    沈念sama閱讀 38,389評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼钻哩,長吁一口氣:“原來是場噩夢啊……” “哼屹堰!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起街氢,我...
    開封第一講書人閱讀 37,019評論 0 259
  • 序言:老撾萬榮一對情侶失蹤双藕,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后阳仔,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體忧陪,經(jīng)...
    沈念sama閱讀 43,519評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,971評論 2 325
  • 正文 我和宋清朗相戀三年近范,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了嘶摊。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,100評論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡评矩,死狀恐怖叶堆,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情斥杜,我是刑警寧澤虱颗,帶...
    沈念sama閱讀 33,738評論 4 324
  • 正文 年R本政府宣布,位于F島的核電站蔗喂,受9級特大地震影響忘渔,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜缰儿,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,293評論 3 307
  • 文/蒙蒙 一畦粮、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧乖阵,春花似錦宣赔、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,289評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至对蒲,卻和暖如春钩蚊,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背齐蔽。 一陣腳步聲響...
    開封第一講書人閱讀 31,517評論 1 262
  • 我被黑心中介騙來泰國打工两疚, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人含滴。 一個(gè)月前我還...
    沈念sama閱讀 45,547評論 2 354
  • 正文 我出身青樓诱渤,卻偏偏與公主長得像,于是被迫代替她去往敵國和親谈况。 傳聞我的和親對象是個(gè)殘疾皇子勺美,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,834評論 2 345

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

  • JavaScript代碼嵌入網(wǎng)頁的方法 JavaScript代碼只有嵌入網(wǎng)頁递胧,才能在用戶瀏覽網(wǎng)頁時(shí)運(yùn)行。 網(wǎng)頁中嵌...
    許先生__閱讀 1,146評論 0 1
  • JavaScript腳本對現(xiàn)代網(wǎng)站來說是必不可少的赡茸。當(dāng)用戶訪問站點(diǎn)缎脾,需要下載各種資源,例如JS腳本占卧,CSS遗菠,圖片,...
    張歆琳閱讀 9,051評論 0 24
  • 簡單介紹JavaScript的發(fā)展歷史 JavaScript因互聯(lián)網(wǎng)而生华蜒,回顧它的歷史要從瀏覽器的歷史講起辙纬。 19...
    _Dot912閱讀 479評論 0 3
  • 本文總結(jié)一下瀏覽器在 javascript 的加載方式。關(guān)鍵詞:異步加載(async loading)叭喜,延遲加載(...
    4ea0af17fd67閱讀 1,055評論 0 2
  • 前端必讀:瀏覽器內(nèi)部工作原理[https://kb.cnblogs.com/page/129756/] 作者: T...
    我是強(qiáng)強(qiáng)閱讀 1,133評論 0 2