為什么都說首屏html大小限制在14KB以內

原文在 https://github.com/879479119/879479119.github.io/issues/7 同步更新

由于前端資源的特殊性,首屏有大量的優(yōu)化都是體現(xiàn)在網絡上的,在網絡優(yōu)化中有非常多文章進行說明,這里我就不再贅述了。但是其中有一個非常有意思的點,就是14KB的問題,大家基本都聽說過,但是卻很少知道其中的道理,我在網上也沒看到很詳細的解釋,所以提出來說一下。

為什么首屏的html資源要限制在14KB以內呢?

  1. 最普遍的說法(各種博客):

    反正是14kb可以最好的利用網絡帶寬,可以讓html在一次就傳輸完所以最快咯~

  2. 詳細的說法(谷歌開發(fā)者文檔):

    https://developers.google.com/speed/docs/insights/mobile

鑒于 TCP 評估連接狀況的方式(即 TCP 慢啟動),新的 TCP 連接無法立即使用客戶端和服務器之間的全部有效帶寬。因此,在通過新連接進行首次往返的過程中,服務器最多只能發(fā)送 10 個 TCP 數(shù)據(jù)包(約 14KB),然后必須等待客戶端確認已收到這些數(shù)據(jù),才能增大擁塞窗口并繼續(xù)發(fā)送更多數(shù)據(jù)。

另外還需注意的是,10 個數(shù)據(jù)包 (IW10) 這一限值源自 TCP 標準的最近一次更新:您應確保自己的服務器已升級到最新版本,以便能夠充分利用這次更新。否則,這一限值可能會降低到 3-4 個數(shù)據(jù)包!

考慮到 TCP 的這種行為,請務必優(yōu)化您的內容,以盡可能減少為傳輸必要數(shù)據(jù)(以完成網頁的首次呈現(xiàn))而需進行的網絡往返的次數(shù)。理想情況下,ATF 內容應小于 98KB,這樣瀏覽器才能在 3 次網絡往返之后即可顯示網頁內容,以便為服務器響應延遲和客戶端呈現(xiàn)留出充足的時間預算。

看到上面的一段我們其實已經大概明白了,原來是因為慢啟動的存在導致我們第一屏只能發(fā)送14kb的內容,那為什么是1.4kb * 10這么計算呢?在舊版本的服務器上又是指的哪個版本之前呢?這里我們分兩塊說

什么是TCP慢啟動

TCP網絡通信占了我們日常使用的網絡通信的絕大部分,網絡環(huán)境質量變化都十分復雜,同時為了避免流量攻擊等行為,TCP實際上有一些防止擁塞的策略,主要是依靠四個算法來實現(xiàn):1)慢啟動2)擁塞避免,3)擁塞發(fā)生,4)快速恢復

我們現(xiàn)在只說slow start這一個,剩下的讀者可以自行搜索閱讀


慢啟動在1988年就由TCP-Tahoe 提出了,主要目的就是為了避免新加入的連接直接把帶寬打滿,也可以避免一些惡意行為。

先好好補一下計算機網絡的概念:

MTU: Maximum Transmission Unit,是指一種通信協(xié)議的某一層上面所能通過的最大數(shù)據(jù)包大?。ㄒ宰止?jié)為單位)。最大傳輸單元這個參數(shù)通常與通信接口有關(網絡接口卡、串口等)。

MSS: Maximum Segment Size,是傳輸控制協(xié)議(TCP)的一個參數(shù),以字節(jié)數(shù)定義一個計算機或通信設備所能接受的分段的最大數(shù)據(jù)量。 它并不會計算 TCP 或 IP 協(xié)議頭的大小。

從算法上來說原理(不論系統(tǒng)實現(xiàn)),慢啟動的算法如下(cwnd全稱Congestion Window):

1)連接建好的開始先初始化cwnd = 1,表明可以傳一個MSS大小的數(shù)據(jù)。

2)每當收到一個ACK,cwnd++; 呈線性上升

3)每當過了一個RTT,cwnd = cwnd*2; 呈指數(shù)讓升

4)還有一個ssthresh(slow start threshold),是一個上限,當cwnd >= ssthresh時,就會進入“擁塞避免算法”(去參考文章里面看)

所以,我們可以看到,如果網速很快的話,ACK也會返回得快,RTT也會短,那么,這個慢啟動就一點也不慢。但是我們首屏注重的就是第一個橫線,在這么看來只有1個MSS肯定是不夠使的,下圖說明了這個過程。

tcp.slow_.start_

上面的是理論的算法,實際上我們工作中就不是從1開始慢慢增長了,需要提一下的是一篇Google的論文《An Argument for Increasing TCP’s Initial Congestion Window》Linux 3.0后采用了這篇論文的建議——把cwnd 初始化成了 10個MSS。

而Linux 3.0以前,比如2.6,Linux采用了RFC3390,cwnd是跟MSS的值來變的,如果MSS< 1095,則cwnd = 4;如果MSS>2190,則cwnd=2;其它情況下,則是3。

不得不說隔了這么幾十年了,互聯(lián)網技術還是還是會隨著硬件能力的增長不斷更新的,現(xiàn)在就是10個MSS起步了,那么Linux 3.0這個我們用不用擔心呢?其實不用,3.0已經是2011年07月22日發(fā)行的了,以我們常用的centOS 7.2為例,他的內核版本已經是3.10了,不用擔心

MSS大小的計算

我們已經知道了1.4K * 10之中的10是從哪里來的了,10就是指的10個MSS,那1.4k就是這個MSS的最大大小了吧。熟悉計算機網絡的同學肯定已經知道是怎么回事了

因為我們一般認為終端用戶使用的網絡MTU是1500Byte來的,由于那相當于是我們數(shù)據(jù)鏈路層能夠傳輸?shù)拇笮×?,我們實際能傳輸?shù)腎P數(shù)據(jù)包內容肯定是比他少的,簡單的算一算

一個TCP包(數(shù)據(jù)段)的荷載 <= MSS < MTU

PPPoE首部6,PPP協(xié)議2
數(shù)據(jù)鏈路層最大data為1500-8=1492
IPv4首部最少20,IPv6首部40,TCP首部最少20
MSS最大為1492-20-20=1452

現(xiàn)在得到了MSS最大是1.452K這個結果,正是與我們預期一致的,Q.E.D


整個探索過程很多東西都是與網絡相關,可見計算機基礎和網絡對于一個工程師的重要性,雖然日常工作很少實際用到底層的原理,但是學習一下打好基礎還是很有價值的。。筆者對計算機網絡并不能算很熟悉,文中若有錯誤還請多指正!


轉載請注明出處及作者,同時感謝下列作者

[TCP的那些事兒(下) 陳皓]https://coolshell.cn/articles/11609.html

[goolge 移動網絡分析]https://developers.google.com/speed/docs/insights/mobile

[TCP/IP數(shù)據(jù)包結構詳解 水沐清華]https://blog.csdn.net/prsniper/article/details/6762145

[TCP一次數(shù)據(jù)包最大負載是多少?wind5o]https://segmentfault.com/a/1190000012962389%

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容