Create by jsliang on 2019-2-23 20:55:34
Recently revised in 2019-3-12 21:34:59javascript
Hello 小夥伴們,若是以爲本文還不錯,記得給個 star , 大家的 star 是我學習的動力!GitHub 地址php
【2019-08-16】Hello 小夥伴們,因爲 jsliang 對文檔庫進行了重構,這篇文章的一些連接可能失效,而 jsliang 沒有精力維護掘金這邊的舊文章,對此深感抱歉。請須要獲取最新文章的小夥伴,點擊上面的 GitHub 地址,去文檔庫查看調整後的文章。html
本文涉及知識點:前端
在本文中,jsliang 會講解經過自我探索後關於上述知識點的我的理解,若有紕漏、疏忽或者誤解,歡迎各位小夥伴留言指出。java
若是小夥伴對文章存有疑問,想快速獲得回覆。
或者小夥伴對 jsliang 我的的前端文檔庫感興趣,也想將本身的前端知識整理出來。
歡迎加 QQ 羣一塊兒探討:798961601
。git
不折騰的前端,和鹹魚有什麼區別github
目錄 |
---|
一 目錄 |
二 前言 |
三 防抖與節流 |
3.1 防抖 |
3.2 節流 |
四 重繪與迴流 |
五 瀏覽器解析 URL |
六 DNS 域名解析 |
七 TCP 三次握手與四次揮手 |
八 瀏覽器渲染頁面 |
九 總結 |
十 參考文獻 |
返回目錄面試
在工做中,咱們可能碰到這樣的問題:數據庫
因此,這時候,咱們就要用到 防抖與節流 了。後端
那麼,講到 防抖與節流,咱們能夠順帶探祕下 重繪與迴流。
提及 重繪與迴流,咱們就順帶把 瀏覽器輸入 URL 後發生的事情 也關注一下,從而引出 DNS、TCP 等知識點,最終串起來構成本文的輪廓,方便 jsliang 和小夥伴們對這塊知識的整理與記憶。
經過代碼去了解某樣事物,每每是瞭解某個知識點最快的形式。
下面咱們有段防抖小案例代碼。
若是小夥伴們手頭有電腦,並感興趣想先本身思考下什麼是防抖。能夠將代碼複製到瀏覽器,嘗試點擊按鈕,並關注下控制檯,看看 Console 是如何打印的。
若是小夥伴們手頭沒有電腦,那麼咱一塊兒先瞅瞅代碼實現,再看看下面 GIF 演示。(這樣效果沒有本身敲的直白有效)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>防抖</title>
</head>
<body>
<button id="debounce">點我防抖!</button>
<script> window.onload = function() { // 一、獲取這個按鈕,並綁定事件 var myDebounce = document.getElementById("debounce"); myDebounce.addEventListener("click", debounce(sayDebounce)); } // 二、防抖功能函數,接受傳參 function debounce(fn) { // 四、建立一個標記用來存放定時器的返回值 let timeout = null; return function() { // 五、每次當用戶點擊/輸入的時候,把前一個定時器清除 clearTimeout(timeout); // 六、而後建立一個新的 setTimeout, // 這樣就能保證點擊按鈕後的 interval 間隔內 // 若是用戶還點擊了的話,就不會執行 fn 函數 timeout = setTimeout(() => { fn.call(this, arguments); }, 1000); }; } // 三、須要進行防抖的事件處理 function sayDebounce() { // ... 有些須要防抖的工做,在這裏執行 console.log("防抖成功!"); } </script>
</body>
</html>
複製代碼
很好,相信小夥伴們已經看完了代碼,下面咱們看看它的演示:
這時候,咱們能夠拋出防抖的概念了:
結合上面的代碼,咱們能夠了解到,在觸發點擊事件後,若是用戶再次點擊了,咱們會清空以前的定時器,從新生成一個定時器。意思就是:這件事兒須要等待,若是你反覆催促,我就從新計時!
空講無益,show you 場景:
小夥伴們能夠嘗試看着上面的案例,先本身實現一遍這個場景的解決,若是感受不行,那就看:《防抖和節流的應用場景和實現》
知識點補充:何爲
arguments
?
首先,後端轉前端的同窗,能夠將arguments
理解爲能實現重載函數功能的工具。
而後,咱們舉個例子:在function test()
這個方法中,因爲咱們不肯定變量有多少,好比test("jsliang", 24)
,又或者test("LiangJunrong", "jsliang", "24")
,這時候只須要在函數test
中用arguments
接收就好了。
最後,在function test() { let arr1 = argument[0] }
中,arr1
就能夠獲取到傳進來的第一個變量。
因此,fn.call(this, arguments)
實際上是將不肯定變量替換到函數中了。
參考資料 1:《閒聊 JS 中的 apply 和 call》
參考資料 2:《js 中 arguments 的用法》
說完防抖,下面咱們講講節流,規矩就不說了,先上代碼:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>節流</title>
</head>
<body>
<button id="throttle">點我節流!</button>
<script> window.onload = function() { // 一、獲取按鈕,綁定點擊事件 var myThrottle = document.getElementById("throttle"); myThrottle.addEventListener("click", throttle(sayThrottle)); } // 二、節流函數體 function throttle(fn) { // 四、經過閉包保存一個標記 let canRun = true; return function() { // 五、在函數開頭判斷標誌是否爲 true,不爲 true 則中斷函數 if(!canRun) { return; } // 六、將 canRun 設置爲 false,防止執行以前再被執行 canRun = false; // 七、定時器 setTimeout( () => { fn.call(this, arguments); // 八、執行完事件(好比調用完接口)以後,從新將這個標誌設置爲 true canRun = true; }, 1000); }; } // 三、須要節流的事件 function sayThrottle() { console.log("節流成功!"); } </script>
</body>
</html>
複製代碼
很好,看完代碼的小夥伴應該大體清楚是怎麼回事了,下面咱們看 GIF 實現:
看完代碼和 GIF 實現,咱們能夠明白,節流便是:
那麼,節流在工做中的應用?
這樣,在某些特定的工做場景,咱們就可使用防抖與節流來減小沒必要要的損耗。
那麼問題來了,假設面試官聽到你這句話,是否是會接着問一句:「爲何說上面的場景不節制會形成過多損耗呢?」
OK,這就涉及到瀏覽器渲染頁面的機制了……
在說瀏覽器渲染頁面以前,咱們須要先了解兩個點,一個叫 瀏覽器解析 URL,另外一個就是本章節將涉及的 重繪與迴流:
常見的重繪操做有:
常見的迴流操做有:
看到這裏,小夥伴們可能有點懵逼,你剛剛還跟我講着 防抖與節流 ,怎麼一會兒跳到 重繪與迴流 了?
OK,賣個關子,先看下面場景:
看到這裏,小夥伴們能夠將一些字眼結合起來了:爲何須要 節流,由於有些事情會形成瀏覽器的 迴流,而 迴流 會使瀏覽器開銷增大,因此咱們經過 節流 來防止這種增大瀏覽器開銷的事情。
形象地用圖來講明:
這樣,咱們就能夠形象的將 防抖與節流 與 重繪與迴流 結合起來記憶起來。
那麼,在工做中咱們要如何避免大量使用重繪與迴流呢?:
OK,至此咱們就講完兩個部分了,那麼問題又來了:「瀏覽器渲染過程當中,是否是也有重繪與迴流?」「從瀏覽器輸入 URL 到渲染成功的過程當中,究竟發生了什麼?」
咱們,繼續深刻探索……
爲了能讓咱們的知識層面看起來更有深度,咱們應該考慮下面兩個問題了:
OK,興致來了,咱們就先從 瀏覽器解析 URL 看起,先來看看當用戶輸入 URL,到瀏覽器呈現給用戶頁面,經歷瞭如下過程:
講到這裏,忽然想起一個對話:
學生:「老師,這門課的考試重點是什麼?」
老師:「全都是重點!」
enm...老師會不會被打我不知道,可是 jsliang 這樣寫會被懟我就清楚,因此,咱仍是結合上面的圖,進一步勾勒咱們的結構:
很好,jsliang 感受本身的畫圖技術又進了一步~
①:雖然很感激網上有那麼多的文章能夠參考,可是在我查了二十來篇文章後,jsliang 以爲這部分十有八九有問題撒,問了些小夥伴,它們有的說對,有的說錯。不過,不妨礙小夥伴們繼續往下看哈。
②:爲了不出簍子,下面貼出另一個版本,小夥伴們能夠在評論區說出你支持哪一個版本哈:
- 版本 B
- 用戶輸入 URL 地址。
- 對 URL 地址進行 DNS 域名解析。
- 進行 TCP 鏈接。
- 進行 HTTP 報文的請求與響應。
- 瀏覽器解析文檔資源並渲染頁面。
在這裏咱們能夠清晰的瞭解到從 用戶輸入 URL,到瀏覽器呈現給用戶頁面,經歷了哪些過程。
那麼剩下的就簡單了:
Let's go~ 逐步完成下面三個知識點!
參考文獻 1:《網頁解析的全過程(輸入url到展現頁面)》
參考文獻 2:《瀏覽器渲染頁面過程剖析》
首先,咱們解決第一個問題:
DNS(Domain Name System)是 域名系統 的英文縮寫,提供的服務是用於將主機名和域名轉換爲 IP 地址的工做:
域名:http://jsliang.top
<---> DNS <---> IPV4:119.147.15.13
IPV4 是造假的,僅用來講明 DNS 解析後能返回 IP 地址
因此,當用戶在瀏覽器輸入 http://jsliang.top
時,DNS 經歷瞭如下步驟:
看文字老是難以理解的,跟着 jsliang 畫張圖過一遍,就感受清晰了:
而後,咱們解決第二個問題:
什麼是 TCP 呢?TCP(Transmission Control Protocol 傳輸控制協議)是一種面向鏈接的、可靠的、基於字節流的傳輸層通訊協議。
簡單來講,它的做用就是將數據流從一臺主機可靠地傳輸到另外一臺主機。
至於具體的工做原理,這裏暫時涉及不到,咱們目前只想知道兩個點:三次握手與四次揮手。
seq = x
,並將該數據包發送給 Server,Client 進入 SYN-SENT 狀態,等待 Server 確認。SYN = 1
得知 Client 請求創建鏈接,Server 將標誌位 SYN 和 ACK 都置爲 1,ack = x + 1
,隨機產生一個值 seq = y
,並將該數據包發送給Client以確認鏈接請求,Server 進入 SYN-RCVD
狀態,此時操做系統爲該 TCP 鏈接分配 TCP 緩存和變量。x + 1
,ACK 是否爲 1,若是正確則將標誌位 ACK 置爲 1,ack = y + 1
,而且此時操做系統爲該 TCP 鏈接分配 TCP 緩存和變量,並將該數據包發送給 Server,Server 檢查 ack 是否爲 y + 1
,ACK 是否爲 1,若是正確則鏈接創建成功,Client 和 Server 進入 established 狀態,完成三次握手,隨後 Client 和 Server 就能夠開始傳輸數據。文字太亂,show you picture:
FIN = 1
,序號 seq = u
),並中止再發送數據,主動關閉 TCP 鏈接,進入 FIN-WAIT-1(終止等待1)狀態,等待 Server 的確認。ACK = 1
,確認號 ack = u + 1
,序號 seq = v
),Server 進入 CLOSE-WAIT(關閉等待)狀態,此時的 TCP 處於半關閉狀態,Client 到 Server 的鏈接釋放。注:Client 收到 Server 的確認後,進入 FIN-WAIT-2(終止等待2)狀態,等待 Server 發出的鏈接釋放報文段。
FIN = 1
,ACK = 1
,序號 seq = w
,確認號 ack = u + 1
),Server 進入 LAST-ACK(最後確認)狀態,等待 Client 的確認。ACK = 1
,seq = u + 1
,ack = w + 1
),Client 進入 TIME-WAIT(時間等待)狀態。此時 TCP 未釋放掉,須要通過時間等待計時器設置的時間 2MSL 後,Client 才進入 CLOSED 狀態。文字太亂,show you picture:
OK,至此咱們就理解了 TCP 及其三次握手和四次揮手過程,爲了方便小夥伴們形象記憶,jsliang 搞了個小故事,但願小夥伴們能加深印象:
OK,成功出糗,相信小夥伴們有了個很好的瞭解了。
那麼,咱們繼續前行探索。
參考文獻 1:《TCP三次握手和四次揮手過程》
參考文獻 2:《TCP的三次握手與四次揮手(詳解+動圖)》
最後,咱們解決第三個問題:
話很少說,一塊兒來看:
文字講解確定仍是不夠清晰的,可是 jsliang 畫了幾張圖也累了,因此我們 盜 來了一張圖:
這樣,咱們就對 瀏覽器渲染頁面過程 一清二楚啦~
參考文獻:《一篇文章搞定前端面試》
至此,咱們回顧下本身作了什麼?
綜上,若是咱們僅僅是須要關注面試的一個點,咱們極可能由於不知頭尾,而被面試官問得啞口無言。
可是,若是咱們知道一個知識點,並對其進行思路發散,深刻學習,相信面試官問起來的時候,小夥伴們就能夠侃侃而談,而不會被問地體無完膚了!
最後祝小夥伴們找到合適的滿意的工做~
jsliang 廣告推送:
也許小夥伴想了解下雲服務器
或者小夥伴想買一臺雲服務器
或者小夥伴須要續費雲服務器
歡迎點擊 雲服務器推廣 查看!
jsliang 的文檔庫 由 梁峻榮 採用 知識共享 署名-非商業性使用-相同方式共享 4.0 國際 許可協議進行許可。
基於github.com/LiangJunron…上的做品創做。
本許可協議受權以外的使用權限能夠從 creativecommons.org/licenses/by… 處得到。