起因
看了一篇文章《阿里面試官的”說一下從url輸入到返回請求的過程“問的難度就是不一樣!》
打算好好補(bǔ)一下這方面的細(xì)節(jié)和計(jì)算機(jī)網(wǎng)絡(luò)的知識
從進(jìn)程的角度看問題
瀏覽器進(jìn)程:
用戶輸入內(nèi)容,進(jìn)行URL 解析(編碼)
- 如果是文本,則拼接成默認(rèn)搜索引擎加關(guān)鍵字的 URL 進(jìn)行搜索(現(xiàn)代瀏覽器功能)
- 如果是 URL 就進(jìn)行頁面訪問請求,并加上協(xié)議頭(http、https 的區(qū)別)
網(wǎng)絡(luò)進(jìn)程:
- 查詢緩存(緩存相關(guān)知識)
- 如果有瀏覽器本地緩存可用則使用本地緩存
- DNS 解析(DNS 相關(guān))
- 通過 DNS 來查詢 IP 地址
- DNS 先查本地、后查運(yùn)營商、逐級網(wǎng)上查。(域名解析是從后往前查的)
- 拿到 IP 地址發(fā)起 HTTP 請求(這塊可以問網(wǎng)絡(luò)相關(guān)各種基礎(chǔ)知識,TCP、IP、UDP、HTTPS、HTTP2)
- 建立 TCP 三次握手連接
- 如果是 HTTPS 建立 TLS 安全通道連接(HTTPS 加密方式)
- 發(fā)送 HTTP 請求,這個(gè)請求可能回到代理服務(wù)器或者源服務(wù)器。(服務(wù)器代理)
- 拿到 HTTP 響應(yīng)(HTTP 響應(yīng)碼)
- 根據(jù) Content-Type 來判斷響應(yīng)文件類型(常用 HTTP 響應(yīng)頭的作用)
? stream 類,瀏覽器啟動下載界面下載文件。
? text、圖片類,瀏覽器直接展示在頁面上
? html 類型,瀏覽器會進(jìn)行頁面解析。
渲染進(jìn)程:
- 頁面解析
- 網(wǎng)絡(luò)進(jìn)程向渲染進(jìn)程傳輸 HTML 數(shù)據(jù)
- 對 HTML 進(jìn)行詞法分析,通過堆棧算法構(gòu)建 DOM 樹。(AST語法樹)
- 如果遇到外部資源,瀏覽器會交給網(wǎng)絡(luò)進(jìn)程去下載。
- 構(gòu)建完 DOM 樹的同時(shí),將 CSS 代碼轉(zhuǎn)為瀏覽器可以理解的 StyleSheets
? 標(biāo)準(zhǔn)化樣式屬性值(單位、大?。?br> ? 計(jì)算出 DOM 樹每個(gè)節(jié)點(diǎn)的具體樣式
? 計(jì)算每個(gè) DOM 節(jié)點(diǎn)的父節(jié)點(diǎn)們的樣式(樣式繼承) - DOM 樹構(gòu)建完成后,合并 StyleSheets 構(gòu)建出 CSSOM 渲染樹。
- 排版:遍歷渲染樹,計(jì)算元素的坐標(biāo)位置。
- 分層:為節(jié)點(diǎn)生成圖層
- 繪制:用瀏覽器指令逐條繪制頁面元素。(如何避免重繪重排)
- 柵格化
- 合成
文章評論區(qū)有人總結(jié)的點(diǎn),我覺得比較清晰了
要點(diǎn)
為什么要進(jìn)行URL解析?
網(wǎng)絡(luò)標(biāo)準(zhǔn)規(guī)定了URL只能是數(shù)字和字母還有一些特殊符號,如果不轉(zhuǎn)義會出現(xiàn)歧義。url編碼的規(guī)則是什么?
URL編碼又稱百分號編碼,交給瀏覽器自己決定。使用Javascript先對URL編碼,然后再向服務(wù)器提交,不要給瀏覽器插手的機(jī)會。因?yàn)镴avascript的輸出總是一致的,所以就保證了服務(wù)器得到的數(shù)據(jù)是格式統(tǒng)一的。(參考阮老師的《關(guān)于URL編碼》)dns的解析流程(淺析DNS域名解析過程)
第一步:檢查瀏覽器緩存中是否緩存過該域名對應(yīng)的IP地址
第二步:如果在瀏覽器緩存中沒有找到IP,那么將繼續(xù)查找本機(jī)系統(tǒng)是否緩存過IP
第三步:向本地域名解析服務(wù)系統(tǒng)發(fā)起域名解析的請求(校園網(wǎng)、移動、電信或聯(lián)通運(yùn)營商)大部分的解析工作到這里就差不多已經(jīng)結(jié)束了,負(fù)責(zé)了大部分的解析工作。
第四步:向根域名解析服務(wù)器發(fā)起域名解析請求
第五步:根域名服務(wù)器返回gTLD域名解析服務(wù)器地址(Generic top-level domain通用頂級域)gTLD是國際頂級域名服務(wù)器,如.com、.cn、.org等,全球只有13臺左右
第六步:向gTLD服務(wù)器發(fā)起解析請求
第七步:gTLD服務(wù)器接收請求并返回Name Server服務(wù)器(找到對應(yīng)的域名服務(wù)器將承擔(dān)域名解析的任務(wù),例如用戶在某個(gè)域名服務(wù)提供商申請的域名)
第八步:Name Server服務(wù)器返回IP地址給本地服務(wù)器
第九步:本地域名服務(wù)器緩存解析結(jié)果
第十步:返回解析結(jié)果給用戶如何做html的dns優(yōu)化?
<link rel="dns-prefetch" >
// a標(biāo)簽?zāi)J(rèn)啟動在https無效需要設(shè)置開啟
<meta http-equiv="x-dns-prefetch-control" content="on">
DNS Prefetch 是一種DNS 預(yù)解析技術(shù),當(dāng)你瀏覽網(wǎng)頁時(shí),瀏覽器會在加載網(wǎng)頁時(shí)對網(wǎng)頁中的域名進(jìn)行解析緩存,這樣在你單擊當(dāng)前網(wǎng)頁中的連接時(shí)就無需進(jìn)行DNS的解析,減少用戶等待時(shí)間,提高用戶體驗(yàn)。
- 從網(wǎng)卡把數(shù)據(jù)包傳輸出去到服務(wù)器發(fā)生了什么?(OSI參考模型Open System Interconnection Model)(OSI參考模型解析)
問題本質(zhì)就是搞懂OSI參考模型的職能:
- 物理層的主要功能是完成相鄰節(jié)點(diǎn)之間原始比特流的傳輸,用物理信號來表示數(shù)據(jù)。物理層常用的網(wǎng)絡(luò)設(shè)備有中繼器和集線器。
- 數(shù)據(jù)鏈路層的主要功能是在不可靠的物理線路上進(jìn)行數(shù)據(jù)的可靠傳輸,為了保證數(shù)據(jù)的可靠傳輸,發(fā)送方把數(shù)據(jù)封裝成幀的形式。數(shù)據(jù)鏈路層的常用網(wǎng)絡(luò)設(shè)備有網(wǎng)橋,交換機(jī),網(wǎng)卡等。
- 網(wǎng)絡(luò)層的主要功能是完成網(wǎng)絡(luò)中主機(jī)間的報(bào)文傳輸,它對應(yīng)的是網(wǎng)絡(luò)主機(jī)到網(wǎng)絡(luò)主機(jī)的報(bào)文傳輸。該層常用的網(wǎng)絡(luò)設(shè)備有路由器,三層交換機(jī)等。
- 傳輸層的主要功能是完成網(wǎng)絡(luò)中不同主機(jī)上的用戶進(jìn)程之間可靠的數(shù)據(jù)通信,傳輸層是真正的端到端的連接。實(shí)質(zhì)也是傳輸數(shù)據(jù),只不過它對應(yīng)的直接是進(jìn)程與進(jìn)程之間的數(shù)據(jù)傳輸,它依據(jù)的是進(jìn)程的端口號。
- 會話層允許不同機(jī)器上的用戶之間建立會話關(guān)系。會話層提供的服務(wù)之一是管理對話控制。
- 表示層關(guān)心的是所傳送信息的語法和語義。表示層就是對數(shù)據(jù)的解碼,解釋成程序都能理解的程序語言。
- 應(yīng)用層的功能就是將解碼后的計(jì)算機(jī)程序語言表示出來,從而展示給用戶,實(shí)現(xiàn)用戶操作計(jì)算機(jī)程序的目的。

參考:探究!一個(gè)數(shù)據(jù)包在網(wǎng)絡(luò)中的心路歷程
- 關(guān)于緩存
- HTTP緩存:強(qiáng)緩存(Expires、Cache-Control)協(xié)商緩存(Etag/If-None-Match、Last-Modified/If-Modified-Since)
- 瀏覽器緩存:本地小容量緩存(Cookie、LocalStorage、SessionStorage)本地大容量緩存(WebSql、IndexDB)
- 應(yīng)用程序緩存:應(yīng)用緩存、PWA
from memory cache和from disk cache分別指從內(nèi)存和硬盤讀取緩存,瀏覽器會優(yōu)先去內(nèi)存里讀取緩存。隱私模式、base64圖片等通常從內(nèi)存讀取,特征快、時(shí)效性。
- 解析html
cssom + doomTree = html,然后布局和繪制
- 構(gòu)建DOM樹(DOM tree):從上到下解析HTML文檔生成DOM節(jié)點(diǎn)樹(DOM tree);
- 構(gòu)建CSSOM(CSS Object Model)樹:加載解析樣式生成CSSOM樹;
- 執(zhí)行JavaScript:加載并執(zhí)行JavaScript代碼(包括內(nèi)聯(lián)代碼或外聯(lián)JavaScript文件);
- 構(gòu)建渲染樹(render tree):根據(jù)DOM樹和CSSOM樹,生成渲染樹(render tree);
- 渲染樹:按順序展示在屏幕上的一系列矩形,這些矩形帶有字體,顏色和尺寸等視覺屬性;
- 布局(layout):根據(jù)渲染樹將節(jié)點(diǎn)樹的每一個(gè)節(jié)點(diǎn)布局在屏幕上的正確位置;
- 繪制(painting):遍歷渲染樹繪制所有節(jié)點(diǎn),為每一個(gè)節(jié)點(diǎn)適用對應(yīng)的樣式,這一過程是通過UI后端模塊完成;
- 頁面渲染優(yōu)化
- HTML文檔結(jié)構(gòu)層次盡量少,最好不深于六層;
- 腳本盡量后放,放在前即可;
- 少量首屏樣式內(nèi)聯(lián)放在標(biāo)簽內(nèi);
- 樣式結(jié)構(gòu)層次盡量簡單;
- 在腳本中盡量減少DOM操作,盡量緩存訪問DOM的樣式信息,避免過度觸發(fā)回流;
- 減少通過JavaScript代碼修改元素樣式,盡量使用修改class名方式操作樣式或動畫;
- 動畫盡量使用在絕對定位或固定定位的元素上;
- 隱藏在屏幕外,或在頁面滾動時(shí),盡量停止動畫;
- 盡量緩存DOM查找,查找器盡量簡潔;
- 涉及多域名的網(wǎng)站,可以開啟域名預(yù)解析
心得
確實(shí)是比較全面的一道題了,典型的從點(diǎn)到面。牽扯到網(wǎng)絡(luò)請求、緩存、渲染等等問題,甚至可以聊tcp的三次握手,水太深了。
P.S.懶狗本質(zhì)太久沒整理了,忙碌起來還是要抽個(gè)時(shí)間沉淀一下,后面可能想到啥寫啥吧。
