面試過程中,常常遇到這樣一道面試題,輸入URL到頁面加載完畢,瀏覽器做了哪些工作?
首先輸入一個URL,你會看到瀏覽器上面的標簽頁出現了一個loading圖標,開始時是逆時針旋轉,接著順時針旋轉,當前頁面消失,顯示我們常說的空白頁面,接著出現顯示我們請求的新頁面。此時如果網絡很差,你有可能看到短暫的DOM頁面,然后再看到渲染后的正常頁面,這是從表面看到的加載過程,實際瀏覽器做的要多得多。
為什么瀏覽器這么多戲呢?直接顯示不好嗎,當然不行,就像喝粥,能直接吃米、喝水嗎?
在用戶輸入URL到頁面展示,瀏覽器要先向服務器獲取前端資源,然后再將服務器返回的字節流轉化成對應的頁面,每一階段都需要瀏覽器對應的能力進行處理的。
作為前端開發,了解整個過程其實很重要,只有知道了瀏覽器加載頁面的整個過程,才能在開發中避免可能跳的坑,才能在發現問題后迅速定位問題,才能在性能優化時提出更多的解決方案。
比如下面問題,看了文章相信你就知道了為什么了
為什么會存在空白頁面?(為了解決這個問題,各大廠都在實踐各種方案)
為什么js要在Dom后面引入
為什么有個頁面崩潰會導致多個頁面崩潰
瀏覽器的緩存策略是怎樣的?
為什么我們常常修改host就可以訪問對應的域名
等等
為了看懂下面的內容,這里必須要了解下現代瀏覽器的多進程架構
,進程
和線程
的關系等知識點。
瀏覽器也是從單個進程架構一步步迭代到現代的多進程架構。
如上圖,我們可以看到線程
和進程
的關系
通常一個程序實例就是一個進程,瀏覽器會為他分配內存空間。
一個進程間的數據是共享的,單線程就是一個進程包含一個線程,一個線程處理所有的任務
多線程就是,一個進程中包含多個線程可以同時執行任務,共享數據和內存
線程不能多帶帶存在,必須依附于進程,一個線程失敗,會導致進程執行失敗,進程銷毀,內存會被立即回收。
下圖是我們打開一個掘金首頁后,再打開任務管理器,觀察發現,此時瀏覽器包括的進程有很多,瀏覽器主進程,GPU進程,網絡進程,存儲進程,音頻進程,渲染進程,多個插件進程。
這些進程負責的功能如下:
進程 | 說明 |
---|---|
瀏覽器進程 | 負責瀏覽器各個子進程的通信,處理瀏覽器界面,包括地址欄等 |
渲染進程 | 也就是我們看到的圖中的標簽頁進程,也就是我們常說的瀏覽器內核,v8就在這個進程。主要負責解析html、js、css渲染頁面等 |
網絡進程 | 負責發起網絡請求,解析返回頭信息 |
GUI進程 | 負責將渲染進程生成的圖塊轉化成位圖 |
渲染進程是運行在沙箱之中的,可以執行js,但是不能獲取系統權限,和瀏覽器進程通過IPC通訊。這是為了保證瀏覽器進程的安全,鎖進沙箱,即使有惡意代碼,也不能突破沙箱讀取或寫入系統信息。
通過上圖,我們已經知道線程是不能獨立存在的,必須依附于進程。這里我們主要關注下渲染進程,因為他的主要工作就是:完成頁面的渲染和展示。
如圖,我們可以看到渲染進程包括很多線程,除了圖上展示的,還有合成線程等,各有各的作用,具體內容,我們將會在后面一章節,瀏覽器渲染原理分析中在來討論。
從用戶輸入域名到瀏覽器渲染頁面完成的過程,可以分為以下幾個部分:
1、輸入信息處理
2、網絡請求
3、服務器返回請求資源
4、瀏覽器渲染
這里每一步涉及到的知識都非常多,其中緩存也在每個階段占了很大比重,接著展開描述前三個階段:
當輸入一個URL,瀏覽器會判斷輸入信息是檢索信息還是請求URL
如果是檢索的信息,就構建請求搜索的URL,調用瀏覽器默認的搜索引擎進行檢索。
如果符合URL格式,瀏覽器主進程就通過IPC通信機制將URL發送給網絡進程。
1)網絡進程首先會查找瀏覽器緩存,判斷緩存是否存在,是否過期
如果存在且不過期,就直接返回緩存信息。具體的緩存策略可以接著看下面的瀏覽器緩存策略
2)如果沒有緩存或過期,就開始進行DNS解析
DNS解析的過程也很復雜,最終目的就是拿到目標主機的IP地址,具體的解析過程可以看下面的域名解析
3)建立http連接或https連接
http通過三次握手建立連接
https需要建立TLS連接,瀏覽器會驗證網站的數字證書是否合法,是否到期,是否安全等,這里https有自己的一套認證邏輯,我們重點不在這一塊。
這里兩個問題常被問到,不了解可以學習一下
http和https的區別?
簡述三次握手、四次揮手?
4)發送請求
網絡進程會構建http請求頭,向服務器發送實際請求
5)網絡傳輸,服務器處理,返回對應的資源
請求從應用層發出,經過運輸層、網絡層、物理層、數據鏈路層找到服務器,服務器拿到請求信息,返回對應的資源
這里的服務器可能是代理服務器,也可能是CDN節點,會判斷當前數據是否存在緩存,如果有緩存且有效,直接返回(具體看配置的緩存策略),否則才會從服務器獲取。
網絡傳輸數據也是很復雜的過程,具體可以看下面簡單的介紹計算機網絡體系模型
1)處理返回信息
瀏覽器接收到服務器返回的資源信息,網絡進程首先會解析返回的頭信息,查看是否有Location字段,如果有的話,再次發起請求,很常見的就是請求http的站點,然后重定向到https。
如下圖我們輸入的是http://www.taobao.com/
,接口返回307內部重定向,然后瀏覽器再次進行了請求https//www.taobao.com/
通過返回頭字段Content-Type
判斷文件類型,如果其他類型,就調用不同的進程處理,如果是html類型,繼續處理。
網絡進程拿到返回的資源信息,會發送消息“提交導航”到瀏覽器主進程,瀏覽器主進程發送信息“提交文檔”,提醒渲染進程準備接收返回的資源信息
渲染進程和網絡進程構建通道,接收資源信息,并發送消息“提交文檔”給瀏覽器主進程,告訴瀏覽器主進程我準備好了,瀏覽器主進程開始刷新頁面,url、安全等信息。
此時頁面將會觸發beforeunload
事件,在頁面退出之前允許用戶選擇終止該流程(常應用于表單提交頁面)。如果不監控該方法,瀏覽器就直接替換當前頁面。
然后在渲染線程繪制出頁面的之前,頁面將存在空白時間,這就是各個技術團隊在攻克的技術點,怎樣讓空白時間最短,這個時間取決于當前頁面渲染的時長,那么我們還是要了解下瀏覽器是如何渲染服務器返回的資源。
8)四次揮手
資源傳輸完畢,斷開連接
我們打開任務管理器,看到如下圖所示
我們發現很多標簽頁都是多帶帶的一個進程,但是其中一些標簽頁確是共用一個渲染進程,為什么會這樣?
其實瀏覽器對于在當前站點打開的新Tab頁面會做一些優化,如果他們同源,且執行環境相同,會直接復用當前站點的渲染進程。
這樣就可以提高渲染的性能,也能讓父窗口和子窗口建立關聯,但這樣也造成了一定的隱患
公用一個進程,如果當前進程中的一個線程出現問題,當前進程就會崩潰,公用同一個進程的頁面也會崩潰。
如果有惡意腳本就可以攻擊新打開的頁面,在新打開的頁面中我們可以通過window.opener
獲取父頁面的操作權限
如果沒有關聯
如果有關聯
這就是我們現實中可能會遇到的一個頁面奔潰,其他同源站點全部退出的現象。
那么這種共同使用一個渲染進程是如果出現的呢?在日常編碼中我們常常有這三種方式:
一般情況下,項目中我們跳轉采用a標簽,如果調整的是同源頁面,會出現
<a href="http://www.baidu.com"></a> 復制代碼
該方法使用最新版的谷歌測試發現,在當前頁面內打開一個同源的站點,使用的是獨立的進程,這和預期的不符合,后面會繼續測試看看。
但是一般情況下,我們可以給a標簽加上屬性rel="noopener norefferrer"
來保證不同頁面使用不同的進程。
window.open("http://www.baidu.com") 復制代碼
使用window.open
打開相同站點,肯定會出現使用同一個渲染進程,如果要規避,就要增加如下代碼,去除兩者的關聯
let newWin = window.open("http://my.dome.com") newWin.opener = null 復制代碼
頁面中采用iframe框架引入其他頁面,則iframe會獨立成輔助框架,有自己的渲染進程,如果同源會采用同一個渲染進程。
存儲策略
強緩存
協商緩存
瀏覽器的緩存策略,有助于提高網頁加載速度,減輕服務器壓力。
具體緩存的過程如圖:
詳細說明:
1、當我們輸入url,瀏覽器會去查看自身是否有緩存,如果沒有緩存會直接請求服務器獲取資源,并緩存到瀏覽器一份,返回數據會攜帶ETag
字段和Last-Modified
字段,狀態碼200 OK(from memory cache),
其中ETag
是文件計算的hash值,如果文件不發生改變,這個值不會變。Last-Modified
是文件最后的修改時間,如果文件更新或者覆蓋就會顯示最新的時間
2、如果瀏覽器有緩存,此時檢查http的請求頭,看cache-control、expires字段,判斷是否過了緩存的有效期,如果沒有過有效期,則返回200狀態碼和對應的緩存數據。
此時是強緩存
expires是http1.0的定義,返回一個絕對的時間GMT,為過期時間。這就導致如果服務器時間和瀏覽器時間不一致,可能會使緩存失效。
cache-control是http1.1的定義,可以定義的值有
max-age=600 表示最長有效期為600s
no-cache 不走瀏覽器緩存,每次都去瀏覽器協商緩存
no-store 每次都請求最新的資源
private 私有,只能在用戶終端緩存,不能在cdn或代理服務器緩存
public 公有,可以在所有節點緩存
兩者同時存在,cache-control優先級高
3、如果瀏覽器緩存已過期,就攜帶請求頭字段If-None-Match
和If-Modified-Since
去服務器拉取資源,服務器看到這兩個字段,發現和當前服務器資源一致,就直接返回緩存和狀態碼304。服務器一般會先驗證If-None-Match/ETag
,如果不變,再去驗證If-Modified-Since/Last-Modified
其中If-Modified-Since
就是之前返回的Last-Modified
,If-None-Match
就是之前返回的ETag
如果第一次請求,默認沒有緩存,瀏覽器將會進行緩存,瀏覽器緩存的都是派生文件, 比如css、js、img等不常變動的文件,內存緩存肯定比較小,所以會緩存一下js,頁面關閉就清空了,disk memory 會在的時間會久一點。
DNS就是域名系統,作用是將域名解析成對應的IP地址。具體的解析過程
1、輸入一個url,首先瀏覽器會對url進行解析,取出主機名
2、接著查找瀏覽器自身的DNS緩存,查到返回對應IP
3、沒有找到,在本機找Host文件是否有對應的IP(host文件就是域名和ip的映射關系表),查到就返回IP
3、沒有的話,本地DNS服務器開始查找,向各級的DNS服務器發送查詢報文,獲取對應的IP地址
在每次查找的過程中,瀏覽器,應用程序,DNS服務器都會對域名進行緩存,如果命中緩存,DNS會直接返回對應的IP,沒有命中則繼續查找相關的域名服務器,定位IP
分析可知這個階段,我們能優化的方法有限,常見的做法有:
1、在html文件增加DNS緩存標簽
2、通過將域名解析到多個IP,做DNS的負載均衡
<link rel="dns-prefetch" href="//g.alicdn.com" /> 復制代碼
上面代碼,會預取g.test.com
解析
<meta http-equiv="x-dns-prefetch-control" content="on"> 復制代碼
上面代碼,設置自動開啟DNS解析功能
這里的網絡請求,我們默認為http請求。
1、首先如果是第一次請求,域名經過DNS解析拿到映射的IP
2、這里客戶端發送http報文給對應的服務器,這個過程中要經過應用層、運輸層、網絡層、數據鏈路層和物理層對數據報的層層處理
3、經過上一步的三次確認,也就是客戶端和服務器(或代理服務器)進行三次握手建立TCP連接
4、然后服務器返回對應的資源給客戶端
5、如果是第二次及以上的請求,瀏覽器或服務器會通過http的header參數,判斷資源是否過期,如果沒有過期,則使用緩存,如果過期,就去服務器拿新的資源
第二步,這里客戶端發送http報文給對應的服務器,具體的過程為:
1、首先應用層提供了很多協議,包括:http、ftp、POP3、IMAP,這里瀏覽器使用的是http協議,首先瀏覽器會在應用層,把請求的數據報按照http協議要求的格式,定義一系列請求的字段,推進TCP套接字,等待運輸層接收。
2、運輸層主要的協議有:TCP和UDP,運輸層拿到數據報以后,會先看是否和目的主機建立連接,如果沒有,則進行三次握手,建立TCP連接。如果連接成功,會對數據報進一步封裝,增加源主機端口號和目的主機端口號,進行差錯檢測,然后傳遞到網絡層。
3、網絡層主要協議有:IP協議,接收運輸層的數據報,然后增加目的主機IP,封裝成一段段符合IP協議的IP數據報,經過若干個路由到達數據鏈路層
4、數據鏈路層有ARP協議,可以通過IP地址解析目標地址的mac地址,通過物理層轉發出去,到達目的局域網后,通過廣播,被目的主機接收
服務器獲取請求,協商緩存查看資源是否有變化,如果沒有變化返回緩存資源。
CDN緩存
這里如果存在代理服務器或者CDN節點,那么相當于增加了一個緩存節點,首先請求會轉發到最新的CDN節點,CDN節點收到請求后會判斷當前資源是否過期cache-control
,如果過期就回源請求最新的資源,如果沒有過期就返回緩存資源。
CDN的存在解決了跨地域請求的時延問題;對服務器壓力進行了分流。
四次揮手:如果請求結束,服務器和客戶端進行四次握手,斷開連接。
具體的渲染是很復雜的,篇幅有限,接著下一篇繼續。
瀏覽器為什么要進行url解析,編碼規則是什么,如何解析
域名解析的過程,遞歸查詢,迭代查詢
網絡請求三次握手、四次揮手原理,為什么要三次握手,兩次不行嗎
網絡請求的過程,計算機網絡體系
ping的原理是什么
http緩存的分類,強緩存和協商緩存、啟發式緩存
如何設置http緩存
http和https區別,不同版本的區別
瀏覽器的渲染原理、渲染順序
頁面渲染優化
什么是重繪和回流
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/127955.html
摘要:分層由高到低分別為應用層傳輸層網絡層數據鏈路層。狀態碼由三位數字組成,其中比較常見的是表示請求成功。在返回狀態碼的同時,響應報文也會附帶重定向的,客戶端接收到后將請求的做相應的改變再重新發送。 當在瀏覽器地址欄輸入網址,如:http://cn.bing.com 后瀏覽器是怎么把最終的頁面呈現出來的呢?這個過程可以大致分為兩個部分:網絡通信和頁面渲染。 一、網絡通信 互聯網內各網絡設備間...
摘要:在上述過程再細化為瀏覽器搜索自己的緩存。至此,瀏覽器已經得到了域名對應的地址。具體過程如下在中這一過程如下首先是字節流,經過解碼之后是字符流,然后通過詞法分析器會被解釋成詞語,之后經過語法分析器構建成節點,最后這些節點被組建成一棵樹。 面試的時候,我們經常會被問從在瀏覽器地址欄中輸入 url 到頁面展現的短短幾秒內瀏覽器究竟做了什么?那么瀏覽器到底做了啥? 瀏覽器的多進程架構一個好的程...
摘要:在上述過程再細化為瀏覽器搜索自己的緩存。至此,瀏覽器已經得到了域名對應的地址。具體過程如下在中這一過程如下首先是字節流,經過解碼之后是字符流,然后通過詞法分析器會被解釋成詞語,之后經過語法分析器構建成節點,最后這些節點被組建成一棵樹。 面試的時候,我們經常會被問從在瀏覽器地址欄中輸入 url 到頁面展現的短短幾秒內瀏覽器究竟做了什么?那么瀏覽器到底做了啥? 瀏覽器的多進程架構一個好的程...
摘要:在上述過程再細化為瀏覽器搜索自己的緩存。至此,瀏覽器已經得到了域名對應的地址。具體過程如下在中這一過程如下首先是字節流,經過解碼之后是字符流,然后通過詞法分析器會被解釋成詞語,之后經過語法分析器構建成節點,最后這些節點被組建成一棵樹。 面試的時候,我們經常會被問從在瀏覽器地址欄中輸入 url 到頁面展現的短短幾秒內瀏覽器究竟做了什么?那么瀏覽器到底做了啥? 瀏覽器的多進程架構一個好的程...
摘要:文章同步到技術內幕之頁面渲染過程最近拜讀了傳說中的技術內幕一書,有很大收獲,尤其是對頁面渲染有了較深的認識。解析語法分析,基于詞法解釋器生成的新標記,構建成抽象語法樹,解析器嘗試將其與某條語法規則進行匹配。 文章同步到github《Webkit技術內幕》之頁面渲染過程 最近拜讀了傳說中的《Webkit技術內幕》一書,有很大收獲,尤其是對頁面渲染有了較深的認識。由于功力有限,而且書中設...
閱讀 289·2024-11-07 18:25
閱讀 130366·2024-02-01 10:43
閱讀 868·2024-01-31 14:58
閱讀 828·2024-01-31 14:54
閱讀 82766·2024-01-29 17:11
閱讀 3048·2024-01-25 14:55
閱讀 1985·2023-06-02 13:36
閱讀 3033·2023-05-23 10:26