談談構建高效能WEB之HTTP首部優化

2021-08-01 07:06:34 字數 3177 閱讀 4999

0×00 前言

在討論瀏覽器優化之前,首先我們先分析下從客戶端發起乙個http請求到使用者接收到響應之間,都發生了什麼?知己知彼,才能百戰不殆。這也是作為乙個web開發者,為什麼一定要深入學習tcp/ip等網路知識。

0×01 到底發生什麼了?

當使用者發起乙個http請求時,首先客戶端將與服務端之間建立tcp連線,成功建立連線後,服務端將對請求進行處理,並對客戶端做出響應,響應內容一般包括響應主體。

(此處我們僅簡單說明,但真實的一次請求其中發生的事情是相當複雜的,這裡貼條連線,講得比較詳細)。

從輸入 url 到頁面載入完成的過程中都發生了什麼事情?

建立tcp連線

為了進行可靠的資料傳輸,tcp在進行傳送資料之前,會進行tcp三次握手,以此確定接收方能夠成功收取傳輸的資料,而建立連線的過程,必然是要耗費系統資源,以及時間資源的。

服務端處理並響應

當服務端接收到客戶端傳送來的請求之後,如果請求內容是靜態資源,服務端會從硬碟中取出靜態資源,然後將靜態資源放在響應主體中,傳送給客戶端。如果是動態資源,服務端首先取出資源,並通過業務邏輯操作,動態生成最終的響應主體,然後傳送給客戶端。

客戶端渲染

客戶端接受到服務端傳輸過來的網路資源,然後進行渲染,繪製等,最終展示給使用者。

0×02 優化點在**?

通過簡單的了解,我們了解到tcp建立連線是有資源消耗,時間消耗的,那麼如果我們無需每次簡歷tcp連線,那是否可以提高**的效能呢?答案是肯定的。

優化點1:減少tcp連線

我們知道,在獲取資源的時候,以獲取速度從慢到快是:網路資源->本地硬碟資源->本地記憶體資源。而網路資源也分硬碟資源以及記憶體資源。並且網路資源的傳輸,也是有相當大的時延的。

優化點2:對資料進行快取

優化點3:減少資料傳輸量

0×03 如何進行優化?

本篇文章主要說的優化點是與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-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響應。

版本標記:etag 和 if-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響應,基本與上一種方式是一致的。

上述兩種方式中,每次請求資源時,雖然在有快取的情況下,選擇快取進行渲染繪製,但是在這之前還是發起了一次http請求,雖然並沒有真實的響應實體,但是依然會造成一些資源消耗。而expires與上述兩種方式使用了不同的思路。

當服務端希望客戶端瀏覽器對某一資源進行快取時,為了免去客戶端每次都要詢問自己:我上次的快取現在還能用嗎?所以,服務端選擇了放權。只去告訴瀏覽器,我這次給你的資源你可以用多長時間,在這個時間段內,你可以一直使用它,無需每次諮詢我。而服務端就是通過expires屬性來告訴客戶端瀏覽器可以多長時間內不需要詢問服務端。如下:

expires:thu, 19 nov 2015 15:00:00 gmt

當客戶端在響應首部中發現該屬性值時,便會將該資源快取起來,而快取的過期時間即是expires中的時間。在這個時間段內,瀏覽器完全自主。

但是,expires有乙個不足的地方是,如果服務端時間與客戶端本地時間不統一時,可能服務端讓客戶端可以對該資源快取乙個小時,而客戶端本地時間比服務端時間快了兩個小時,那就意味著,所有快取都將不會生效。

於是有了彌補該不足的乙個屬性,即:cache-control。如果服務端在響應首部新增該屬性時,客戶端將直接使用該屬性值來生成本地時間的快取過期時間,這樣便解決了這個問題,如下:

cache-control:max-age=3600

如果客戶端在2023年10月01日13時00分00秒收到該響應時,便會加上3600秒也就是2023年10月01日14時00分00秒作為快取過期時間。如果響應頭部既有expires和cache-control,瀏覽器會首選cache-control。

0×04 結束

這裡,基本上說的都是與http首部有關的**效能優化。本文主要是在對《構建高效能web站點. 郭欣著》中第六章瀏覽器快取的學習總結筆記。這本書對於web站點的優化,從各個層面都做了很詳盡的講解,確實是一本很棒的書,也在這裡感謝hqboss的推薦。

構建高效能web

一直想在web效能 可擴充套件性和可用性提公升領域有所深入,但由於這些經驗的沉澱,沒有比較集中的學習資料輔助,並且也一直沒有接觸過有大規模訪問需求的web專案,因此總是在這個領域門外徘徊。上星期讀到一本書,構建高效能web站點 感覺有點如獲至寶,完全可以稱為高效能web的入門寶典,雖然內容不夠深入,...

構建高效能Web站點 筆記四

第七章 web伺服器快取 對url對映進行快取 ssi模式下對內容的通讀 有什麼提高?需要了解url解析過程。對於apache,它提供了兩個磁碟快取和記憶體快取mod disk cache,mod mem cache。mod disk cache在磁碟上維護了一塊多個程序的快取區,在效能上比mod ...

原創 構建高效能的Web站點

原創 構建高效能的web站點 一 web站點高效能主要體現在 高可用,低成本,高效能,可擴充套件,易維護 二 構建高效能的web站點措施 1 瀏覽器端優化 快取1 瀏覽器快取 2 web負載均衡 快取2 反向 快取 3 web元件分離 快取3 動態內容快取 快取4 分布式快取 快取5 資料庫快取及效...