我是如何將網(wǎng)頁性能提升5倍的 — 網(wǎng)絡(luò)優(yōu)化篇
本文是性能優(yōu)化系列的第二篇,主要從網(wǎng)絡(luò)的角度來聊聊如何提升網(wǎng)頁性能,上篇沒看的同學(xué)可以先看上一篇:構(gòu)建優(yōu)化篇
開啟 HTTP2
主要收益有三:
多路復(fù)用:真正意義的使多次請(qǐng)求復(fù)用一個(gè) TCP鏈接,降低建連時(shí)間二進(jìn)制格式傳輸信息:更貼合機(jī)器語言,解析更高效,性能更好 首部壓縮:降低頭部體積
多路復(fù)用

在 HTTP1.1 中,每次TCP連接只能下載一個(gè)資源,雖然可以使用長(zhǎng)連接來復(fù)用 tcp 連接,但是多次請(qǐng)求無法并發(fā):
1.每請(qǐng)求一個(gè)資源就會(huì)來一次 TCP連接,且有”隊(duì)首阻塞”問題出現(xiàn),這樣在資源過多的情況下,TCP連接消耗的時(shí)間會(huì)逐漸增加2.每次發(fā)送請(qǐng)求的 HTTP頭部信息基本相同,造成頭部信息冗長(zhǎng),耗費(fèi)流量3.從獲取解析 index.html文件到碰撞<link>、<script>等標(biāo)簽時(shí),中間流失的時(shí)間沒有充分利用
在 HTTP2 中:同域名下所有通信都在單個(gè)連接上完成,只需要占用一個(gè) TCP 連接,使用一個(gè)連接并行發(fā)送多個(gè)請(qǐng)求和響應(yīng), 這樣整個(gè)頁面資源的下載過程只需要一次慢啟動(dòng),同時(shí)也避免了多個(gè) TCP 連接競(jìng)爭(zhēng)帶寬所帶來的問題。單個(gè)連接可以承載任意數(shù)量的雙向數(shù)據(jù)流,并行交錯(cuò)地發(fā)送多個(gè)請(qǐng)求 / 響應(yīng),請(qǐng)求 / 響應(yīng)之間互不影響。
二進(jìn)制傳輸協(xié)議

H2 使用二進(jìn)制格式傳輸信息,相比 http 1.1 使用文本(plaintext)傳輸相比:
具有更貼合機(jī)器語言,解析更高效,性能更好 體積更小,本身是 0 1 構(gòu)成的二進(jìn)制流,避免了 http 1.1 一些無用空白或者低效的壓縮情況 傳輸不容易出錯(cuò)
首部壓縮

在 http 1.1 中,消息頭是不可以壓縮的,對(duì)于消息頭體積較大的情況(如 Cookie 頭中出現(xiàn)復(fù)雜長(zhǎng)消息),性能影響非常明顯。
H2 可以消除冗余的消息頭、壓縮消息頭體積:使用 『HPACK』算法來壓縮消息頭,同時(shí)在客戶端和服務(wù)器兩端建立“字典”,用索引號(hào)表示重復(fù)的字符串,類似的請(qǐng)求就不會(huì)再重復(fù)發(fā)送消息頭。
頭部壓縮可能有 90% 左右的提升,http 1.1 統(tǒng)計(jì)的平均響應(yīng)頭大小有 500 個(gè)字節(jié)左右,而 H2 的平均響應(yīng)頭大小只有 20 多個(gè)字節(jié),提升比較大。
域名收斂
把頁面資源部署在盡可能少的域名下,配合 H2,可以最大化的節(jié)省 DNS 解析、TCP 建連等網(wǎng)絡(luò)成本,更好的發(fā)揮其多路復(fù)用的優(yōu)勢(shì),大幅提升頁面性能。
同域名下所有通信都在單個(gè)連接上完成,只需要占用一個(gè) TCP 連接,使用一個(gè)連接并行發(fā)送多個(gè)請(qǐng)求和響應(yīng), 這樣整個(gè)頁面資源的下載過程只需要一次慢啟動(dòng),同時(shí)也避免了多個(gè) TCP 連接競(jìng)爭(zhēng)帶寬所帶來的問題。
我們可以將頁面中的 CDN 資源都收斂到常量中,統(tǒng)一引用:
const CDN_PRE = 'https://xxx.cdn.com/';
export default {
LOGO: `${CDN_PRE}img/logo.png`,
ICON: `${CDN_PRE}img/icon.png`
}
DNS 預(yù)解析
用戶請(qǐng)求頁面時(shí),首先通過 DNS 把域名解析為具體的 ip 地址,然后向具體的 ip 發(fā)起實(shí)際頁面請(qǐng)求。

使用 dns-prefetch 的 link 標(biāo)簽來向?yàn)g覽器聲明在接下來的頁面中即將用到某個(gè)域名下的資源,要求瀏覽器盡可能早的提前發(fā)起對(duì)該域名的 dns 解析操作。
DNS 預(yù)解析比較適合用于 CDN 域名場(chǎng)景,將常用的 CDN 域名進(jìn)行 DNS 預(yù)解析:
<!-- DNS 預(yù)解析 -->
<link rel="dns-prefetch" href="http://xxx.cdn.com/">
<link rel="dns-prefetch" href="http://xxx.cnd2.org/">
提前建立網(wǎng)絡(luò)連接
瀏覽器在建立網(wǎng)絡(luò)連接時(shí),要經(jīng)過 DNS 解析、TCP 握手等過程,在 https 場(chǎng)景下還需要進(jìn)行 TLS 加密信息驗(yàn)證。這些都是相當(dāng)耗時(shí)的操作??梢允褂?preconnet 的 link 標(biāo)簽來提前觸發(fā)上述操作,它會(huì)告訴瀏覽器,頁面即將使用某域名下的資源,可以讓瀏覽器提前建立網(wǎng)絡(luò)連接,在頁面真正發(fā)起資源請(qǐng)求時(shí),會(huì)使用已經(jīng)建立的網(wǎng)絡(luò)連接,直接跳過這些耗時(shí)建連操作。

使用網(wǎng)絡(luò)預(yù)連接的前提是可以判斷頁面有極大可能使用預(yù)先建立的網(wǎng)絡(luò)連接(如 Server API );對(duì)于 CDN 的資源,由于緩存的存在大多數(shù)情況并不會(huì)發(fā)送資源請(qǐng)求,所以不適合進(jìn)行 preconnet。
<!-- 提前建立網(wǎng)絡(luò)鏈接 -->
<link rel="preconnect" href="http://xxx.api.net" crossorigin>
<link rel="preconnect" href="http://xxx.api2.com" crossorigin>
brotli 壓縮

谷歌在 2015 年發(fā)布 Brotli 壓縮算法,相比 gzip,它具有更高的壓縮比和更快的壓縮性能。
JavaScript體積比gzip小14%HTML體積比gzip小21%CSS體積比gzip小17%
支持 TLS 1.3

TLS 1.3 是時(shí)隔九年對(duì) TLS 1.2 等之前版本的新升級(jí),也是迄今為止改動(dòng)最大的一次。針對(duì)目前已知的安全威脅,IETF(Internet Engineering Task Force,互聯(lián)網(wǎng)工程任務(wù)組) 正在制定 TLS 1.3 的新標(biāo)準(zhǔn),使其有望成為有史以來最安全,但也最復(fù)雜的 TLS 協(xié)議。
使用 TLS 1.3 協(xié)議只需要一次往返( 1-RTT )就可以完成握手,而使用 TLS 1.2 需要兩次往返( 2-RTT )才能完成握手,然后才能發(fā)送請(qǐng)求。相比 TLS 1.2,TLS 1.3 的握手時(shí)間減半。
支持 HSTS
如果你的站點(diǎn)在服務(wù)端開啟了強(qiáng)制 HTTPS,如果這時(shí)用戶使用 HTTP 協(xié)議進(jìn)行訪問,服務(wù)端會(huì)自動(dòng) 302 到 HTTPS,這會(huì)增加一次請(qǐng)求成本。

Strict-Transport-Security(簡(jiǎn)稱HSTS)HTTP Header 會(huì)告知瀏覽器在和網(wǎng)站進(jìn)行通信的時(shí)候強(qiáng)制性的使用 HTTPS,而不是通過明文的 HTTP 進(jìn)行通信,注意是在瀏覽器端進(jìn)行 HTTPS 重定向,這個(gè)會(huì)減少一次請(qǐng)求時(shí)間。
未完待續(xù),后續(xù)預(yù)告:
資源加載優(yōu)化 運(yùn)行時(shí)優(yōu)化 服務(wù)端優(yōu)化 性能指標(biāo)和測(cè)試工具
你的閱讀、點(diǎn)贊、在看都是對(duì)我最大的鼓勵(lì)
感謝支持??
