從輸入url到頁面展示到底發(fā)生了什么

  1. 輸入地址
  2. 瀏覽器查找域名的 IP 地址
  3. 瀏覽器向 web 服務(wù)器發(fā)送一個 HTTP 請求
  4. 服務(wù)器的永久重定向響應(yīng)
  5. 瀏覽器跟蹤重定向地址
  6. 服務(wù)器處理請求
  7. 服務(wù)器返回一個 HTTP 響應(yīng)
  8. 覽器顯示 HTML
  9. 瀏覽器發(fā)送請求獲取嵌入在 HTML 中的資源(如圖片、音頻、視頻、CSS、JS等等)

總的過程大概如下:

1、輸入地址

當(dāng)我們開始在瀏覽器中輸入網(wǎng)址的時候,瀏覽器其實就已經(jīng)在智能的匹配可能得 url 了,他會從歷史記錄,書簽等地方,找到已經(jīng)輸入的字符串可能對應(yīng)的 url,然后給出智能提示,讓你可以補全url地址。對于 google的chrome 的瀏覽器,他甚至?xí)苯訌木彺嬷邪丫W(wǎng)頁展示出來,就是說,你還沒有按下 enter,頁面就出來了。

2、瀏覽器查找域名的 IP 地址

  1. 請求一旦發(fā)起,瀏覽器首先要做的事情就是解析這個域名,一般來說,瀏覽器會首先查看本地硬盤的 hosts 文件,看看其中有沒有和這個域名對應(yīng)的規(guī)則,如果有的話就直接使用 hosts 文件里面的 ip 地址。
  2. 如果在本地的 hosts 文件沒有能夠找到對應(yīng)的 ip 地址,瀏覽器會發(fā)出一個 DNS請求到本地DNS服務(wù)器 。本地DNS服務(wù)器一般都是你的網(wǎng)絡(luò)接入服務(wù)器商提供,比如中國電信,中國移動。
  3. 查詢你輸入的網(wǎng)址的DNS請求到達本地DNS服務(wù)器之后,本地DNS服務(wù)器會首先查詢它的緩存記錄,如果緩存中有此條記錄,就可以直接返回結(jié)果,此過程是遞歸的方式進行查詢。如果沒有,本地DNS服務(wù)器還要向DNS根服務(wù)器進行查詢。
  4. 根DNS服務(wù)器沒有記錄具體的域名和IP地址的對應(yīng)關(guān)系,而是告訴本地DNS服務(wù)器,你可以到域服務(wù)器上去繼續(xù)查詢,并給出域服務(wù)器的地址。這種過程是迭代的過程。
  5. 本地DNS服務(wù)器繼續(xù)向域服務(wù)器發(fā)出請求,在這個例子中,請求的對象是.com域服務(wù)器。.com域服務(wù)器收到請求之后,也不會直接返回域名和IP地址的對應(yīng)關(guān)系,而是告訴本地DNS服務(wù)器,你的域名的解析服務(wù)器的地址。
  6. 最后,本地DNS服務(wù)器向域名的解析服務(wù)器發(fā)出請求,這時就能收到一個域名和IP地址對應(yīng)關(guān)系,本地DNS服務(wù)器不僅要把IP地址返回給用戶電腦,還要把這個對應(yīng)關(guān)系保存在緩存中,以備下次別的用戶查詢時,可以直接返回結(jié)果,加快網(wǎng)絡(luò)訪問。
    下面這張圖很完美的解釋了這一過程:
1.jpeg

知識擴展:

1. 什么是DNS?

DNS(Domain Name System,域名系統(tǒng)),因特網(wǎng)上作為域名和IP地址相互映射的一個分布式數(shù)據(jù)庫,能夠使用戶更方便的訪問互聯(lián)網(wǎng),而不用去記住能夠被機器直接讀取的IP數(shù)串。通過主機名,最終得到該主機名對應(yīng)的IP地址的過程叫做域名解析(或主機名解析)。
通俗的講,我們更習(xí)慣于記住一個網(wǎng)站的名字,比如www.baidu.com,而不是記住它的ip地址,比如:167.23.10.2。而計算機更擅長記住網(wǎng)站的ip地址,而不是像www.baidu.com等鏈接。因為,DNS就相當(dāng)于一個電話本,比如你要找www.baidu.com這個域名,那我翻一翻我的電話本,我就知道,哦,它的電話(ip)是167.23.10.2。

2. DNS查詢的兩種方式:遞歸查詢和迭代查詢

1、遞歸解析
當(dāng)局部DNS服務(wù)器自己不能回答客戶機的DNS查詢時,它就需要向其他DNS服務(wù)器進行查詢。此時有兩種方式,如圖所示的是遞歸方式。局部DNS服務(wù)器自己負責(zé)向其他DNS服務(wù)器進行查詢,一般是先向該域名的根域服務(wù)器查詢,再由根域名服務(wù)器一級級向下查詢。最后得到的查詢結(jié)果返回給局部DNS服務(wù)器,再由局部DNS服務(wù)器返回給客戶端。

2.png

2、迭代解析
當(dāng)局部DNS服務(wù)器自己不能回答客戶機的DNS查詢時,也可以通過迭代查詢的方式進行解析,如圖所示。局部DNS服務(wù)器不是自己向其他DNS服務(wù)器進行查詢,而是把能解析該域名的其他DNS服務(wù)器的IP地址返回給客戶端DNS程序,客戶端DNS程序再繼續(xù)向這些DNS服務(wù)器進行查詢,直到得到查詢結(jié)果為止。也就是說,迭代解析只是幫你找到相關(guān)的服務(wù)器而已,而不會幫你去查。比如說:baidu.com的服務(wù)器ip地址在192.168.4.5這里,你自己去查吧,本人比較忙,只能幫你到這里了。

3.jpeg

3)DNS域名稱空間的組織方式
我們在前面有說到根DNS服務(wù)器,域DNS服務(wù)器,這些都是DNS域名稱空間的組織方式。按其功能命名空間中用來描述 DNS 域名稱的五個類別的介紹詳見下表中,以及與每個名稱類型的示例

4.jpeg
3. DNS負載均衡

當(dāng)一個網(wǎng)站有足夠多的用戶的時候,假如每次請求的資源都位于同一臺機器上面,那么這臺機器隨時可能會蹦掉。處理辦法就是用DNS負載均衡技術(shù),它的原理是在DNS服務(wù)器中為同一個主機名配置多個IP地址,在應(yīng)答DNS查詢時,DNS服務(wù)器對每個查詢將以DNS文件中主機記錄的IP地址按順序返回不同的解析結(jié)果,將客戶端的訪問引導(dǎo)到不同的機器上去,使得不同的客戶端訪問不同的服務(wù)器,從而達到負載均衡的目的?例如可以根據(jù)每臺機器的負載量,該機器離用戶地理位置的距離等等。

3. 瀏覽器向 web 服務(wù)器發(fā)送一個 HTTP 請求

拿到域名對應(yīng)的IP地址之后,瀏覽器會以一個隨機端口(1024<端口<65535)向服務(wù)器的WEB程序(常用的有httpd,nginx等)80端口發(fā)起TCP的連接請求。這個連接請求到達服務(wù)器端后(這中間通過各種路由設(shè)備,局域網(wǎng)內(nèi)除外),進入到網(wǎng)卡,然后是進入到內(nèi)核的TCP/IP協(xié)議棧(用于識別該連接請求,解封包,一層一層的剝開),還有可能要經(jīng)過Netfilter防火墻(屬于內(nèi)核的模塊)的過濾,最終到達WEB程序,最終建立了TCP/IP的連接。
TCP連接如圖所示:

5.jpeg

建立了TCP連接之后,發(fā)起一個http請求。一個典型的 http request header 一般需要包括請求的方法,例如 GET 或者 POST 等,不常用的還有 PUT 和 DELETE 、HEAD、OPTION以及 TRACE 方法,一般的瀏覽器只能發(fā)起 GET 或者 POST 請求。
客戶端向服務(wù)器發(fā)起http請求的時候,會有一些請求信息,請求信息包含三個部分:
| 請求方法URI協(xié)議/版本
| 請求頭(Request Header)
| 請求正文:
下面是一個完整的HTTP請求例子:

GET/sample.jspHTTP/1.1   
Accept:image/gif.image/jpeg,*/*   Accept-Language:zh-cn   
Connection:Keep-Alive   
Host:localhost   
User-Agent:Mozila/4.0(compatible;MSIE5.01;Window NT5.0)   
Accept-Encoding:gzip,deflate   

username=jinqiao&password=1234

注意:最后一個請求頭之后是一個空行,發(fā)送回車符和換行符,通知服務(wù)器以下不再有請求頭。
(1)請求的第一行是“方法URL議/版本”:GET/sample.jsp HTTP/1.1
(2)請求頭(Request Header)

請求頭包含許多有關(guān)的客戶端環(huán)境和請求正文的有用信息。例如,請求頭可以聲明瀏覽器所用的語言,請求正文的長度等。

Accept:image/gif.image/jpeg.*/*  
 Accept-Language:zh-cn   
Connection:Keep-Alive  
Host:localhost   
User-Agent:Mozila/4.0(compatible:MSIE5.01:Windows NT5.0)  
Accept-Encoding:gzip,deflate.

(3)請求正文

請求頭和請求正文之間是一個空行,這個行非常重要,它表示請求頭已經(jīng)結(jié)束,接下來的是請求正文。請求正文中可以包含客戶提交的查詢字符串信息:
username=jinqiao&password=1234

知識擴展:

1. TCP三次握手

第一次握手:客戶端A將標(biāo)志位SYN置為1,隨機產(chǎn)生一個值為seq=J(J的取值范圍為=1234567)的數(shù)據(jù)包到服務(wù)器,客戶端A進入SYN_SENT狀態(tài),等待服務(wù)端B確認;
第二次握手:服務(wù)端B收到數(shù)據(jù)包后由標(biāo)志位SYN=1知道客戶端A請求建立連接,服務(wù)端B將標(biāo)志位SYN和ACK都置為1,ack=J+1,隨機產(chǎn)生一個值seq=K,并將該數(shù)據(jù)包發(fā)送給客戶端A以確認連接請求,服務(wù)端B進入SYN_RCVD狀態(tài)。
第三次握手:客戶端A收到確認后,檢查ack是否為J+1,ACK是否為1,如果正確則將標(biāo)志位ACK置為1,ack=K+1,并將該數(shù)據(jù)包發(fā)送給服務(wù)端B,服務(wù)端B檢查ack是否為K+1,ACK是否為1,如果正確則連接建立成功,客戶端A和服務(wù)端B進入ESTABLISHED狀態(tài),完成三次握手,隨后客戶端A與服務(wù)端B之間可以開始傳輸數(shù)據(jù)了。
如圖所示:

7.png
2. 為什需要三次握手?

《計算機網(wǎng)絡(luò)》第四版中講“三次握手”的目的是“為了防止已失效的連接請求報文段突然又傳送到了服務(wù)端,因而產(chǎn)生錯誤”
書中的例子是這樣的,“已失效的連接請求報文段”的產(chǎn)生在這樣一種情況下:client發(fā)出的第一個連接請求報文段并沒有丟失,而是在某個網(wǎng)絡(luò)結(jié)點長時間的滯留了,以致延誤到連接釋放以后的某個時間才到達server。本來這是一個早已失效的報文段。但server收到此失效的連接請求報文段后,就誤認為是client再次發(fā)出的一個新的連接請求。于是就向client發(fā)出確認報文段,同意建立連接
假設(shè)不采用“三次握手”,那么只要server發(fā)出確認,新的連接就建立了。由于現(xiàn)在client并沒有發(fā)出建立連接的請求,因此不會理睬server的確認,也不會向server發(fā)送數(shù)據(jù)。但server卻以為新的運輸連接已經(jīng)建立,并一直等待client發(fā)來數(shù)據(jù)。這樣,server的很多資源就白白浪費掉了。采用“三次握手”的辦法可以防止上述現(xiàn)象發(fā)生。例如剛才那種情況,client不會向server的確認發(fā)出確認。server由于收不到確認,就知道client并沒有要求建立連接。”。主要目的防止server端一直等待,浪費資源。

3. TCP四次揮手

第一次揮手:Client發(fā)送一個FIN,用來關(guān)閉Client到Server的數(shù)據(jù)傳送,Client進入FIN_WAIT_1狀態(tài)。

第二次揮手:Server收到FIN后,發(fā)送一個ACK給Client,確認序號為收到序號+1(與SYN相同,一個FIN占用一個序號),Server進入CLOSE_WAIT狀態(tài)。

第三次揮手:Server發(fā)送一個FIN,用來關(guān)閉Server到Client的數(shù)據(jù)傳送,Server進入LAST_ACK狀態(tài)。

第四次揮手:Client收到FIN后,Client進入TIME_WAIT狀態(tài),接著發(fā)送一個ACK給Server,確認序號為收到序號+1,Server進入CLOSED狀態(tài),完成四次揮手。

8.png
4. 為什么建立連接是三次握手,而關(guān)閉連接卻是四次揮手呢?

這是因為服務(wù)端在LISTEN狀態(tài)下,收到建立連接請求的SYN報文后,把ACK和SYN放在一個報文里發(fā)送給客戶端。而關(guān)閉連接時,當(dāng)收到對方的FIN報文時,僅僅表示對方不再發(fā)送數(shù)據(jù)了但是還能接收數(shù)據(jù),己方也未必全部數(shù)據(jù)都發(fā)送給對方了,所以己方可以立即close,也可以發(fā)送一些數(shù)據(jù)給對方后,再發(fā)送FIN報文給對方來表示同意現(xiàn)在關(guān)閉連接,因此,己方ACK和FIN一般都會分開發(fā)送。

4. 服務(wù)器的永久重定向響應(yīng)

服務(wù)器給瀏覽器響應(yīng)一個301永久重定向響應(yīng),這樣瀏覽器就會訪問“http://www.google.com/” 而非“http://google.com/”。
為什么服務(wù)器一定要重定向而不是直接發(fā)送用戶想看的網(wǎng)頁內(nèi)容呢?其中一個原因跟搜索引擎排名有關(guān)。如果一個頁面有兩個地址,就像http://www.yy.com/http://yy.com/,搜索引擎會認為它們是兩個網(wǎng)站,結(jié)果造成每個搜索鏈接都減少從而降低排名。而搜索引擎知道301永久重定向是什么意思,這樣就會把訪問帶www的和不帶www的地址歸到同一個網(wǎng)站排名下。還有就是用不同的地址會造成緩存友好性變差,當(dāng)一個頁面有好幾個名字時,它可能會在緩存里出現(xiàn)好幾次。

擴展知識

1)301和302的區(qū)別。
301和302狀態(tài)碼都表示重定向,就是說瀏覽器在拿到服務(wù)器返回的這個狀態(tài)碼后會自動跳轉(zhuǎn)到一個新的URL地址,這個地址可以從響應(yīng)的Location首部中獲取(用戶看到的效果就是他輸入的地址A瞬間變成了另一個地址B)——這是它們的共同點。
他們的不同在于。301表示舊地址A的資源已經(jīng)被永久地移除了(這個資源不可訪問了),搜索引擎在抓取新內(nèi)容的同時也將舊的網(wǎng)址交換為重定向之后的網(wǎng)址;
302表示舊地址A的資源還在(仍然可以訪問),這個重定向只是臨時地從舊地址A跳轉(zhuǎn)到地址B,搜索引擎會抓取新的內(nèi)容而保存舊的網(wǎng)址。 SEO302好于301

2)重定向原因:
(1)網(wǎng)站調(diào)整(如改變網(wǎng)頁目錄結(jié)構(gòu));
(2)網(wǎng)頁被移到一個新地址;
(3)網(wǎng)頁擴展名改變(如應(yīng)用需要把.php改成.Html或.shtml)。

這種情況下,如果不做重定向,則用戶收藏夾或搜索引擎數(shù)據(jù)庫中舊地址只能讓訪問客戶得到一個404頁面錯誤信息,訪問流量白白喪失;再者某些注冊了多個域名的網(wǎng)站,也需要通過重定向讓訪問這些域名的用戶自動跳轉(zhuǎn)到主站點等。

3)什么時候進行301或者302跳轉(zhuǎn)呢?
當(dāng)一個網(wǎng)站或者網(wǎng)頁24—48小時內(nèi)臨時移動到一個新的位置,這時候就要進行302跳轉(zhuǎn),而使用301跳轉(zhuǎn)的場景就是之前的網(wǎng)站因為某種原因需要移除掉,然后要到新的地址訪問,是永久性的。
清晰明確而言:使用301跳轉(zhuǎn)的大概場景如下:
1、域名到期不想續(xù)費(或者發(fā)現(xiàn)了更適合網(wǎng)站的域名),想換個域名。
2、在搜索引擎的搜索結(jié)果中出現(xiàn)了不帶www的域名,而帶www的域名卻沒有收錄,這個時候可以用301重定向來告訴搜索引擎我們目標(biāo)的域名是哪一個。
3、空間服務(wù)器不穩(wěn)定,換空間的時候。
5、瀏覽器跟蹤重定向地址
現(xiàn)在瀏覽器知道了 "http://www.google.com/"才是要訪問的正確地址,所以它會發(fā)送另一個http請求。這里沒有啥好說的
6、服務(wù)器處理請求
經(jīng)過前面的重重步驟,我們終于將我們的http請求發(fā)送到了服務(wù)器這里,其實前面的重定向已經(jīng)是到達服務(wù)器了,那么,服務(wù)器是如何處理我們的請求的呢?
后端從在固定的端口接收到TCP報文開始,它會對TCP連接進行處理,對HTTP協(xié)議進行解析,并按照報文格式進一步封裝成HTTP Request對象,供上層使用。
一些大一點的網(wǎng)站會將你的請求到反向代理服務(wù)器中,因為當(dāng)網(wǎng)站訪問量非常大,網(wǎng)站越來越慢,一臺服務(wù)器已經(jīng)不夠用了。于是將同一個應(yīng)用部署在多臺服務(wù)器上,將大量用戶的請求分配給多臺機器處理。此時,客戶端不是直接通過HTTP協(xié)議訪問某網(wǎng)站應(yīng)用服務(wù)器,而是先請求到Nginx,Nginx再請求應(yīng)用服務(wù)器,然后將結(jié)果返回給客戶端,這里Nginx的作用是反向代理服務(wù)器。同時也帶來了一個好處,其中一臺服務(wù)器萬一掛了,只要還有其他服務(wù)器正常運行,就不會影響用戶使用。
如圖所示:

9.jpeg

通過Nginx的反向代理,我們到達了web服務(wù)器,服務(wù)端腳本處理我們的請求,訪問我們的數(shù)據(jù)庫,獲取需要獲取的內(nèi)容等等,當(dāng)然,這個過程涉及很多后端腳本的復(fù)雜操作。由于對這一塊不熟,所以這一塊只能介紹這么多了。

擴展閱讀:

1)什么是反向代理?
客戶端本來可以直接通過HTTP協(xié)議訪問某網(wǎng)站應(yīng)用服務(wù)器,網(wǎng)站管理員可以在中間加上一個Nginx,客戶端請求Nginx,Nginx請求應(yīng)用服務(wù)器,然后將結(jié)果返回給客戶端,此時Nginx就是反向代理服務(wù)器。

10.jpeg

7、服務(wù)器返回一個 HTTP 響應(yīng) 
經(jīng)過前面的6個步驟,服務(wù)器收到了我們的請求,也處理我們的請求,到這一步,它會把它的處理結(jié)果返回,也就是返回一個HTPP響應(yīng)。
HTTP響應(yīng)與HTTP請求相似,HTTP響應(yīng)也由3個部分構(gòu)成,分別是:
l 狀態(tài)行
l 響應(yīng)頭(Response Header)
l 響應(yīng)正文

HTTP/1.1 200 OK   
Date: Sat, 31 Dec 2005 23:59:59 GMT   
Content-Type: text/html;charset=ISO-8859-1   
Content-Length: 122   
<html>   <head>   <title>http</title>   </head>   <body>   <!-- body goes here -->   </body>   </html>
狀態(tài)行:

狀態(tài)行由協(xié)議版本、數(shù)字形式的狀態(tài)代碼、及相應(yīng)的狀態(tài)描述,各元素之間以空格分隔。
格式: HTTP-Version Status-Code Reason-Phrase CRLF
例如: HTTP/1.1 200 OK \r\n
-- 協(xié)議版本:是用http1.0還是其他版本
-- 狀態(tài)描述:狀態(tài)描述給出了關(guān)于狀態(tài)代碼的簡短的文字描述。比如狀態(tài)代碼為200時的描述為 ok
-- 狀態(tài)代碼:狀態(tài)代碼由三位數(shù)字組成,第一個數(shù)字定義了響應(yīng)的類別,且有五種可能取值。如下

1xx:信息性狀態(tài)碼,表示服務(wù)器已接收了客戶端請求,客戶端可繼續(xù)發(fā)送請求。
100 Continue
101 Switching Protocols
2xx:成功狀態(tài)碼,表示服務(wù)器已成功接收到請求并進行處理。200 OK 表示客戶端請求成功
204 No Content 成功,但不返回任何實體的主體部分
206 Partial Content 成功執(zhí)行了一個范圍(Range)請求
3xx:重定向狀態(tài)碼,表示服務(wù)器要求客戶端重定向。
301 Moved Permanently 永久性重定向,響應(yīng)報文的Location首部應(yīng)該有該資源的新URL
302 Found 臨時性重定向,響應(yīng)報文的Location首部給出的URL用來臨時定位資源
303 See Other 請求的資源存在著另一個URI,客戶端應(yīng)使用GET方法定向獲取請求的資源
304 Not Modified 服務(wù)器內(nèi)容沒有更新,可以直接讀取瀏覽器緩存
307 Temporary Redirect 臨時重定向。與302 Found含義一樣。302禁止POST變換為GET,但實際使用時并不一定,307則更多瀏覽器可能會遵循這一標(biāo)準(zhǔn),但也依賴于瀏覽器具體實現(xiàn)
4xx:客戶端錯誤狀態(tài)碼,表示客戶端的請求有非法內(nèi)容。
400 Bad Request 表示客戶端請求有語法錯誤,不能被服務(wù)器所理解
401 Unauthonzed 表示請求未經(jīng)授權(quán),該狀態(tài)代碼必須與 WWW-Authenticate 報頭域一起使用
403 Forbidden 表示服務(wù)器收到請求,但是拒絕提供服務(wù),通常會在響應(yīng)正文中給出不提供服務(wù)的原因
404 Not Found 請求的資源不存在,例如,輸入了錯誤的URL
5xx:服務(wù)器錯誤狀態(tài)碼,表示服務(wù)器未能正常處理客戶端的請求而出現(xiàn)意外錯誤。
500 Internel Server Error 表示服務(wù)器發(fā)生不可預(yù)期的錯誤,導(dǎo)致無法完成客戶端的請求
503 Service Unavailable 表示服務(wù)器當(dāng)前不能夠處理客戶端的請求,在一段時間之后,服務(wù)器可能會恢復(fù)正常

響應(yīng)頭:

響應(yīng)頭部:由關(guān)鍵字/值對組成,每行一對,關(guān)鍵字和值用英文冒號":"分隔,典型的響應(yīng)頭有:

11.jpeg

響應(yīng)正文
包含著我們需要的一些具體信息,比如cookie,html,image,后端返回的請求數(shù)據(jù)等等。這里需要注意,響應(yīng)正文和響應(yīng)頭之間有一行空格,表示響應(yīng)頭的信息到空格為止,下圖是fiddler抓到的請求正文,紅色框中的:響應(yīng)正文:

12.png
8. 瀏覽器顯示 HTML

在瀏覽器沒有完整接受全部HTML文檔時,它就已經(jīng)開始顯示這個頁面了,瀏覽器是如何把頁面呈現(xiàn)在屏幕上的呢?不同瀏覽器可能解析的過程不太一樣,這里我們只介紹webkit的渲染過程,下圖對應(yīng)的就是WebKit渲染的過程,這個過程包括:

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

13.jpeg

瀏覽器在解析html文件時,會”自上而下“加載,并在加載過程中進行解析渲染。在解析過程中,如果遇到請求外部資源時,如圖片、外鏈的CSS、iconfont等,請求過程是異步的,并不會影響html文檔進行加載。

解析過程中,瀏覽器首先會解析HTML文件構(gòu)建DOM樹,然后解析CSS文件構(gòu)建渲染樹,等到渲染樹構(gòu)建完成后,瀏覽器開始布局渲染樹并將其繪制到屏幕上。這個過程比較復(fù)雜,涉及到兩個概念: reflow(回流)和repain(重繪)。

DOM節(jié)點中的各個元素都是以盒模型的形式存在,這些都需要瀏覽器去計算其位置和大小等,這個過程稱為relow;當(dāng)盒模型的位置,大小以及其他屬性,如顏色,字體,等確定下來之后,瀏覽器便開始繪制內(nèi)容,這個過程稱為repain。

頁面在首次加載時必然會經(jīng)歷reflow和repain。reflow和repain過程是非常消耗性能的,尤其是在移動設(shè)備上,它會破壞用戶體驗,有時會造成頁面卡頓。所以我們應(yīng)該盡可能少的減少reflow和repain。

14.png

當(dāng)文檔加載過程中遇到j(luò)s文件,html文檔會掛起渲染(加載解析渲染同步)的線程,不僅要等待文檔中js文件加載完畢,還要等待解析執(zhí)行完畢,才可以恢復(fù)html文檔的渲染線程。因為JS有可能會修改DOM,最為經(jīng)典的document.write,這意味著,在JS執(zhí)行完成前,后續(xù)所有資源的下載可能是沒有必要的,這是js阻塞后續(xù)資源下載的根本原因。所以我明平時的代碼中,js是放在html文檔末尾的。

JS的解析是由瀏覽器中的JS解析引擎完成的,比如谷歌的是V8。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ù),這個過程是不斷重復(fù)的,所以又叫做事件循環(huán)(Event loop)。

9、瀏覽器發(fā)送請求獲取嵌入在 HTML 中的資源(如圖片、音頻、視頻、CSS、JS等等)
其實這個步驟可以并列在步驟8中,在瀏覽器顯示HTML時,它會注意到需要獲取其他地址內(nèi)容的標(biāo)簽。這時,瀏覽器會發(fā)送一個獲取請求來重新獲得這些文件。比如我要獲取外圖片,CSS,JS文件等,類似于下面的鏈接:

圖片:http://static.ak.fbcdn.net/rsrc.php/z12E0/hash/8q2anwu7.gif
CSS式樣表:http://static.ak.fbcdn.net/rsrc.php/z448Z/hash/2plh8s4n.css
JavaScript 文件:http://static.ak.fbcdn.net/rsrc.php/zEMOA/hash/c8yzb6ub.js

這些地址都要經(jīng)歷一個和HTML讀取類似的過程。所以瀏覽器會在DNS中查找這些域名,發(fā)送請求,重定向等等...

不像動態(tài)頁面,靜態(tài)文件會允許瀏覽器對其進行緩存。有的文件可能會不需要與服務(wù)器通訊,而從緩存中直接讀取,或者可以放到CDN中。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,546評論 6 533
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,570評論 3 418
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,505評論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,017評論 1 313
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 71,786評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,219評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,287評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,438評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,971評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 40,796評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,995評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,540評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,230評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,662評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,918評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,697評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 47,991評論 2 374

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