http发送16进制报文_HTTP系列探索HTTP网络层的”前端性能优化“
作者:前端學苑 公號 / 前端小賈 (本文來自作者投稿)
編者薦語
性能是前端編碼規范、網絡層面、輔助工具等相互作用的結果。
這是一個兼顧廣度和深度的問題,優化好了可以加快首屏加載速度提高用戶留存率,節省服務器資源降低成本等,也是區分初高級前端工程師的重要標準。
本文重點
- 掌握HTTP報文及其在實踐中的運用
- 掌握瀏覽器中的“強緩存” 和 “協商緩存”
- 掌握TCP三次握手和四次揮手的運行機制及意義
- 掌握HTTP1.0/1.1/2.0之間的區別
為了把HTML、CSS和JavaScript轉化成活靈活現、絢麗多彩的網頁,瀏覽器需要處理一系列的中間過程。
優化性能其實就是了解這個過程中發生了什么
即CRP(Critical Rendering Path,關鍵渲染路徑)。
從輸入 URL 到頁面展示,這中間發生了什么?
1)URL解析
2)緩存檢查
3)DNS 解析:將域名解析成 IP 地址;
4)TCP 連接:TCP 三次握手;
5)發送 HTTP 請求;
6)服務器處理請求并返回 HTTP 的報文;
7)瀏覽器解析渲染頁面;
8)斷開連接:TCP 四次揮手;
整個過程的關鍵點展開的說一下。
URL解析
1、地址解析
HTTP 是明文傳輸協議,連接簡單,是無狀態的。
HTTPS 協議是由 SSL+HTTP 協議構建的可進行加密傳輸、身份認證的網絡協議,比 HTTP 協議安全。
端口號:HTTP ?80,HTTPS ?443。FTP 21
2、編碼(面試常問)
encodeURI ?編碼/ decodeURI 解碼
對整個URL的編碼:處理空格/中文...
var?uriStr?=?"http://www.baidu.com?name=張三&num=001?zs";var?uriec?=?encodeURI(uriStr);
document.write("編碼后的"?+?uriec);
編碼后的http://www.baidu.com?name=%E5%BC%A0%E4%B8%89&num=001%20zs
var?uridc?=?decodeURI(uriec);
document.write("解碼后的"?+?uridc);
解碼后的http://www.baidu.com?name=張三&num=001?zs
encodeURIComponent / decodeURIComponent
主要對傳遞的參數信息編碼
let?url?=?`http://www.jb51.net/api/?lx=1&name=${encodeURIComponent("前端學苑")}&from=${encodeURIComponent("http://www.baidu.com/")}`
結果:
http://www.jb51.net/api/?lx=1&
name=%E5%89%8D%E7%AB%AF%E5%AD%A6%E8%8B%91&from=http%3A%2F%2Fwww.baidu.com%2F
URI / URL / URN
(1)URI統一資源標識符,用來唯一的標識一個資源。
(2)URL統一資源定位器,它是一種具體的URI,即URL可以用來標識一個資源,
而且還指明了如何locate這個資源。
(3)URN統一資源命名,是通過名字來標識資源,比如mailto:java-net@java.sun.com。
緩存檢查
緩存檢測:產品性能優化的重要手段。
緩存位置:
1)Memory Cache : 內存緩存
2)Disk Cache:硬盤緩存
補充回答:(面試常問)
1)打開網頁:查找 disk cache 中是否有匹配,如有則使用,如沒有則發送網絡請求。
2)普通刷新:因TAB沒關閉,因此memory cache是可用的,會被優先使用,其次才是disk cache。
3)強制刷新:瀏覽器不使用緩存,因此發送的請求頭部均帶有 Cache-control: no-cache,服務器直接返回 200 和最新內容。
說明:頁面刷新的情況:先看有沒有內存,如果沒有走硬盤。頁面重新加載:直接走硬盤。
注: html 頁面一般不做強緩存:每一次html的請求都是正常的HTTP請求。
緩存方式
- 強緩存(Expires / Cache-Control)
- 協商緩存(Last-Modified / ETag)
強緩存
強緩存 Expires / Cache-Control瀏覽器對于強緩存的處理:根據第一次請求資源時返回的響應頭來確定的。
1)Expires: 緩存過期時間,用來指定資源到期的時間(HTTP/1.0)
2)Cache-Control: cache-control: max-age=2592000第一次拿到資源后的2592000秒內(30天),再次發送請求,讀取緩存中的信息(HTTP/1.1)。
3)兩者同時存在的話,Cache-Control優先級高于Expires。
強緩存流程導圖補充回答:(面試常問)
強緩存問題,如果服務器文件更新了,但是本地還是有緩存,這樣不就拿不到最新的信息了嗎?
處理方式:
1)服務器更新資源后,讓資源名稱和之前不一樣,這樣頁面導入全新的資源。
例如:
index.abc.jsindex.cde.js
處理結果:webpack hash name。
2)當文件更新后,我們在html導入的時候,設置一個后綴[時間戳]。
例如:
<script?src="index.js?123456"><script?src="index.js?234234">處理結果:隨機碼或時間戳。
協商緩存
協商緩存與強緩存區別:協商緩存總會和服務器協商,所以一定要發HTTP請求的。
協商緩存 Last-Modified / ETag協商緩存就是強制緩存失效后,瀏覽器攜帶緩存標識向服務器發起請求,由服務器根據緩存標識決定是否使用緩存的過程。
協商緩存流程導圖補充回答:
第一次向服務器發送請求
協商緩存緩存沒有,向服務器發送請求 (沒有傳遞任何的標識);
服務器收到請求準備內容;
last-modified: 資源文件最后更新的時間;
ETag:記錄的是一個標識 (也是根據資源文件更新生成的,每一次資源更新都會重新生成一個 ETag);
說明:客戶端拿到信息后渲染,把信息和標識緩存到本地。
第二次發請求
if-Modified-Since = Last-Modified 值;if-None-Match = ETag 值;
給服務器;
說明:服務器根據標識判斷文件是否更新。
擴展問題:
1)304時,本地緩存文件丟失了怎么辦?會向服務器再發請求 ,獲取最新的數據。
2)什么情況下強緩存協商緩存都要設置?一般情況下都需要設置的。
3)強緩存與協商緩存策略,針對于我們的靜態資源文件,而且是不經常更新的。
數據緩存
數據緩存流程導圖cookie 和 session 區別 (面試常問)
1)cookie數據存放在客戶的瀏覽器上,session數據放在服務器上。
2)cookie不是很安全,別人可以分析存放在本地的cookie并進行cookie欺騙,考慮到安全應當使用session。
3)session會在一定時間內保存在服務器上。當訪問增多,會比較占用你服務器的性能,考慮到減輕服務器性能方面,應當使用cookie。
4)單個cookie保存的數據不能超過4K,很多瀏覽器都限制一個站點最多保存20個cookie。
5)可以考慮將登陸信息等重要信息存放為session,其他信息如果需要保留,可以放在cookie中。
DNS解析
在地址欄輸入的域名并不是最后資源所在的真實位置,域名只是與IP地址的一個映射。
DNS域名解析有兩種方法:遞歸查詢和迭代查詢
首先走遞歸查詢:主機向本地域名服務器的查詢采用遞歸查詢。
其次走迭代查詢:本地域名服務器向根域名服務器的查詢采用迭代查詢。
每一次DNS解析時間預計在20\~120毫秒
1)減少DNS請求次數
2)DNS預獲取(DNS Prefetch)
<meta?http-equiv="x-dns-prefetch-control"?content="on"><link?rel="dns-prefetch"?href="//static.360buyimg.com"/>
<link?rel="dns-prefetch"?href="//misc.360buyimg.com"/>
<link?rel="dns-prefetch"?href="//img10.360buyimg.com"/>
<link?rel="dns-prefetch"?href="//d.3.cn"/>
<link?rel="dns-prefetch"?href="//d.jd.com"/>
服務器拆分的優勢
1)資源的合理利用;
2)抗壓能力加強;
3)提高HTTP并發;
TCP三次握手
TCP三次握手,建立連接通道
1) 客戶端發送一個 SYN (標志)碼給服務器,要求建立數據連接。(第一次握手,由瀏覽器發起,告訴服務器我要發送請求了)
2) 服務器SYN和自己處理一個SYN (標志);叫SYN+ACK (確認包);發送給客戶端,可以建立連接。(第二次握手,由服務器發起,告訴瀏覽器我準備接受了,你趕緊發送吧)
3) 客戶端再次發送ACK向服務器,服務器驗證 ACK 沒問題,建立連接。(第三次握手,由瀏覽器發送,告訴服務器,我馬上就發了,準備接受吧)
seq序號,用來標識從TCP源端向目的端發送的字節流,發起方發送數據時對此進行標記;
ack確認序號,只有ACK標志位為1時,確認序號字段才有效,ack=seq+1;
標志位
ACK:確認序號有效
RST:重置連接
SYN:發起一個新連接
FIN:釋放一個連接
TCP三次握手流程導圖三次握手為什么不用兩次,或者四次? (面試常問)
TCP作為一種可靠傳輸控制協議,其核心思想:既要保證數據可靠傳輸,又要提高傳輸的效率!
數據傳輸
HTTP請求報文與響應報文格式
請求報文包含:
- 請求行:包含請求方法、URI、HTTP版本信息;
- 請求頭;
- 請求體。
響應報文包含:
- 響應行:包含HTTP版本、狀態碼、狀態碼的原因短語;
- 響應頭
- 響應體
HTTP Request Header 常見的請求頭:
1)Accept: 瀏覽器能夠處理的內容類型 ?application/json, text/javascript, /; q=0.01
2)Accept-Charset: 瀏覽器能夠顯示的字符集
3)Accept-Encoding: 瀏覽器能夠處理的壓縮編碼 gzip ?application/json, text/javascript, /; q=0.01
4)Accept-Language: 瀏覽器當前設置的語言 zh-CN,zh;q=0.9,en;q=0.8
5)Connection: 瀏覽器與服務器之間連接的類型 keep-alive
6)Cookie: 當前頁面設置的任何 Cookie
7)Host: 發出請求的頁面所在的域 ?www.baidu.com
8)Referer: 發出請求的頁面的URL
9)User-Agent: 瀏覽器的用戶代理字符串
HTTP Responses Header常見響應頭:
1)Date: 表示消息發送的時間,時間的描述格式由rfc822定義
2)server: 服務器名字
3)Connection: 瀏覽器與服務器之間連接的類型
4)content-type: 表示后面的文檔屬于什么MIME類型
5)Cache-Control: 控制HTTP緩存
HTTP 狀態碼 (面試常問)
101: 切換協議
200: 請求被正常處理
206: 客戶端只是請求資源的一部分,服務器只對請求的部分資源執行GET方法,相應報文中通過Content-Range指定范圍的資源。(視頻大小)
301: 永久性重定向
302: 臨時重定向
304: 發送附帶條件的請求時,條件不滿足時返回,與重定向無關 (用于緩存控制)
307: 協商緩存
400: 請求無效
401: 請求需要認證
403: 服務器已經得到請求,但是拒絕執行
404: 服務器無法找到對應資源
500: 服務器內部錯誤
502: 網關錯誤
503: 服務器正忙
TCP四次揮手
1)客戶端發送 FIN (結束)報文,通知服務器數據已經傳輸完畢;(第一次揮手:由瀏覽器發起的,發送給服務器,我請求報文發送完了,你準備關閉吧) 用來關閉Client到Server的數據傳送。
2)服務器接收到之后,通知客戶端我收到了SYN,發送ACK(確認)給客戶端,數據還沒有傳輸完成。(第二次揮手:由服務器發起的,告訴瀏覽器,我請求報文接受完了,我準備關閉了,你也準備吧)
3)服務器已經傳輸完畢,再次發送FIN通知客戶端,數據已經傳輸完畢;(第三次揮手:由服務器發起,告訴瀏覽器,我響應報文發送完了,你準備關閉吧) 用來關閉Server到Client的數據傳送
4)客戶端再次發送ACK,進入TIME\_WAIT狀態,服務器和客戶端關閉連接。(第四次揮手:由瀏覽器發起,告訴服務器,我的響應報文接受完了,我準備關閉了,你也準備吧)
TCP四次揮手流程導圖為什么連接的時候是三次握手,關閉的時候卻是四次握手?(面試常問)
1)服務器端收到客戶端的SYN連接請求報文后,可以直接發送SYN+ACK報文。
2)但關閉連接時,當服務器端收到FIN報文時,很可能并不會立即關閉鏈接,所以只能先回復一個ACK報文,告訴客戶端:”你發的FIN報文我收到了”,只有等到服務器端所有的報文都發送完了,我才能發送FIN報文,因此不能一起發送,故需要四步握手。
Connection: keep-alive
當使用Keep-Alive模式時,Keep-Alive功能使 客戶端到服務器端的連接持續有效,對服務器的后繼請求時,Keep-Alive功能避免了建立或者重新建立連接。
通過使用keep-alive機制,可以減少tcp連接建立次數,也意味著可以減少TIME_WAIT狀態連接,以此提高性能和提高httpd服務器的吞吐率 (更少的tcp連接意味著更少的系統內核調用,socket的accept()和close()調用)。
HTTP版本間的對比
HTTP1.0和HTTP1.1的一些區別
1)緩存處理
HTTP1.0中主要使用 Last-Modified,Expires 來做為緩存判斷的標準,HTTP1.1則引入了更多的緩存控制策略:ETag,Cache-Control…
2)帶寬優化及網絡連接的使用
HTTP1.1支持斷點續傳,即返回碼是206(Partial Content)
3)錯誤通知的管理
在HTTP1.1中新增了24個錯誤狀態響應碼,如409(Conflict)表示請求的資源與資源的當前狀態發生沖突;410(Gone)表示服務器上的某個資源被永久性的刪除…
4)Host頭處理
在HTTP1.0中認為每臺服務器都綁定一個唯一的IP地址,因此,請求消息中的URL并沒有傳遞主機名(hostname)。但隨著虛擬主機技術的發展,在一臺物理服務器上可以存在多個虛擬主機(Multi-homed Web Servers),并且它們共享一個IP地址。HTTP1.1的請求消息和響應消息都應支持Host頭域,且請求消息中如果沒有Host頭域會報告一個錯誤(400 Bad Request)
5)長連接
HTTP1.1中默認開啟Connection:keep-alive,一定程度上彌補了HTTP1.0每次請求都要創建連接的缺點。
HTTP2.0和HTTP1.X相比的新特性
1)新的二進制格式(Binary Format)
HTTP1.x的解析是基于文本,基于文本協議的格式解析存在天然缺陷,文本的表現形式有多樣性,要做到健壯性考慮的場景必然很多,二進制則不同,只認0和1的組合,基于這種考慮HTTP2.0的協議解析決定采用二進制格式,實現方便且健壯。
2)header壓縮
HTTP1.x的header帶有大量信息,而且每次都要重復發送,HTTP2.0使用encoder來減少需要傳輸的header大小,通訊雙方各自cache一份header fields表,既避免了重復header的傳輸,又減小了需要傳輸的大小。
3)服務端推送(server push)
例如我的網頁有一個sytle.css的請求,在客戶端收到sytle.css數據的同時,服務端會將sytle.js的文件推送給客戶端,當客戶端再次嘗試獲取sytle.js時就可以直接從緩存中獲取到,不用再發請求了
//?通過在應用生成HTTP響應頭信息中設置Link命令Link:?styles.css>;?rel=preload;?as=style,?</example.png>;?rel=preload;?as=image
4)多路復用(MultiPlexing)
- HTTP/1.0 ?每次請求響應,建立一個TCP連接,用完關閉
- HTTP/1.1 「長連接」 若干個請求排隊串行化單線程處理,后面的請求等待前面請求的返回才能獲得執行機會,一旦有某請求超時等,后續請求只能被阻塞,毫無辦法,也就是人們常說的線頭阻塞;
- HTTP/2.0 「多路復用」多個請求可同時在一個連接上并行執行,某個請求任務耗時嚴重,不會影響到其它連接的正常執行;
感謝大家
如果你覺得這篇內容對你挺有啟發,我想邀請你幫我三個小忙:
總結
以上是生活随笔為你收集整理的http发送16进制报文_HTTP系列探索HTTP网络层的”前端性能优化“的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python123外汇兑换计算器_Pyt
- 下一篇: oracle如何规则显示,Oracle语