1者铜、瀏覽器的地址欄輸入URL并按下回車腔丧。
2、瀏覽器查找當前URL是否存在緩存作烟,并比較緩存是否過期愉粤。
3、DNS解析URL對應的IP拿撩。(DNS優(yōu)化 DNS緩存 DNS負載均衡)
4衣厘、根據(jù)IP建立TCP連接(三次握手)。
5绷雏、HTTP發(fā)起請求头滔。
6、服務器處理請求涎显,瀏覽器接收HTTP響應。
7兴猩、渲染頁面期吓,構建DOM樹。
8、關閉TCP連接(四次揮手)讨勤。
DNS解析
TCP連接
發(fā)送HTTP請求
服務器處理請求并返回HTTP報文
瀏覽器解析渲染頁面
連接結束
瀏覽器解析渲染頁面.png
1箭跳、從瀏覽器接收url到開啟網(wǎng)絡請求線程(涉及到:瀏覽器機制,線程和進程之間的關系等)
2潭千、開啟網(wǎng)絡線程到發(fā)出一個完整的http請求(涉及到:dns查詢谱姓,tcp/ip請求,5層網(wǎng)絡協(xié)議棧等)3刨晴、從服務器接收到請求到對應后臺接收到請求(涉及到:均衡負載屉来,安全攔截,后臺內(nèi)部的處理等)
4狈癞、后臺和前臺的http交互(涉及到:http頭茄靠,響應碼,報文結構蝶桶,cookie等慨绳,可以提下靜態(tài)資源的cookie優(yōu)化,以及編碼解碼如gzip壓縮等)
5真竖、緩存問題:http緩存(涉及到:涉及到http緩存頭部脐雪,etag,expired恢共,cache-control等)
6喂江、瀏覽器接收到http數(shù)據(jù)包后的解析流程
(涉及到:html的詞法分析,然后解析成dom樹旁振,同時解析css生成css規(guī)則樹获询,合并生成render樹。然后layout布局拐袜、painting渲染吉嚣、復合圖層的合成、GPU繪制蹬铺、外鏈接處理尝哆、loaded和documentloaded等)
7、css可視化格式模型(涉及到:元素渲染規(guī)則甜攀,如:包含塊秋泄,控制框,BFC规阀,IFC等概念)
8恒序、js引擎解析過程(涉及到:js解釋階段,預處理階段谁撼,執(zhí)行階段生成執(zhí)行上下文歧胁,VO(全局對象),作用域鏈,回收機制等)
9喊巍、其他(擴展其他模塊:跨域屠缭,web安全等)
從瀏覽器接收到url到開啟網(wǎng)絡請求線程
涉及到:瀏覽器的進程和線程模型,js的運行機制崭参。
1呵曹、瀏覽器是多進程的
(1)瀏覽器是多進程的;
(2)不同類型的標簽頁會開啟一個新的進程何暮;
(3)相同類型的標簽頁會合并到一個進程中奄喂。
瀏覽器中各個進程以及作用:
1、瀏覽器進程:只有1個進程郭卫,
(1)負責管理各個標簽的創(chuàng)建和銷毀砍聊;
(2)負責瀏覽器頁面顯示;
(3)負責資源的管理和下載贰军;
GPU進程:最多1個進程玻蝌,負責3D繪制和硬件加速;
瀏覽器渲染進程:可以是多個進程词疼,瀏覽器的內(nèi)核俯树,每個tab頁一個進程,主要負責HTML贰盗,css许饿,js等文件的解析,執(zhí)行和渲染舵盈,以及事件處理等陋率。
瀏覽器渲染進程(內(nèi)核進程)
每一個tab頁面是瀏覽器內(nèi)核進程,然后這個每一個進程是多線程的
它有幾大類子線程:(1)GUI線程秽晚;(2)JS引擎線程瓦糟;(3)事件觸發(fā)線程;(4)定時器線程赴蝇;(5)異步的http網(wǎng)絡請求線程
200——表明該請求被成功地完成菩浙,所請求的資源發(fā)送回客戶端
304——自從上次請求后,請求的網(wǎng)頁未修改過句伶,請客戶端使用本地緩存
400——客戶端請求有錯(譬如可以是安全模塊攔截)
403——禁止訪問(譬如可以是未登錄時禁止)
401——請求未經(jīng)授權
404——資源未找到
500——服務器內(nèi)部錯誤
503——服務不可用
瀏覽器內(nèi)核拿到內(nèi)容后劲蜻,渲染大致分為以下幾步:
(1)解析html,構建DOM樹考余;同時解析CSS先嬉,生成CSS規(guī)則樹。
(2)合并DOM樹和CSS規(guī)則樹秃殉,生成Render樹
(3)布局Render樹(layout/reflow),負責各元素的尺寸坝初,位置計算浸剩。
(4)繪制render樹(paint)钾军,繪制頁面像素信息。
(5)瀏覽器會將各層的信息發(fā)給GPU。GPU會將各層合成(composite)迹卢,顯示在屏幕上扬虚。
Layout,也稱為Reflow樱哼,即回流哀九。一般意味著元素的內(nèi)容、結構搅幅、位置或尺寸發(fā)生了變化阅束,需要重新計算樣式和渲染樹。
Repaint茄唐,即重繪息裸。意味著元素發(fā)生的改變只是影響了元素的一些外觀之類的時候(例如,背景色沪编,邊框顏色呼盆,文字顏色等),此時只需要應用新樣式繪制這個元素就可以
什么引起回流:1.頁面渲染初始化 2.DOM結構改變蚁廓,比如刪除了某個節(jié)點 3.render樹變化访圃,比如減少了padding
4.窗口resize
5.最復雜的一種:獲取某些屬性,引發(fā)回流相嵌, 很多瀏覽器會對回流做優(yōu)化腿时,會等到數(shù)量足夠時做一次批處理回流, 但是除了render樹的直接變化饭宾,當獲取一些屬性時批糟,瀏覽器為了獲得正確的值也會觸發(fā)回流,這樣使得瀏覽器優(yōu)化無效
回流一定伴隨著重繪捏雌,重繪卻可以單獨出現(xiàn)跃赚。
優(yōu)化方案:
1)減少逐項更改樣式,做好一次性更改樣式性湿∥嘲粒或者將樣式定義為class,并一次性更新肤频。
(2)避免循環(huán)操作dom叹括,創(chuàng)建一個documentFragment或div,在他上面進行所有的dom操作宵荒,最后添加到window.document中汁雷。
(3)避免多次讀取offset等屬性净嘀,無法避免就將他們緩存到變量中。
(4)將復雜的元素絕對定位或者固定定位侠讯,使他們脫離文檔流挖藏,否則回流代價很高。
注意:改變字體大小會引起回流厢漩。
靜態(tài)資源:
css 下載時異步的膜眠,不會阻塞瀏覽器構建 DOM 樹。但會阻塞渲染
js腳本處理時溜嗜,阻塞瀏覽器的解析(defer 與 async去優(yōu)化)defer 是延遲執(zhí)行宵膨,而 async 是異步執(zhí)行。
遇到圖片等資源時炸宵,直接就是異步下載辟躏,不會阻塞解析,下載完畢后直接用圖片替換原有src的地方
JS的解析.png
Event Loop
即事件循環(huán)土全,是指瀏覽器或Node
的一種解決javaScript單線程
運行時不會阻塞
的一種機制捎琐,也就是我們經(jīng)常使用異步
的原理。
console.log('script start')
async function async1() {
await async2()
console.log('async1 end')
}
async function async2() {
console.log('async2 end')
}
async1()
setTimeout(function() {
console.log('setTimeout')
}, 0)
new Promise(resolve => {
console.log('Promise')
resolve()
})
.then(function() {
console.log('promise1')
})
.then(function() {
console.log('promise2')
})
console.log('script end')
//script start async2 end Promise script end async1 end promise1 promise2
首先涯曲,打印script start野哭,調(diào)用async1()時,返回一個Promise幻件,所以打印出來async2 end拨黔。
每個 await,會新產(chǎn)生一個promise,但這個過程本身是異步的绰沥,所以該await后面不會立即調(diào)用篱蝇。
繼續(xù)執(zhí)行同步代碼,打印Promise和script end徽曲,將then函數(shù)放入微任務隊列中等待執(zhí)行零截。
同步執(zhí)行完成之后,檢查微任務隊列是否為null秃臣,然后按照先入先出規(guī)則涧衙,依次執(zhí)行。
然后先執(zhí)行打印promise1,此時then的回調(diào)函數(shù)返回undefinde奥此,此時又有then的鏈式調(diào)用弧哎,又放入微任務隊列中,再次打印promise2稚虎。
再回到await的位置執(zhí)行返回的 Promise 的 resolve 函數(shù)撤嫩,這又會把 resolve 丟到微任務隊列中,打印async1 end蠢终。
當微任務隊列為空時序攘,執(zhí)行宏任務,打印setTimeout茴她。
JS是單線程運行,也就是說程奠,在同一個時間內(nèi)只能做一件事丈牢,所有的任務都需要排隊,前一個任務結束梦染,后一個任務才能開始赡麦。
但是又存在某些任務比較耗時朴皆,如IO讀寫等帕识,所以需要一種機制可以先執(zhí)行排在后面的任務,
這就是:同步任務(synchronous)和異步任務(asynchronous)遂铡。
JS的執(zhí)行機制就可以看做是一個主線程加上一個任務隊列(task queue)肮疗。
同步任務就是放在主線程上執(zhí)行的任務,異步任務是放在任務隊列中的任務扒接。
所有的同步任務在主線程上執(zhí)行伪货,形成一個執(zhí)行棧;
異步任務有了運行結果就會在任務隊列中放置一個事件;
腳本運行時先依次運行執(zhí)行棧钾怔,然后會從任務隊列里提取事件碱呼,運行任務隊列中的任務,
這個過程是不斷重復的宗侦,所以又叫做事件循環(huán)(Event loop)
JS代碼執(zhí)行前瀏覽器必須保證CSS文件已經(jīng)下載并加載完畢愚臀。
HTTP默認端口80,HTTPS默認端口443矾利。
DNS實際上是一個域名和IP對應的數(shù)據(jù)庫
第一次握手: 建立連接時姑裂,客戶端發(fā)送syn包(syn=j)到服務器,并進入等待服務器確認的狀態(tài)男旗;
第二次握手: 服務器收到syn包舶斧,必須確認客戶端的syn(ack=j+1),同時自己根據(jù)syn生成一個ACK包察皇,此時服務器進入等待狀態(tài)茴厉;
第三次握手: 客戶端收到服務器的ACK包,向服務器發(fā)送確認什荣,此包發(fā)送完畢矾缓,客戶端和服務器進入ESTABLISHED(TCP連接成功)狀態(tài),完成三次握手溃睹。
第一次握手是瀏覽器發(fā)完數(shù)據(jù)而账,然后發(fā)送FIN請求斷開連接。
第二次握手是服務器向客戶端發(fā)送ACK因篇,表示同意泞辐。
第三次握手是服務器可能還有數(shù)據(jù)向瀏覽器發(fā)送笔横,所以向瀏覽器發(fā)送ACK同時也發(fā)送FIN請求,是第三次握手咐吼。
第四次握手是瀏覽器接受返回的ACK吹缔,表示數(shù)據(jù)傳輸完成。
輸入url之后.png