前言
大家好,我是林三心,相信大家在面試中被問過很多次“說一說在網址欄輸入URL會發生什麼?”
,相信很多人都能倒背如流地答出所有步驟,但是單單會背可是不行的,其實這個問題包含了很多瀏覽器
與效能優化
的知識點,今天我就給大家分享一下這15個知識點
輸入URL發生了啥?
- 1、瀏覽器的位址列輸入URL並按下回車。
- 2、瀏覽器查詢當前URL是否存在快取,並比較快取是否過期。
- 3、DNS解析URL對應的IP。
- 4、根據IP建立TCP連線(三次握手)。
- 5、HTTP發起請求。
- 6、伺服器處理請求,瀏覽器接收HTTP響應。
- 7、渲染頁面,構建DOM樹。
- 8、關閉TCP連線(四次揮手)。
永恆鑽石
1. 瀏覽器應該具備什麼功能?
- 1、網路:瀏覽器通過網路模組來下載各式各樣的資源,例如
HTML文字,JavaScript程式碼,CSS樣式表,圖片,音視訊檔案等
。網路部分尤為重要,因為它耗時長,而且需要安全訪問網際網路上的資源 - 2、資源管理:從網路下載,或者本地獲取到的資源需要有
高效的機制
來管理他們。例如如何避免重複下載,資源如何快取等等
- 3、網頁瀏覽:這是瀏覽器的核心也是最
基本
的功能,最重要
的功能。這個功能決定了如何將資源轉變為視覺化
的結果 - 4、多頁面管理
- 5、外掛與管理
- 6、賬戶和同步
- 7、安全機制
- 8、開發者工具
瀏覽器的主要功能總結起來就是一句話:將使用者輸入的url轉變成視覺化的影像
。
2. 瀏覽器的核心
在瀏覽器中有一個最重要的模組,它主要的作用是把一切請求回來的資源變成視覺化的影像
,這個模組就是瀏覽器核心
,通常他也被稱為渲染引擎
。
下面是瀏覽器核心的總結:
- 1、IE:
Trident
- 2、Safari:
WebKit
。WebKit本身主要是由兩個小引擎構成的,一個正是渲染引擎“WebCore”,另一個則是javascript解釋引擎“JSCore”,它們均是從KDE的渲染引擎KHTML及javascript解釋引擎KJS衍生而來。 - 3、Chrome:
Blink
。在13年釋出的Chrome 28.0.1469.0版本開始,Chrome放棄Chromium引擎轉而使用最新的Blink引擎(基於WebKit2——蘋果公司於2010年推出的新的WebKit引擎),Blink對比上一代的引擎精簡了程式碼、改善了DOM框架,也提升了安全性。 - 4、Opera:2013年2月宣佈放棄
Presto
,採用Chromium
引擎,又轉為Blink
引擎 - 5、Firefox:
Gecko
3. 程式和執行緒
- 1、程式:程式的一次執行,它佔有一片獨有的記憶體空間,是
作業系統
執行的基本單元
- 2、執行緒:是程式內的一個獨立執行單元,是CPU排程的最小單元,
程式執行
的基本單元
- 3、一個程式中
至少
有一個執行的執行緒:主執行緒
。它在程式啟動後自動建立 - 4、一個程式可以同時執行多個執行緒,我們常說程式是
多執行緒執行
的,比如你使用聽歌軟體
,這個軟體就是一個程式
,而你在這個軟體裡聽歌
,收藏歌
,點贊評論
,這就是一個程式裡的多個執行緒操作
- 5、一個程式中的資料可以供其中的多個執行緒
直接共享
,但是程式與程式
之間的資料時不能共享
的 - 6、JS引擎是
單執行緒執行
的
4. 瀏覽器渲染引擎的主要模組
- 1、HTML解析器:解釋
HTML文件
的解析器,主要作用是將HTML文字解釋為DOM樹
- 2、CSS解析器:它的作用是為DOM中的各個元素物件
計算出樣式資訊
,為佈局提供基礎設施
- 3、JavaScript引擎:JavaScript引擎能夠解釋
JavaScript程式碼
,並通過DOM介面和CSS介面
來修改網頁內容 和樣式資訊
,從而改變渲染的結果
- 4、佈局(layout):在DOM建立之後,WebKit需要將其中的元素物件同樣式資訊
結合起來
,計算他們的大小位置等佈局資訊
,形成一個能表達著所有資訊的內部表示模型
- 5、繪圖模組(paint):使用
圖形庫
將佈局計算後的各個網頁的節點繪製成影像結果
5. 大致的渲染過程
第1題的第7點,渲染頁面,構建DOM樹
,接下來說說大致的渲染過程
- 1、瀏覽器會從上到下解析文件
- 2、遇見HTML標記,呼叫
HTML解析器
解析為對應的token(一個token就是一個標籤文字的序列化)並構建DOM樹(就是一塊記憶體,儲存著tokens,建立他們之間的關係) - 3、遇見style/link標記呼叫相應解析器處理CSS標記,並構建出
CSS樣式樹
- 4、遇見script標記,呼叫
JavaScript引擎
處理script標記,繫結事件,修改DOM樹/CSS樹等 - 5、將DOM樹與CSS合併成一個
渲染樹
- 6、根據渲染樹來渲染,以計算每個節點的
幾何資訊
(這一過程需要依賴GPU) - 7、最終將各個節點
繪製
在螢幕上
至尊星耀
6. CSS阻塞情況以及優化
- 1、style標籤中的樣式:由
HTML解析器
進行解析,不會
阻塞瀏覽器渲染(可能會產生“閃屏現象”),不會阻塞DOM解析 - 2、link引入的CSS樣式:由
CSS解析器
進行解析,會
阻塞瀏覽器渲染,會阻塞後面的js語句執行,不阻塞DOM的解析 - 3、優化:使用CDN節點進行外部資源加速,對CSS進行壓縮,優化CSS程式碼(不要使用太多層選擇器)
注意:看下圖,HTML
和CSS
是並行解析的,所以CSS不會阻塞HTML解析
,但是,會阻塞整體頁面的渲染
(因為最後要渲染必須CSS和HTML一起解析完併合成一處)
7. JS阻塞問題
- 1、
js會阻塞後續DOM的解析
,原因是:瀏覽器不知道後續指令碼的內容,如果先去解析了下面的DOM,而隨後的js刪除了後面所有的DOM,那麼瀏覽器就做了無用功,瀏覽器無法預估指令碼里面具體做了什麼操作,例如像document.write這種操作,索性全部停住,等指令碼執行完了,瀏覽器再繼續向下解析DOM - 2、
js會阻塞頁面渲染
,原因是:js中也可以給DOM設定樣式,瀏覽器等該指令碼執行完畢,渲染出一個最終結果,避免做無用功。 - 3、
js會阻塞後續js的執行
,原因是維護依賴關係,例如:必須先引入jQuery再引入bootstrap
8. 資源載入阻塞
無論css阻塞,還是js阻塞,都不會阻塞瀏覽器載入外部資源
(圖片、視訊、樣式、指令碼等)
原因:瀏覽器始終處於一種:“先把請求發出去”
的工作模式,只要是涉及到網路請求的內容,無論是:圖片、樣式、指令碼,都會先傳送請求去獲取資源,至於資源到本地之後什麼時候用,由瀏覽器自己協調。這種做法效率很高。
9. 為什麼CSS解析順序從右到左
如果是從左到右
的話:
- 1、第一次從
爺節點 -> 子節點 -> 孫節點1
- 2、第一次從
爺節點 -> 子節點 -> 孫節點2
- 3、第一次從
爺節點 -> 子節點 -> 孫節點3
如果三次都匹配不到的話,那至少也得走三次:爺節點 -> 子節點 -> 孫節點
,這就做了很多無用功啊。
如果是從右到左
的話:
- 1、第一次從
孫節點1
,找不到,停止 - 2、第一次從
孫節點2
,找不到,停止 - 3、第一次從
孫節點3
,找不到,停止
這樣的話,儘早發現找不到,儘早停止,可以少了很多無用功。
最強王者
10. 什麼是重繪迴流
- 1、重繪:重繪是一個
元素外觀的改變
所觸發的瀏覽器行為,例如改變outline、背景色等屬性。瀏覽器會根據元素的新屬性重新繪製,使元素呈現新的外觀。重繪不會帶來重新佈局,所以並不一定伴隨重排。 - 2、迴流:渲染物件在建立完成並新增到渲染樹時,並不包含位置和大小資訊。
計算這些值的過程稱為佈局或重排,或迴流
- 3、
"重繪"不一定需要"重排"
,比如改變某個網頁元素的顏色,就只會觸發"重繪",不會觸發"重排",因為佈局沒有改變。 - 4、
"重排"大多數情況下會導致"重繪"
,比如改變一個網頁元素的位置,就會同時觸發"重排"和"重繪",因為佈局改變了。
11. 觸發重繪的屬性
` color background * outline-color
* border-style * background-image * outline
* border-radius * background-position * outline-style
* visibility * background-repeat * outline-width
* text-decoration * background-size * box-shadow`
12. 觸發迴流的屬性
` width top * text-align
* height * bottom * overflow-y
* padding * left * font-weight
* margin * right * overflow
* display * position * font-family
* border-width * float * line-height
* border * clear * vertival-align
* min-height * white-space`
13. 常見觸發重繪迴流的行為
- 1、當你增加、刪除、修改 DOM 結點時,會導致 Reflow , Repaint。
- 2、當你移動 DOM 的位置
- 3、當你修改 CSS 樣式的時候。
- 4、當你
Resize
視窗的時候(移動端沒有這個問題,因為移動端的縮放沒有影響佈局視口) - 5、當你修改網頁的
預設字型
時。 - 6、獲取DOM的
height或者width
時,例如clientWidth、clientHeight、clientTop、clientLeft、offsetWidth、offsetHeight、offsetTop、offsetLeft、scrollWidth、scrollHeight、scrollTop、scrollLeft、scrollIntoView()、scrollIntoViewIfNeeded()、getComputedStyle()、getBoundingClientRect()、scrollTo()
14. 針對重繪迴流的優化方案
- 1、元素位置移動變換時儘量使用CSS3的
transform
來代替top,left
等操作 - 2、不要使用
table
佈局 - 3、將多次改變樣式屬性的操作
合併成一次操作
- 4、利用
文件素碎片(documentFragment)
,vue使用了該方式提升效能 - 5、動畫實現過程中,啟用
GPU硬體加速:transform:tranlateZ(0)
- 6、為動畫元素
新建圖層
,提高動畫元素的z-index
- 7、編寫動畫時,儘量使用
requestAnimationFrame
15. 瀏覽器快取分類
強快取
- 不會向伺服器傳送請求,直接從本地快取中獲取資料
- 請求資源的的狀態碼為:
200 ok(from memory cache)
- 優先順序:
cache-control > expires
協商快取
- 向伺服器傳送請求,伺服器會根據請求頭的資源判斷是否命中協商快取
- 如果命中,則返回
304
狀態碼通知瀏覽器從快取中讀取資源 - 優先順序:
Last-Modified與ETag是可以一起使用的
,伺服器會優先驗證ETag
,一致的情況下,才會繼續比對Last-Modified
,最後才決定是否返回304
結語
我是林三心,一個熱心的前端菜鳥程式設計師。如果你上進,喜歡前端,想學習前端,那我們們可以交朋友,一起摸魚哈哈,摸魚群,加我請備註【思否】