博客原文地址:Claiyre的我的博客 https://claiyre.github.io
如需轉載,請在文章開頭註明原文地址css
衡量一個網站的性能有多個指標,DNS解析時間,TCP連接時間,HTTP重定向時間,等待服務器響應時間等等,從用戶角度來看,就能夠歸結爲該網站訪問速度的快慢。也就是說性能等於網站的訪問速度。
早些年Amazon曾經作過一個統計:網頁加載時間每延長1秒鐘,一年將減小16億美圓的營收。(16億美圓是一個什麼概念呢?2015年,百度整年的總營收約100億美圓!)。
鑑於性能的重要性,因而咱們便常常看到許多記錄提高訪問速度的方法的文章:減小http請求,雪碧圖,壓縮文件等等,看了這些文章後,博主瞭解了一些比較廣泛的提高性能的方法,可是還不明白爲啥這樣能提高速度呀!
做爲一名有志青年,博主認爲,不只要知其然,還要知其因此然。在查閱大量書籍和博文後,終於明白了其中的玄機,特此記錄下來,與你們分享。html
接下來,咱們首先來深刻理解一個瀏覽器與互聯網的通訊過程,而後分析每一個過程所佔時間的多少,以及哪些過程的時間是能夠減小的,再說明經過怎樣的方法能夠減小這些時間,以此來縮小網站總的加載時間,提高網站的訪問速度。git
互聯網內各網絡設備間的通訊都遵循TCP/IP協議,利用TCP/IP協議族進行網絡通訊時,會經過分層順序與對方進行通訊。分層由高到低分別爲:應用層、傳輸層、網絡層、數據鏈路層。發送端從應用層往下走,接收端從數據鏈路層網上走。如圖所示:github
在瀏覽器中輸入url
用戶輸入url,如https://www.zhihu.com。其中https是協議,//後面的是網絡地址,網絡地址指出了請求的資源在哪一個計算機上。網絡地址能夠是IP地址,也能夠是域名,這裏是域名,域名更方便記憶web
瀏覽器查詢緩存
若是存在有效的緩存,則跳至第11步的渲染階段。chrome
應用層DNS解析域名
域名是爲了方便人類記憶,但計算機不能很好的處理域名,由於IP地址的長度是固定的32位(IPv6是128位),而域名的長度不固定,機器處理起來比較困難,所以須要有一個輔助系統提供域名到IP地址的映射,這個輔助系統就是DNS(Domain Name System)。 在收到一個域名後,客戶端會先檢查本地是否有對應的IP地址,若找到則返回響應的IP地址。若沒找到則請求上級DNS服務器,直至找到根域。最終獲得域名對應的IP地址,存在負載均衡時同一域名返回IP可能不一樣,因此IP地址纔是是計算機在網絡中的惟一標識。segmentfault
應用層發送http請求
http協議是用於客戶端與服務器端通訊的一種協議,它是經過請求和響應這種方式來實現通訊的。HTTP請求包括請求報頭和請求主體兩個部分,其中請求報頭包含了相當重要的信息,好比請求的方法(GET,POST,PUT,DELETE,CONNECT...)、目標url、遵循的協議(http / https / ftp…),以及客戶端是否發送cookie等。windows
SSL/TLS安全傳輸協議
它是位於傳輸層之上的一個安全套接層也就是https中的's',確保了(1)全部信息都是加密傳播的,第三方沒法竊聽(2)具備校驗機制,一旦被篡改,通訊雙方會馬上發現(3)配備身份證書,防止身份被發現。瀏覽器
爲網絡通訊提供安全保障。緩存
傳輸層用TCP協議傳輸報文
位於傳輸層的TCP協議爲傳輸報文提供可靠的字節流服務。它爲了方便傳輸,將大塊的數據分割成以報文段爲單位的數據包,併爲他們編號,方便服務器接收時能正確的快速還原報文信息。TCP協議經過三次握手來創建鏈接,經過四次揮手斷開鏈接,保證了傳輸的安全可靠,下面的兩張圖和那後地解釋了三次握手和四次揮手。
(圖片來源於http://www.cnblogs.com/zmlctt...)
網絡層IP協議查詢MAC地址
IP協議的做用是把TCP分割好的各類數據包傳送給接收方,這時就須要接收方的MAC 地址,也就是物理地址。IP地址和MAC地址是一一對應的關係,一個網絡設備的IP地址能夠更換,可是MAC地址通常是固定不變的。ARP協議能夠將IP地址解析成對應的MAC地址。當通訊的雙方不在同一個局域網時,須要屢次中轉才能到達最終的目標,在中轉的過程當中須要經過下一個中轉站的MAC地址來搜索下一個中轉目標,路由提供這種中轉服務。
數據到達數據鏈路層被處理包裝
在找到對方的MAC地址後,就將數據發送到數據鏈路層,數據鏈路層負責三件事:封裝成幀,透明傳輸,差錯檢測。
物理層傳輸到達服務器端
數據進入物理層到達服務器後,再經歷3-7的相反操做:在鏈路層接收到數據包,再層層向上直到應用層。這過程當中包括在運輸層經過TCP協議將分段的數據包從新組成原來的HTTP請求報文。
服務器響應
服務接收到客戶端發送的HTTP請求後,查找客戶端請求的資源,並返回響應報文,響應報文中包括一個重要的信息——狀態碼。狀態碼由三位數字組成,其中比較常見的是200 OK表示請求成功。301表示永久重定向,即請求的資源已經永久轉移到新的位置。在返回301狀態碼的同時,響應報文也會附帶重定向的url,客戶端接收到後將http請求的url作相應的改變再從新發送。
客戶端接收響應並渲染頁面
服務器的響應到達客戶端後,瀏覽器會根據接收到的數據渲染頁面。渲染階段也有許多改善性能的方案,本文的重點不在這裏,下次在另外一篇文章裏細說。
以上就是網絡通訊的整個過程,深究起來極其複雜,用到的協議也是很是多,不得不禁衷地佩服先人的智慧!
chrome瀏覽器下按F12打開開發者工具,找到第四欄的network,在瀏覽器上方地址欄輸入一個本身從未訪問過的url,目的是保證請求的內容沒被緩存在本地(爲此,博主還清理了一波瀏覽器緩存(;′⌒`),傷心)。
總體大概是這樣:
找一個有表明性的請求,如上圖紅色框所示,將鼠標放在黃色箭頭所指的地方,會浮現該請求timeline的詳情,以下圖所示
這張詳情圖中可謂是藏了很多有價值的信息呢( •̀ ω •́ )✧,注意看咯!
Resource scheduling(紅色圈圈3)
第一部分首先是資源調度的時間。
紅色圈圈告訴咱們Queued at 214.06ms,在214.06 ms 時開始排隊。排了0.57ms後(圈圈4),就Started at 214.63ms(圈圈2),也就是說資源調度結束後就開始處理該指令了。
據chrome官方解釋,致使Queueing的緣由有如下幾種:
請求已被渲染引擎推遲,由於該請求的優先級被視爲低於關鍵資源(例如腳本/樣式)的優先級。 圖像常常發生這種狀況。
請求已被暫停,以等待將要釋放的不可用 TCP 套接字。
請求已被暫停,由於在 HTTP 1 上,瀏覽器僅容許每一個源擁有六個 TCP 鏈接。
生成磁盤緩存條目所用的時間(一般很是迅速)
Connection Start(圈圈5)
資源調度後就要開始創建連接了。
圈圈6 Stalled表明 請求等待發送所用的時間,此時間包含第一部分中的第二步:查看瀏覽器緩存所用的時間,下圖是刷新後一個「from disk cache」文件的詳情圖,能夠很好地證實這一點。
圈圈7 Proxy negotiation 表明與代理服務器協商的時間
圈圈8 DNS Lookup 執行 DNS 查詢所用的時間。 頁面上的每個新域都須要完整的往返才能執行 DNS 查詢。對應於第一部分中的「應用層DNS解析域名」時間
圈圈9 Initial Connection 初始化鏈接所用的時間,包括 TCP 握手/重試和協商 SSL 的時間。對應於第一部分的6和7
圈圈10 SSL 完成SSL握手所須要的時間,對應於第一部分的5
機智的你是否是已經發現創建連接的時間恰好對應於第一部分中的3-
Request/Response
通訊連接創建後,就能夠發送請求了,服務器處理後返回響應,客戶端再根據響應內容下一步處理
圈圈11 Request sent 發送請求的時間,這個是很是快的
圈圈12 Waiting(TTFB)等待服務器初始響應所用的時間,也稱爲至第一字節的時間。 此時間將捕捉到服務器往返的延遲時間,以及等待服務器傳送響應所用的時間。
最後是 Content Download,接受(下載)響應數據所須要的時間。
能夠發現,詳情圖中的時間順序和第一張網絡模型示意圖恰好一一對應,只有TCP/IP鏈接創建完成後,才能再創建SSL/TLS,最後纔可用http協議請求/響應。
到這裏,想必你已經明白了一次完整的請求須要經歷的步驟和耗費的時間,那麼這些時間中有哪些是能夠人爲減小的呢?咱們能夠經過怎樣的方式來減小這些時間來提升性能呢?
看下面
減小http的請求數下降connection的時間
由上面的詳情圖能夠看到,若是本地沒有緩存時,許多時間都花在了第二步Connection Start 創建連接上,只有少部分花在了Content Download上。那好,如今若是咱們把兩個文件合併成一個,就能夠用一次請求代替以前的兩次請求,理論上是否是就節約了一次Connection的時間了?合併的文件越多,節約的時間就越多。
因此咱們能夠把圖片,css,js等一些能夠合併的文件儘可能合併來減小http的請求數,下降總的connection的時間。
細心的朋友可能會發現,有的請求是幾乎沒有connection的時間的,它們的詳情圖長這樣:
查看request header發現其中有一個這樣的鍵值對:
對,就是由於它,http的keep-alive能夠在必定的時間內保證鏈接的可複用性,減小鏈接時間,但它的期限是有限的,能夠看到network下的請求中仍是有若干次請求是有connection的時間的,因此合併文件仍是必須的。
壓縮文件下降content download的時間
上圖中content download的時間不算多,只有20.47ms ,但它仍是能夠被減小的呀,若是咱們壓縮了該文件,在相同物理環境下,它會變得更少呀!能減小一點是一點嘛。
並且在一些項目中,部分文件可達幾百kb,這時content download的時間就不止20ms了,因此壓縮後仍是能減小很多時間的。
因此項目上線前,像一些圖片啦,css,js啦,能壓縮的仍是儘可能壓縮。
使用瀏覽器緩存
把網站裏面更新頻率比較低的靜態資源緩存在瀏覽器中,可以很好地提高速度。事實證實的確如此,( •̀ ω •́ )✧
畢竟對於幾百K的文件硬盤仍是能夠秒讀的嘛。
經過設置 http 頭裏的 Cache-Control 和 Expires 屬性來設定瀏覽器緩存時間,另外還有 Etags 和 opcode 的緩存,根據具體狀況進行選擇吧
減小DNS查找
DNS用於映射主機名和IP地址,通常一次解析須要20~120毫秒。瀏覽器會首先根據頁面的主機名進行域名解析,在有ISP返回結果以前頁面不會加載任何內容,因此減小DNS查找能夠有效下降等待時間。爲達到更高的性能,DNS解析一般被多級別地緩存,如由ISP或局域網維護的caching server,本地機器操做系統的緩存(如windows上的DNS Client Service),瀏覽器。IE的缺省DNS緩存時間爲30分鐘,Firefox的缺省緩衝時間是1分鐘。 咱們能作的是儘可能減小一個頁面的主機名,但要在瀏覽器最大並行下載數跟dns查找之間作權衡。根據雅虎的研究,最好將主機名控制在2-4個內。
CDN加速
CDN 的本質也屬於緩存,內容分發網絡,把數據緩存在裏用戶近的地方,使用戶儘快的獲取數據。
CDN 一般是部署在網絡運營商的機房,這些運營商爲用戶提供網絡服務,所以用戶請求的路由會優先到達 CDN 服務器,若是存在請求的資源的話,就直接返回,以最短路徑返回響應,提升了用戶訪問速度,同時還可以爲中心機房減輕壓力。其原理以下:
CDN 通常用來緩存靜態資源,如css,Script腳本,靜態頁面,圖片等,這些內容修改頻率很低可是訪問請求頻率很高,所以放在 CDN 上可以很好的改善訪問速度
減小重定向
重定向是指將一個URL從新路由到另外一個URL。瀏覽器會自動重定向請求到Location指定的URL上,也就說把以前的過程又重複一遍才能請求到真正的資源,會極大地下降用戶體驗。
好了,到此本文的主要內容已所有完結了。
本文是博主在學習過程當中的一個總結,特此記錄下來備忘,也但願對其餘小夥伴有所幫助。其中若有敘述不當之處,還望您能指出,一塊兒探討~
參考:(http://www.cnblogs.com/dojo-l...
(http://seanlook.com/2015/01/0...
(https://segmentfault.com/a/11...