聊聊 HTTP 性能優化
哈嘍大家好,我是咸魚。
作為用戶的我們在 "上網沖浪" 的時候總是希望快一點,尤其是搶演唱會門票的時候,但是現實并非如此,有時候我們會遇到頁面加載緩慢、響應延遲的情況。
而 HTTP 協議作為互聯網世界的基礎,從網站打開速度到移動應用的響應時間,HTTP 性能的優化直接關系到我們在網絡世界的舒適體驗程度。
更快的響應時間和速度能夠提供更好的用戶體驗,不但如此,還可以降低服務器和網絡帶寬的使用,從而節省相關的成本。
那么今天我們就來聊聊 HTTP 性能如何進行優化。
數據壓縮
隨著互聯網的發展,網路上傳輸的數據越來越大,隨隨便便一個文件幾個 G 甚至上百 G,就算你是百兆、千兆帶寬也扛不住。
如何能夠在有限的帶寬里傳輸更多的數據,常見的解決方式是數據壓縮。
如果壓縮率能有 50%,例如 100K 的數據能夠壓縮成 50K 的大小,那么就相當于在帶寬不變的情況下網速提升了一倍,加速的效果是非常明顯的。
使用常見的壓縮算法(如 gzip 和 br )對數據進行壓縮,不但如此,我們可以對 HTTP 中傳輸的各種數據進行針對性地壓縮,做到【對癥下藥】。
- HTML/CSS/JS
對于這類純文本格式數據,我們在進行壓縮時通常會去除其中多余的空格、換行和注釋等元素。盡管壓縮后的文本可能看起來比較混亂,對人類可讀性較差,但這對計算機并不影響流暢閱讀。
- JPG/JPEG/PNG
對于這類圖片格式數據,雖然它本身已經被壓縮過了,不能被 gzip、br 處理,但仍然有優化的空間。
例如,可以考慮去除圖片中的拍攝時間、地點、機型等元數據,適度降低分辨率和縮小尺寸。
此外,盡量采用高壓縮率的格式,有損格式可以選擇 JPEG,而無損格式則可以考慮使用 webp 格式。
- 小數據
對于較小的數據,HTTP 中有一種被稱為 “資源合并”(Concatenation)的優化方式,即將多個小資源合并成一個大資源,通過單個請求下載到客戶端,隨后由客戶端使用 JavaScript、CSS 等進行拆分使用。
這種方式雖然減少了請求的次數,但是處理起來比較麻煩。
需要注意的是,在數據壓縮的時候應當注意選擇適當的壓縮率,不要追求最高壓縮比,否則會耗費服務器的計算資源,增加響應時間,反而會“得不償失”。
上面講的都是針對 HTTP 報文里的 body 的壓縮方式,對于 header 的壓縮在 HTTP/1 里是沒有的(HTTP/2 才有)。
不過我們可以采取一些手段來減少 header 的大小,不必要的字段就盡量不發(例如 User-Agent、Server、X-Powered-By)
使用緩存
數據 “千里迢迢” 從服務端到客戶端,我們可以把這些 “來之不易” 的數據【暫時保存】起來,以便在下次請求時直接復用,從而避免多次請求帶來的高昂成本。
比如說網站上訪問量最高的網頁、熱點新聞,尤其是【讀多寫少】的數據,把它們緩存下來能夠把巨大的流量擋在外面,減輕服務器的壓力,對性能的改善是非常顯著
的。
HTTP 傳輸的每一個環節基本上都會有緩存,不過大致可以分成:
- 瀏覽器端緩存
- 服務端緩存
- 中間傳輸緩存
在瀏覽器端,通過與服務端協商相關的緩存策略,將一些資源緩存到本地,以便在下次訪問時進行復用。
常見的緩存策略包括 HTTP 頭中的 Cache-Control、Expires 以及 ETag 等,通過這些標識,瀏覽器可以判斷是否需要從服務端重新獲取資源,或者直接使用本地緩存。
在服務端,可以借助專門的緩存中間件,如 Memcache 或 Redis,將計算得到的中間結果和資源存儲在內存或硬盤中。
這樣,Web 服務器在處理請求時會首先檢查緩存,如果找到相應的數據,就能夠立即返回給客戶端,避免了訪問后端服務或數據庫的時間開銷。
而關于中間傳輸的緩存,常見的有 HTTP 代理緩存和 CDN(Content Delivery Network,內容分發網絡)。
HTTP 代理緩存,通過使用增加了緩存功能的 HTTP 代理服務器(例如 Nginx),緩存源服務器的數據,分發給下游的客戶端。
而使用 CDN 把源服務器的內容逐級緩存到網絡中的每一個 CDN 節點中,這樣用戶在上網的時候就不直接訪問源站,而是訪問離它最近的一個 CDN 節點(其實就是緩存了源服務器內容的代理服務器)
圖片
使用高性能 web 服務器
除了傳輸過程中對數據進行壓縮和使用緩存,我們還可以在服務端下手。
首先我們應該選擇高性能的 Web 服務器,最常見的應該就是 Nginx 了。
作為一款【高性能,輕量級】的 Web 服務器,【進程池+單線程】的工作模式讓 Nginx 消耗較少的 CPU 和內存,非常輕量,而【I/O 多路復用】又使得 Nginx 的工作效率大大提升。
我們還可以通過 Nginx 實現【動靜分離】:把動態頁面和靜態頁面交給不同的服務器來解析,來加快解析速度,提高請求的訪問效率,降低原來單個服務器的壓力。
# Nginx 動靜分離配置
server {
listen 80 ;
location ~* \.(png)$ {
root /var/images/png/;
}
location ~* \.(php)$ {
proxy_pass http://php_back_end;
}
}不但如此,在配置 Nginx 的時候還應該開啟 HTTP 長連接。
這樣做可以平均握手成本到多次請求中,避免了每個請求都要進行 TCP 連接建立和斷開的開銷,從而提高了性能。連接的復用使得后續的請求不再需要進行完整的三次握手過程,減少了連接建立的延遲。
升級 HTTP/2
除了上面的【數據壓縮】、【使用緩存】、【使用高性能 web 服務器】,HTTP 性能優化還有一個選擇,那就是【把協議由 HTTP/1 升級到 HTTP/2】
HTTP/2 基于 Google 的 SPDY 協議,完全兼容 HTTP/1,我們來看看它的一些優點。
- 頭部壓縮
報文 Header 一般會攜帶 “User Agent”、“Cookie”、“Accept”、“Server” 等許多固定的頭字段,多達幾百字節甚至上千字節,但 Body 卻經常只有幾十字節(比如 GET 請求)
更要命的是,成千上萬的請求響應報文里有很多字段值都是重復的,非常浪費,導致大量帶寬消耗在了這些冗余度極高的數據上。
為了壓縮頭部,HTTP/2 開發了專門的 “HPACK” 算法:在客戶端和服務器兩端建立“字典”,用索引號表示重復的字符串,還釆用哈夫曼編碼來壓縮整數和字符串,可以達到 50%~90% 的高壓縮率。
- 二進制格式
相較于 HTTP/1 里純文本形式的報文,HTTP/2 全面采用二進制格式,既方便計算機解析,而且體積小、速度快,使性能大大提高。
除此之外,HTTP/2 使用虛擬的流(stream)傳輸消息,解決了“隊頭阻塞”問題,同時實現了“多路復用”,提高連接的利用率;
圖片
今天這篇文章講了 HTTP 性能優化的一些方法,希望能對你有幫助!


























