從輸入URL到頁面加載發(fā)生了什么

從輸入URL到頁面加載發(fā)生了什么剪撬,之前百度前端寫過這篇文章摄乒,里面講解的非常的詳細。

總體來說分為以下幾個過程:

  1. DNS解析
  2. TCP連接
  3. 發(fā)送HTTP請求
  4. 服務(wù)器處理請求并返回HTTP報文
  5. 瀏覽器解析渲染頁面
  6. 連接結(jié)束

DNS解析

DNS解析的過程就是尋找哪臺機器上有你需要資源的過程婿奔。當你在瀏覽器中輸入一個地址時缺狠,例如www.baidu.com 其實不是百度網(wǎng)站真正意義上的地址∑继互聯(lián)網(wǎng)上每一臺計算機的唯一標識是它的IP地址挤茄,但是IP地址并不方便記憶。用戶更喜歡用方便記憶的網(wǎng)址去尋找互聯(lián)網(wǎng)上的其它計算機冰木,也就是上面提到的百度的網(wǎng)址穷劈。所以互聯(lián)網(wǎng)設(shè)計者需要在用戶的方便性與可用性方面做一個權(quán)衡,這個權(quán)衡就是一個網(wǎng)址到IP地址的轉(zhuǎn)換踊沸,這個過程就是DNS解析歇终。它實際上充當了一個翻譯的角色,實現(xiàn)了網(wǎng)址到IP地址的轉(zhuǎn)換逼龟。網(wǎng)址到IP地址轉(zhuǎn)換的過程是如何進行的?

解析過程

DNS解析是一個遞歸查詢的過程评凝。

上述圖片是查找www.google.com 的IP地址過程。首先在本地域名服務(wù)器中查詢IP地址腺律,如果沒有找到的情況下奕短,本地域名服務(wù)器會向根域名服務(wù)器發(fā)送一個請求,如果根域名服務(wù)器也不存在該域名時匀钧,本地域名會向com頂級域名服務(wù)器發(fā)送一個請求翎碑,依次類推下去。直到最后本地域名服務(wù)器得到google的IP地址并把它緩存到本地之斯,供下次查詢使用日杈。從上述過程中,可以看出網(wǎng)址的解析是一個從右向左的過程: com -> google.com -> www.google.com 但是你是否發(fā)現(xiàn)少了點什么,根域名服務(wù)器的解析過程呢莉擒?事實上酿炸,真正的網(wǎng)址是www.google.com. 并不是我多打了一個.,這個.對應(yīng)的就是根域名服務(wù)器涨冀,默認情況下所有的網(wǎng)址的最后一位都是.梁沧,既然是默認情況下,為了方便用戶蝇裤,通常都會省略,瀏覽器在請求DNS的時候會自動加上频鉴,所有網(wǎng)址真正的解析過程為: . -> .com -> google.com. -> www.google.com.栓辜。

DNS優(yōu)化

了解了DNS的過程,可以為我們帶來哪些垛孔?上文中請求到google的IP地址時藕甩,經(jīng)歷了8個步驟,這個過程中存在多個請求(同時存在UDP和TCP請求周荐,為什么有兩種請求方式狭莱,請自行查找)。如果每次都經(jīng)過這么多步驟概作,是否太耗時間腋妙?如何減少該過程的步驟呢?那就是DNS緩存讯榕。

DNS緩存

DNS存在著多級緩存骤素,從離瀏覽器的距離排序的話,有以下幾種: 瀏覽器緩存愚屁,系統(tǒng)緩存济竹,路由器緩存,IPS服務(wù)器緩存霎槐,根域名服務(wù)器緩存送浊,頂級域名服務(wù)器緩存,主域名服務(wù)器緩存丘跌。

在你的chrome瀏覽器中輸入 chrome://dns/袭景,你可以看到chrome瀏覽器的DNS緩存。
系統(tǒng)緩存主要存在/etc/hosts(Linux系統(tǒng))中

DNS負載均衡

不知道大家有沒有思考過一個問題: DNS返回的IP地址是否每次都一樣碍岔?如果每次都一樣是否說明你請求的資源都位于同一臺機器上面浴讯,那么這臺機器需要多高的性能和儲存才能滿足億萬請求呢?其實真實的互聯(lián)網(wǎng)世界背后存在成千上百臺服務(wù)器蔼啦,大型的網(wǎng)站甚至更多榆纽。但是在用戶的眼中,它需要的只是處理他的請求,哪臺機器處理請求并不重要奈籽。DNS可以返回一個合適的機器的IP給用戶饥侵,例如可以根據(jù)每臺機器的負載量,該機器離用戶地理位置的距離等等衣屏,這種過程就是DNS負載均衡躏升,又叫做DNS重定向。大家耳熟能詳?shù)腃DN(Content Delivery Network)就是利用DNS的重定向技術(shù)狼忱,DNS服務(wù)器會返回一個跟用戶最接近的點的IP地址給用戶膨疏,CDN節(jié)點的服務(wù)器負責響應(yīng)用戶的請求,提供所需的內(nèi)容钻弄。在這里打個免費的廣告佃却,我平時使用的比較多的是七牛云的CDN(免費)儲存圖片,作為我個人博客的圖床使用窘俺。


TCP連接

HTTP協(xié)議是使用TCP作為其傳輸層協(xié)議的饲帅,當TCP出現(xiàn)瓶頸時,HTTP也會受到影響瘤泪。但由于TCP優(yōu)化這一塊我平常接觸的并不是很多灶泵,再加上大學時的計算機網(wǎng)絡(luò)的基礎(chǔ)基本上忘完,所以這一部分我也就不在這里分析了对途。


HTTPS協(xié)議

我不知道把HTTPS放在這個部分是否合適赦邻,但是放在這里好像又說的過去。HTTP報文是包裹在TCP報文中發(fā)送的实檀,服務(wù)器端收到TCP報文時會解包提取出HTTP報文深纲。但是這個過程中存在一定的風險,HTTP報文是明文劲妙,如果中間被截取的話會存在一些信息泄露的風險湃鹊。那么在進入TCP報文之前對HTTP做一次加密就可以解決這個問題了。HTTPS協(xié)議的本質(zhì)就是HTTP + SSL(or TLS)镣奋。在HTTP報文進入TCP報文之前币呵,先使用SSL對HTTP報文進行加密。從網(wǎng)絡(luò)的層級結(jié)構(gòu)看它位于HTTP協(xié)議與TCP協(xié)議之間侨颈。

HTTPS過程

HTTPS在傳輸數(shù)據(jù)之前需要客戶端與服務(wù)器進行一個握手(TLS/SSL握手)余赢,在握手過程中將確立雙方加密傳輸數(shù)據(jù)的密碼信息。TLS/SSL使用了非對稱加密哈垢,對稱加密以及hash等妻柒。具體過程請參考經(jīng)典的阮一峰先生的博客TLS/SSL握手過程。
HTTPS相比于HTTP耘分,雖然提供了安全保證举塔,但是勢必會帶來一些時間上的損耗绑警,如握手和加密等過程,是否使用HTTPS需要根據(jù)具體情況在安全和性能方面做出權(quán)衡央渣。


HTTP請求

其實這部分又可以稱為前端工程師眼中的HTTP计盒,它主要發(fā)生在客戶端。發(fā)送HTTP請求的過程就是構(gòu)建HTTP請求報文并通過TCP協(xié)議中發(fā)送到服務(wù)器指定端口(HTTP協(xié)議80/8080, HTTPS協(xié)議443)芽丹。HTTP請求報文是由三部分組成: 請求行, 請求報頭和請求正文北启。

請求行

格式如下:
Method Request-URL HTTP-Version CRLF

eg: GET index.html HTTP/1.1
常用的方法有: GET, POST, PUT, DELETE, OPTIONS, HEAD。

請求報頭

請求報頭允許客戶端向服務(wù)器傳遞請求的附加信息和客戶端自身的信息拔第。
PS: 客戶端不一定特指瀏覽器咕村,有時候也可使用Linux下的CURL命令以及HTTP客戶端測試工具等。
常見的請求報頭有: Accept, Accept-Charset, Accept-Encoding, Accept-Language, Content-Type, Authorization, Cookie, User-Agent等蚊俺。

上圖是使用Chrome開發(fā)者工具截取的對百度的HTTP請求以及響應(yīng)報文培廓,從圖中可以看出,請求報頭中使用了Accept, Accept-Encoding, Accept-Language, Cache-Control, Connection, Cookie等字段春叫。Accept用于指定客戶端用于接受哪些類型的信息,Accept-Encoding與Accept類似泣港,它用于指定接受的編碼方式暂殖。Connection設(shè)置為Keep-alive用于告訴客戶端本次HTTP請求結(jié)束之后并不需要關(guān)閉TCP連接,這樣可以使下次HTTP請求使用相同的TCP通道当纱,節(jié)省TCP連接建立的時間呛每。

請求正文

當使用POST, PUT等方法時,通常需要客戶端向服務(wù)器傳遞數(shù)據(jù)坡氯。這些數(shù)據(jù)就儲存在請求正文中晨横。在請求包頭中有一些與請求正文相關(guān)的信息,例如: 現(xiàn)在的Web應(yīng)用通常采用Rest架構(gòu)箫柳,請求的數(shù)據(jù)格式一般為json手形。這時就需要設(shè)置Content-Type: application/json。


服務(wù)器處理請求并返回HTTP報文

自然而然這部分對應(yīng)的就是后端工程師眼中的HTTP悯恍。后端從在固定的端口接收到TCP報文開始库糠,這一部分對應(yīng)于編程語言中的socket。它會對TCP連接進行處理涮毫,對HTTP協(xié)議進行解析瞬欧,并按照報文格式進一步封裝成HTTP Request對象,供上層使用罢防。這一部分工作一般是由Web服務(wù)器去進行艘虎,我使用過的Web服務(wù)器有Tomcat, Jetty和Netty等等。

HTTP響應(yīng)報文也是由三部分組成: 狀態(tài)碼, 響應(yīng)報頭和響應(yīng)報文咒吐。

狀態(tài)碼

狀態(tài)碼是由3位數(shù)組成野建,第一個數(shù)字定義了響應(yīng)的類別属划,且有五種可能取值:

  • 1xx:指示信息–表示請求已接收,繼續(xù)處理贬墩。
  • 2xx:成功–表示請求已被成功接收榴嗅、理解、接受陶舞。
  • 3xx:重定向–要完成請求必須進行更進一步的操作嗽测。
  • 4xx:客戶端錯誤–請求有語法錯誤或請求無法實現(xiàn)。
  • 5xx:服務(wù)器端錯誤–服務(wù)器未能實現(xiàn)合法的請求肿孵。平時遇到比較常見的狀態(tài)碼有:200, 204, 301, 302, 304, 400, 401, 403, 404, 422, 500(分別表示什么請自行查找)唠粥。

響應(yīng)報頭

常見的響應(yīng)報頭字段有: Server, Connection...。

響應(yīng)報文

服務(wù)器返回給瀏覽器的文本信息停做,通常HTML, CSS, JS, 圖片等文件就放在這一部分晤愧。


瀏覽器解析渲染頁面

瀏覽器在收到HTML,CSS,JS文件后,它是如何把頁面呈現(xiàn)到屏幕上的蛉腌?下圖對應(yīng)的就是WebKit渲染的過程

瀏覽器是一個邊解析邊渲染的過程官份。首先瀏覽器解析HTML文件構(gòu)建DOM樹,然后解析CSS文件構(gòu)建渲染樹烙丛,等到渲染樹構(gòu)建完成后舅巷,瀏覽器開始布局渲染樹并將其繪制到屏幕上。這個過程比較復雜河咽,涉及到兩個概念: reflow(回流)和repain(重繪)钠右。DOM節(jié)點中的各個元素都是以盒模型的形式存在,這些都需要瀏覽器去計算其位置和大小等忘蟹,這個過程稱為relow;當盒模型的位置,大小以及其他屬性飒房,如顏色,字體,等確定下來之后,瀏覽器便開始繪制內(nèi)容媚值,這個過程稱為repain狠毯。頁面在首次加載時必然會經(jīng)歷reflow和repain。reflow和repain過程是非常消耗性能的褥芒,尤其是在移動設(shè)備上垃你,它會破壞用戶體驗,有時會造成頁面卡頓喂很。所以我們應(yīng)該盡可能少的減少reflow和repain惜颇。

JS的解析是由瀏覽器中的JS解析引擎完成的。JS是單線程運行少辣,也就是說凌摄,在同一個時間內(nèi)只能做一件事,所有的任務(wù)都需要排隊漓帅,前一個任務(wù)結(jié)束锨亏,后一個任務(wù)才能開始痴怨。但是又存在某些任務(wù)比較耗時,如IO讀寫等器予,所以需要一種機制可以先執(zhí)行排在后面的任務(wù)浪藻,這就是:同步任務(wù)(synchronous)和異步任務(wù)(asynchronous)。JS的執(zhí)行機制就可以看做是一個主線程加上一個任務(wù)隊列(task queue)乾翔。同步任務(wù)就是放在主線程上執(zhí)行的任務(wù)爱葵,異步任務(wù)是放在任務(wù)隊列中的任務(wù)。所有的同步任務(wù)在主線程上執(zhí)行反浓,形成一個執(zhí)行棧;異步任務(wù)有了運行結(jié)果就會在任務(wù)隊列中放置一個事件萌丈;腳本運行時先依次運行執(zhí)行棧,然后會從任務(wù)隊列里提取事件雷则,運行任務(wù)隊列中的任務(wù)辆雾,這個過程是不斷重復的,所以又叫做事件循環(huán)(Event loop)月劈。

瀏覽器在解析過程中度迂,如果遇到請求外部資源時,如圖像,iconfont,JS等猜揪。瀏覽器將重復1-6過程下載該資源惭墓。請求過程是異步的,并不會影響HTML文檔進行加載湿右,但是當文檔加載過程中遇到JS文件,HTML文檔會掛起渲染過程罚勾,不僅要等到文檔中JS文件加載完畢還要等待解析執(zhí)行完畢毅人,才會繼續(xù)HTML的渲染過程。原因是因為JS有可能修改DOM結(jié)構(gòu)尖殃,這就意味著JS執(zhí)行完成前丈莺,后續(xù)所有資源的下載是沒有必要的,這就是JS阻塞后續(xù)資源下載的根本原因送丰。CSS文件的加載不影響JS文件的加載缔俄,但是卻影響JS文件的執(zhí)行。JS代碼執(zhí)行前瀏覽器必須保證CSS文件已經(jīng)下載并加載完畢器躏。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末俐载,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子登失,更是在濱河造成了極大的恐慌遏佣,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,743評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件揽浙,死亡現(xiàn)場離奇詭異状婶,居然都是意外死亡意敛,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評論 3 385
  • 文/潘曉璐 我一進店門膛虫,熙熙樓的掌柜王于貴愁眉苦臉地迎上來草姻,“玉大人,你說我怎么就攤上這事稍刀×枚溃” “怎么了?”我有些...
    開封第一講書人閱讀 157,285評論 0 348
  • 文/不壞的土叔 我叫張陵掉丽,是天一觀的道長跌榔。 經(jīng)常有香客問我,道長捶障,這世上最難降的妖魔是什么僧须? 我笑而不...
    開封第一講書人閱讀 56,485評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮项炼,結(jié)果婚禮上担平,老公的妹妹穿的比我還像新娘。我一直安慰自己锭部,他們只是感情好暂论,可當我...
    茶點故事閱讀 65,581評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著拌禾,像睡著了一般取胎。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上湃窍,一...
    開封第一講書人閱讀 49,821評論 1 290
  • 那天闻蛀,我揣著相機與錄音,去河邊找鬼您市。 笑死觉痛,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的茵休。 我是一名探鬼主播薪棒,決...
    沈念sama閱讀 38,960評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼榕莺!你這毒婦竟也來了俐芯?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,719評論 0 266
  • 序言:老撾萬榮一對情侶失蹤钉鸯,失蹤者是張志新(化名)和其女友劉穎泼各,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體亏拉,經(jīng)...
    沈念sama閱讀 44,186評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡扣蜻,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,516評論 2 327
  • 正文 我和宋清朗相戀三年逆巍,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片莽使。...
    茶點故事閱讀 38,650評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡锐极,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出芳肌,到底是詐尸還是另有隱情灵再,我是刑警寧澤,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布亿笤,位于F島的核電站翎迁,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏净薛。R本人自食惡果不足惜汪榔,卻給世界環(huán)境...
    茶點故事閱讀 39,936評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望肃拜。 院中可真熱鬧痴腌,春花似錦、人聲如沸燃领。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,757評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽猛蔽。三九已至剥悟,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間曼库,已是汗流浹背区岗。 一陣腳步聲響...
    開封第一講書人閱讀 31,991評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留凉泄,地道東北人躏尉。 一個月前我還...
    沈念sama閱讀 46,370評論 2 360
  • 正文 我出身青樓蚯根,卻偏偏與公主長得像后众,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子颅拦,可洞房花燭夜當晚...
    茶點故事閱讀 43,527評論 2 349

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