構建高性能WEB之HTTP首部優化

0x00 前言

在討論瀏覽器優化以前,首先咱們先分析下從客戶端發起一個HTTP請求到用戶接收到響應之間,都發生了什麼?知己知彼,才能百戰不殆。這也是做爲一個WEB開發者,爲何必定要深刻學習TCP/IP等網絡知識算法

0x01 到底發生什麼了?

當用戶發起一個HTTP請求時,首先客戶端將與服務端之間創建TCP鏈接,成功創建鏈接後,服務端將對請求進行處理,並對客戶端作出響應,響應內容通常包括響應主體。
(此處咱們僅簡單說明,但真實的一次請求其中發生的事情是至關複雜的,這裏貼條鏈接,講得比較詳細)。
從輸入 URL 到頁面加載完成的過程當中都發生了什麼事情?瀏覽器

創建TCP鏈接

爲了進行可靠的數據傳輸,TCP在進行發送數據以前,會進行TCP三次握手,以此肯定接收方可以成功收取傳輸的數據,而創建鏈接的過程,必然是要耗費系統資源,以及時間資源的。緩存

服務端處理並響應

當服務端接收到客戶端發送來的請求以後,若是請求內容是靜態資源,服務端會從硬盤中取出靜態資源,而後將靜態資源放在響應主體中,發送給客戶端。若是是動態資源,服務端首先取出資源,並經過業務邏輯操做,動態生成最終的響應主體,而後發送給客戶端。性能優化

客戶端渲染

客戶端接受到服務端傳輸過來的網絡資源,而後進行渲染,繪製等,最終展現給用戶。服務器

0x02 優化點在哪裏?

經過簡單的瞭解,咱們瞭解到TCP創建鏈接是有資源消耗,時間消耗的,那麼若是咱們無需每次簡歷TCP鏈接,那是否能夠提升網站的性能呢?答案是確定的。網絡

  • 優化點1:減小TCP鏈接app

咱們知道,在獲取資源的時候,以獲取速度從慢到快是:網絡資源->本地硬盤資源->本地內存資源。而網絡資源也分硬盤資源以及內存資源。而且網絡資源的傳輸,也是有至關大的時延的。性能

  • 優化點2:對數據進行緩存學習

  • 優化點3:減小數據傳輸量優化

0x03 如何進行優化?

本篇文章主要說的優化點是與HTTP首部有關的優化,或者說是與瀏覽器端有關的優化,其它優化這裏暫不贅述。

持久鏈接:Keep-Alive

HTTP鏈接設計之初是請求-響應-關閉,也就是每創建一次HTTP鏈接,只能進行一次資源請求,當須要在同一目標服務器上獲取多個資源的時候,就須要屢次創建HTTP鏈接,而這個屢次創建鏈接的過程,便下降了網站的性能。

因而,出現了Connection:Keep-Alive,人稱持久鏈接。Keep-Alive避免了創建或者說從新創建鏈接的過程,減小了HTTP鏈接。

而與此配套的有Keep-Alive:timeout=120,max=5

其中,timeout=120 是指這個TCP通道保持120S,max=5 指這個TCP通道最多接收5個HTTP請求,以後便自動關閉該鏈接。

修改時間:Last-ModifiedIf-Modified-Since

Last-Modified首部是服務端對客戶端的HTTP響應所加的一個與緩存有關的HTTP首部,該首部標記了所請求資源在服務端的最後修改時間。相似:

Last-Modified : Fri , 12 May 2015 13:10:33 GMT

當客戶端發現HTTP響應頭中有Last-Modified,會對資源進行緩存,在下次請求資源時,在HTTP請求頭中添加If-Modified-Since首部,首部中將會添加上次成功請求資源時響應頭部的Last-Modified屬性值,即:

If-Modified-Since : Fri , 12 May 2015 13:10:33 GMT

當服務端接收到的HTTP請求中,發現有If-Modified-Since頭部時,會將該屬性值與請求資源的最後修改時間進行比對,若是最後修改時間與該屬性值一致時,服務端會返回一個304 Not Modified響應,該響應中不包括響應實體。瀏覽器收到304的響應後,會進行重定向,獲取本地緩存資源。若是最後修改時間與該屬性值不一致,則會從服務端從新獲取資源,作出200響應。

版本標記:ETagIf-None-Match

ETag其實與Last-Modified是差很少的方式,可是ETag並無選擇以時間做爲標記,而是對所請求文件進行某些算法來生成一串惟一的字符串,做爲對某一文件的標記。當收到客戶端對某一資源的請求時,服務端在響應時,添加ETag首部,以下:

ETag:W/"a627ff1c9e65d2dede2efe0dd25efb8c"

當客戶端發現ETag頭部時,一樣會對資源進行緩存,並在下次請求時,在請求頭部添加If-None-Match,如:

If-None-Match:W/"a627ff1c9e65d2dede2efe0dd25efb8c"

當服務端收到請求中含有該頭部時,會使用一樣的ETag生成算法對文件ETag進行計算,並與If-None-Match屬性值進行比對,若是一致,則返回一個304 Not Modified響應,基本與上一種方式是一致的。

緩存時間:ExpiresCache-Control

上述兩種方式中,每次請求資源時,雖然在有緩存的狀況下,選擇緩存進行渲染繪製,可是在這以前仍是發起了一次HTTP請求,雖然並無真實的響應實體,可是依然會形成一些資源消耗。而Expires與上述兩種方式使用了不一樣的思路。

當服務端但願客戶端瀏覽器對某一資源進行緩存時,爲了免去客戶端每次都要詢問本身:我上次的緩存如今還能用嗎?因此,服務端選擇了放權。只去告訴瀏覽器,我此次給你的資源你能夠用多長時間,在這個時間段內,你能夠一直使用它,無需每次諮詢我。而服務端就是經過Expires屬性來告訴客戶端瀏覽器能夠多長時間內不須要詢問服務端。以下:

Expires:Thu, 19 Nov 2015 15:00:00 GMT

當客戶端在響應首部中發現該屬性值時,便會將該資源緩存起來,而緩存的過時時間便是Expires中的時間。在這個時間段內,瀏覽器徹底自主。

可是,Expires有一個不足的地方是,若是服務端時間與客戶端本地時間不統一時,可能服務端讓客戶端能夠對該資源緩存一個小時,而客戶端本地時間比服務端時間快了兩個小時,那就意味着,全部緩存都將不會生效。

因而有了彌補該不足的一個屬性,即:Cache-Control。若是服務端在響應首部添加該屬性時,客戶端將直接使用該屬性值來生成本地時間的緩存過時時間,這樣便解決了這個問題,以下:

Cache-Control:max-age=3600

若是客戶端在2015年10月01日13時00分00秒收到該響應時,便會加上3600秒也就是2015年10月01日14時00分00秒做爲緩存過時時間。若是響應頭部既有ExpiresCache-Control,瀏覽器會首選Cache-Control

0x04 結束

這裏,基本上說的都是與HTTP首部有關的網站性能優化。本文主要是在對《構建高性能WEB站點. 郭欣著》中第六章瀏覽器緩存的學習總結筆記。這本書對於WEB站點的優化,從各個層面都作了很詳盡的講解,確實是一本很棒的書,也在這裏感謝HQBOSS的推薦。

原文做者:我纔是二亮
原文連接:http://www.2liang.me/archives/264轉載必須在正文中標註並保留原文連接、做者等信息。

相關文章
相關標籤/搜索