簡述網(wǎng)絡(luò)通信的整個過程:
網(wǎng)絡(luò)通信的整個過程:
URL地址解析
DNS域名解析
和服務(wù)器建立TCP連接(三次握手)
客戶端將信息發(fā)送給服務(wù)器(發(fā)送HTTP請求)
服務(wù)器得到并處理請求(HTTP響應(yīng)內(nèi)容)
客戶端渲染服務(wù)器返回的內(nèi)容
客戶端斷開和服務(wù)端TCP連接(四次揮手)
1.URL:
URL (Uniform Resource Location):統(tǒng)一資源定位符,根據(jù)這個地址找到對應(yīng)的資源。
URN(Uniform Resource Name):統(tǒng)一資源名稱,一般指國際上通用的標準名字,比如國際統(tǒng)一發(fā)版的編號。不常用,沒能融入網(wǎng)絡(luò)標準。
URI(Uniform Resource Identifier):統(tǒng)一資源標識符,URL 和 URN 是它的子集。一般來說,提到 URI 其實就是指 URL。
一個完整的URL包含的內(nèi)容:
https://www.bilibili.com:80/video/BV1Lb411k7eP?p=2&b=4#hash
協(xié)議(https:// ):信息傳輸?shù)臉藴屎凸ぞ?/span>
- HTTP 超文本傳輸協(xié)議,除了文本,也支持媒體資源文件及(或者流文件)XML格式數(shù)據(jù)。
- HTTPS 更加安全,提供加密的HTTP。
- FTP 文件傳輸協(xié)議(一般應(yīng)用于本地資源到服務(wù)器的上傳下載)
域名(www.bilibili.com):確定要訪問的主機。方便用戶記憶的名字,通過域名解析對應(yīng)相應(yīng)的IP地址。
- 頂級域名 bilibili.com
- 一級域名 www.bilibili.com
- 二級域名 member.bilibili.com
- 域名后綴的語義化:.com 國際域名? . cn 中文域名??? .gov 政府??? .net 系統(tǒng)類??
??? .io 博客??? .org 官方組織
端口號(:80): 確定一個服務(wù)器上的哪一個服務(wù)。端口號取值范圍 0~65535
- HTTP 默認端口號:80
- HTTPS 默認端口號: 443
- FTP 默認端口號:21
請求資源的路徑名稱(/video/BV1Lb411k7eP):
- 默認資源路徑或者名稱:比如:xxx.com/mydate/123.html? 如果省略:123.html
這個資源名,服務(wù)器會默認尋找 default.html 沒有,再找 index.html... ,如果都沒有,返回404。當然這些默認資源也可以在服務(wù)端自行配置。- 偽URL地址處理:URL重寫技術(shù)=>為了增加SEO搜索引擎優(yōu)化。 大型網(wǎng)站一般會使用動態(tài)網(wǎng)址,而動態(tài)的網(wǎng)址通常不能被搜索引擎收錄,所以往往需要將動態(tài)網(wǎng)址靜態(tài)化,此時就需要重寫URL。
URL地址傳參信息(?p=2&b=4):
- 客戶端向服務(wù)器傳遞信息,有很多方式:URL地址問號傳參(以 ?開始的鍵值對,相鄰的兩個鍵值對之間 以 & 隔開)和 請求報文傳輸(請求頭和請求體)
- 也可以用于不同頁面之間的信息交互。
HASH值(#hash):
- 也能充當信息傳輸方法
- 錨點定位
- 基于HASH實現(xiàn)路由管控:不同的HASH值,展示不同的組件和模塊
對URL進行編碼:
- 如果我們的參數(shù)是這樣的:?value=100&key='c=c&c=c' ,即:參數(shù)值中就包含=或&這種特殊字符,這必然會造成解析歧義,所以我們需要對URL地址進行編碼。
- 1.現(xiàn)代游覽器會默認對 請求地址中出現(xiàn)的非UNICODE編碼類容進行編碼。 默認基于 encodeURI 編碼 我們可以使用 decodeURI 解碼。使用 encodeURI 整個URL中的特殊字符都會自動編譯。
- 2. encodeURLComponent 和 decodeURIComponent 相對于 encodeURL 來書,不用于對整個URL編碼,僅是對URL的部分信息進行編碼(一般都是問號傳參的值編碼)
- 3. escape 和 unescape 不同于以上兩種,這種編碼格式不是客戶端與服務(wù)端都有。它只針對瀏覽器對中文進行編碼,一般只用于客戶端頁面之間的傳值處理。
2. DNS優(yōu)化
DNS緩存:瀏覽器會在第一次域名解析后,默認建立緩存,這個緩存一般只有一分鐘。
減少DNS解析次數(shù)。
DNS預(yù)獲取(dns-prefetch):在頁面加載開始時,就把當前頁面中需要訪問其他域名(服務(wù)器)的信息進行提前DNS解析,以后在加載到這部分具體內(nèi)容就可以不用再開始域名解析了。

<meta http-equiv=”x-dns-prefetch-control” content=”on”>? <!-- 開啟DNS預(yù)解析-->
<link rel="dns-prefetch" href="//s1.hdslb.com">?? <!-- DNS預(yù)解析的域名-->

3. TCP 三次握手
第一次握手:由瀏覽器發(fā)起,告訴服務(wù)器 “嘿!我要發(fā)送請求了”
- 客戶端發(fā)送syn包(seq=j)到服務(wù)器,并進入SYN_SENT狀態(tài),等待服務(wù)器確認;(SYN:同步序列編號,通常值為: 1)
第二次握手:由服務(wù)器發(fā)起,告訴瀏覽器 “我已經(jīng)做好接收請求的準備了,你趕緊發(fā)送吧”
- 服務(wù)器收到syn包,必須確認客戶的SYN(ack=j+1),同時自己也發(fā)送一個SYN包(seq=k),即SYN+ACK包,此時服務(wù)器進入SYN_RECV狀態(tài)。
第三次握手:由瀏覽器發(fā)起,告訴服務(wù)器,“我開始發(fā)送了,你準備接收”
- 客戶端收到服務(wù)器的SYN+ACK包,向服務(wù)器發(fā)送確認包ACK(ack=k+1),此包發(fā)送完畢,客戶端和服務(wù)器進入ESTABLISHED(TCP連接成功)狀態(tài),完成三次握手。
4. HTTP
HTTP報文:請求報文+響應(yīng)報文(控制臺 => network)
HTTP常見狀態(tài)碼:1~5開頭的三位數(shù)字。
? -?? 200 OK::成功。
? - ? 201 CREATED:一般用于告訴服務(wù)器創(chuàng)建一個新文件,最后創(chuàng)建成功后返回 201 狀態(tài)碼。
? -? 204 NO CONTENT:服務(wù)已成功接收請求,但對于某些請求(列如:PUT 或 DELETE),服務(wù)器并不想處理,所以返回一個空內(nèi)容,并告知 204 狀態(tài)碼。
? - ? 301 Moved Permanently:永久重定向(永遠轉(zhuǎn)移)。
? -?? 302 Moved Temporarily: 臨時轉(zhuǎn)移,現(xiàn)在不常見?,F(xiàn)在重定向用 307 處理。
? -?? 307 Temporary Redirect:臨時重定向,主要用于:服務(wù)器的負載均衡。
? -?? 304? Not Modified:設(shè)置 HTTP的協(xié)商緩存。
? -?? 400 Bad Request: 傳遞給服務(wù)器的參數(shù)錯誤。
? -?? 401 Unauthorized:無權(quán)限訪問。
? -?? 404? Not Found:請求地址錯誤。
? -?? 500? Internal Server Error:未知服務(wù)器錯誤。
? -?? 503? Service Unavailable:服務(wù)器超負荷。
5.? 瀏覽器渲染

?? 瀏覽器渲染頁面的步驟:
瀏覽器 解析HTML,生成DOM樹;解析CSS,生成CSSOM樹。
將DOM樹和CSSOM樹結(jié)合,生成渲染樹(Render Tree)。
回流(Layout):根據(jù)渲染樹,計算它們在視口的確切位置和大小。
重繪(Painting):根據(jù)渲染樹以及回流得到的幾何信息,得到節(jié)點的絕對像素。
Display:將像素發(fā)送給GPU,展示在頁面上。
? DOM的重繪和回流:
重繪:元素樣式改變(但大小,位置不變)
回流:頁面布局的幾何信息發(fā)生變化(元素大小、位置 發(fā)生變化),會觸發(fā)重新布局,從而導(dǎo)致渲染樹重新計算布局和渲染。
觸發(fā)回流的操作如:添加或刪除可見的DOM元素;元素的位置、大小發(fā)生變化;瀏覽器的窗口尺寸發(fā)生變化(因為回流是根據(jù)可視窗口來計算元素的大小和位置)。
回流一定會觸發(fā)重繪,但重繪不一定會回流。
性能優(yōu)化——避免DOM回流:
- 減少DOM操作,基于 Vue/React 使用數(shù)據(jù)驅(qū)動 MVVM/MVC/虛擬DOM、
- 分離讀寫操作:現(xiàn)代瀏覽器的渲染隊列機制=> 當瀏覽器讀取到某一行代碼要修改樣式,并不是立刻就渲染,而是先將修改操作放到渲染隊列中,然后繼續(xù)向下讀取。直到讀取的不再是修改樣式操作,再將整個渲染隊列整體渲染,引發(fā)一次回流。(讀取樣式,如:offsetTop、clientLeft、scrollLeft、getComputedStyle、currentStyle ... 也會刷新渲染隊列)
- 樣式集中改變。
- 緩存布局信息:其原理也就是 分離讀取操作。
????div.style.left = div.offsetLeft + '1px';? ? div.style.Top= div.offsetTop + '1px';
???? 改為:
???? var strLeft =?div.offsetLeft;? var strTop =?div.offsetTop;
?????div.style.left =?strLeft + '1px'; ? div.style.Top =?strTop + '1px';
- 元素批量修改:
??? 比如:我想為一個 id=box 的div盒子添加10個span標簽。
??? let frg = document.creatDocumentFragment();??? // 先創(chuàng)建一個文檔容器。
??? for (let i = 0; i < 10; i++) {????????? // 在文檔容器中執(zhí)行操作。
???????? let span = document.creatElement('span');
???????? span.innerHTML = i;
? ? ? ?? frg.appendChild(span); ?
???? }
???? box.appendChild(frg);???? // 將文檔容器一次添加。
??? frg = null;? // 最后刪除文檔容器,釋放內(nèi)存。
??? 當然,使用ES6的 ` ` 模板字符串還要更為簡潔些。
- 動畫效果應(yīng)用到position屬性為absolute或fixed的元素上(即脫離文檔流):
- CSS3硬件加速(GPU加速):css3 的:transform 、 opacity、 filters ... 這些屬性會觸發(fā)硬件加速,不會引發(fā)回流重繪。但是,過多的使用會占用大量內(nèi)存,性能消耗嚴重。
- 犧牲平滑度換取速度。
- 避免table布局和使用CSS的JavaScript表達式