當我們訪問一個網站的時候,我們通常是在瀏覽器中輸入我們所需要訪問的網址,然后點擊就可以瀏覽我們所需要瀏覽的網站,但瀏覽器在我們輸入域名到返回給我們最后的結果也是經歷了一番繁瑣的操作。
瀏覽器通常的步驟如下
1.瀏覽器的地址欄輸入URL并按下回車。
2.瀏覽器查找當前URL是否存在緩存,并比較緩存是否過期。
3.DNS解析URL對應的IP。
4.根據IP建立TCP連接(三次握手)。
5.HTTP發起請求。
6.服務器處理請求,瀏覽器接收HTTP響應。
7.渲染頁面,構建DOM樹。
8.關閉TCP連接(四次揮手)
接下來我們主要分析第七點,也就是瀏覽器如何根據獲取到的文件渲染出相應的頁面,主要從HTML、CSS、JS這三點來分析
HTML稱為超文本標簽語言,是一種標識性的語言。普通的txt文檔在加了HTML標簽之后,就變得具有語義了,瀏覽器能根據不同的語義進行不同的解析。目前常見的HTML分為兩種,一種是HTML另一種是XHTML。相較于XHTML的”嚴格“,HTML以其相對較為”寬松“的特效獲得了較為廣泛的喜愛
瀏覽器獲取到HTML文擋的時候,會逐行解析文檔,并根據文檔內容將文檔內容轉化為DOM樹在在瀏覽器中渲染出來
<html> <body> <h1> Hello World </h1> </body> </html> 這是一個最基礎的HTML文檔,當瀏覽器獲取到這個文件的時候,通過解析文字中的語義化標簽,通過解析標簽的<(Tag open state:開始標簽)到>(Tag name state:結束標簽),屬性名稱和相應值,直到文檔結束,并將其轉換為DOM樹并最終在瀏覽器中繪制出來。
DOM樹
瀏覽器遇到語義解釋性的CSS標簽嵌入文件,那么此時IE的下載過程會啟用單獨連接進行下載,并在下載后繼續進行解析。并且只有在文件解析完成后才會在往下解析(瀏覽器阻塞),瀏覽器對CSS樣式的解析是從左到右的,比如.box .left p,會在頁面中找到所有的p標簽,然后在p標簽中找其父元素有.left類的p元素,再找祖父元素有.box的p標簽
如下圖示,瀏覽器會按照從右向左的順序去讀取選擇器。先找到span然后順著往上找到class為“haha”的div再找到id為“molly”的元素。成功匹配到則加入結果集,如果直到根元素html都沒有匹配,則不再遍歷這條路徑,從下一個span開始重復這個過程
提升渲染效率的幾個點 - 盡量少的去對標簽進行選擇,而是用class - 不要去用標簽限定ID或者類選擇符 - 減少層級關系,使查詢效率更高 - 盡量少的去使用后代選擇器,降低選擇器的權重值 - 不要放空的class - 多用繼承屬性,可以通過繼承避免對屬性重復使用
瀏覽器遇到語義解釋性的JS標簽嵌入文件,那么此時IE的下載過程會啟用單獨連接進行下載,并在下載后繼續進行解析。并且只有在JS文件解析完成并且加載完后才會繼續往下解析(瀏覽器阻塞)
在當前作用域中,JavaScript代碼執行之前,瀏覽器首先會默認的把所有帶var和function聲明的變量進行提前的聲明或者定義(主要指的是ES6之前,由于ES6引了let和const所以會存在不同)
JS代碼在逐行解析代碼的時候,變量賦值表達式是可以修改預解析的值。但如果有多個表達式對相同的變量多次賦值,那么除過函數聲明不能修改上次的賦值,變量賦值和函數表達式都可以修改這個變量的值
整個渲染的過程大致上可以概述為
- 用戶輸入網址,服務器返回html文檔
- 瀏覽器開始解析HTML文檔
- 瀏覽器解析文檔過程中解析到CSS或者JS標簽嵌入文件,這時候瀏覽器優先解析標簽嵌入文件,待標簽嵌入文件解析完成并執行完成后在繼續解析HTML文檔
- 瀏覽器將解析好的DOM進行繪制,在瀏覽器中繪制出來
https://segmentfault.com/a/1190000016253407
https://www.jianshu.com/p/b41f1258c044
覽器輸入URL到頁面渲染完成,這個過程大致可分為兩個階段:網絡通信和頁面渲染。
互聯網內各網絡間設備的通信遵循TCP/IP協議,利用TCP/IP協議進行網絡通信時,會通過分層與對方通信。數據傳輸的過程:由應用層產生數據后,經過傳輸層的分段處理(添加TCP或UDP包頭)、網絡層(添加IP地址信息)、數據鏈路層(封裝成MAC幀)、物理層傳輸電信號。
??
瀏覽器可以分為兩部分:shell和瀏覽器內核,shell是外殼,如工具欄,菜單等,內核是根本,是基于標記語言顯示的程序或模塊。
瀏覽器內核分為兩部分:渲染引擎和JS引擎。
渲染引擎主要負責解析瀏覽器所呈現的內容,比如HTML,CSS。 渲染引擎的主要流程
始解析 HTML 文檔,并將各標記逐個轉化成“內容樹”上的 DOM 節點。同時也會解析外部 CSS 文件以及樣式元素中的樣式數據。HTML 中這些帶有視覺指令的樣式信息將用于創建另一個樹結構:呈現樹。呈現樹包含多個帶有視覺屬性(如顏色和尺寸)的矩形。這些矩形的排列順序就是它們將在屏幕上顯示的順序。
呈現樹構建完畢之后,進入“布局”處理階段,也就是為每個節點分配一個應出現在屏幕上的確切坐標。下一個階段是繪制 - 呈現引擎會遍歷呈現樹,由用戶界面后端層將每個節點繪制出來。
需要著重指出的是,這是一個漸進的過程。為達到更好的用戶體驗,呈現引擎會力求盡快將內容顯示在屏幕上。它不必等到整個 HTML 文檔解析完畢之后,就會開始構建呈現樹和設置布局。在不斷接收和處理來自網絡的其余內容的同時,呈現引擎會將部分內容解析并顯示出來。 Webkit 渲染引擎主流程如下圖:
Gecko渲染引擎如下圖:
1、用戶界面。包括地址欄、前進/后退按鈕、書簽菜單等。除了瀏覽器主窗口顯示的您請求的頁面外,其他顯示的各個部分都屬于用戶界面。
2、瀏覽器引擎。在用戶界面和呈現引擎之間傳送指令。
3、呈現引擎。負責顯示請求的內容。如果請求的內容是 HTML,它就負責解析 HTML 和 CSS 內容,并將解析后的內容顯示在屏幕上。
4、用戶界面后端。用于繪制基本的窗口小部件,比如組合框和窗口。其公開了與平臺無關的通用接口,而在底層使用操作系統的用戶界面方法。
5、JavaScript 解釋器。用于解析和執行 JavaScript 代碼。
6、數據存儲。這是持久層。瀏覽器需要在硬盤上保存各種數據,例如 Cookie。新的 HTML 規范 (HTML5) 定義了“網絡數據庫”,這是一個完整(但是輕便)的瀏覽器內數據庫。
7、網絡。用于網絡調用,比如 HTTP 請求。其接口與平臺無關,并為所有平臺提供底層實現
關于DOM解析有如下HTML片段
關于CSS解析
html代碼:
css代碼:
解析成CSS tree
注意:CSS遍歷DOM,一層層找到對應的渲染規則是十分復雜的過程,這也是我們經常要求盡量精簡DOM結構,減少CSS嵌套層級的原因。CSS渲染流程
1、計算CSS屬性; 2、構建Render Tree; 3、Layout,進行定位,元素的坐標及尺寸,將元素放到指定位置; 4、繪制注意:圖中有兩種箭頭,一種是指向流程自身的,表示“回流”,即修改某個屬性會導致頁面進行重新渲染,一種的指向外部的,表示“重繪”,即修改某個屬性不會影響整個頁面布局。
這是前端經常會提到的兩個概念。 重繪:Repaint,可以理解為頁面局部某個元素要進行重新繪制,比如修改元素的背景顏色,但是幾何尺寸并不會變; 回流:Reflow,可以理解為頁面整個重新繪制,比如修改元素的尺寸,往往會導致整個render tree要進行重新計算,reflow是從html標簽開始自上而下一次重新計算元素尺寸,重新布局。 通過兩者概念區別明顯得知,回流要比重繪的成本大得多,我們應該盡量減少回流操作,減少頁面性能消耗。
(1)引起回流的方法或操作:
任何會改變元素幾何信息(元素的位置和尺寸大小)的操作,都會觸發回流。
(2)常見引起重繪屬性和方法減少reflow/repaint
4.盡可能的修改層級比較低的DOM。當然,改變層級比較底的DOM有可能會造成大面積的reflow,但是也可能影響范圍很小。
5.千萬不要使用table布局。因為可能很小的一個小改動會造成整個table的重新布局。
*請認真填寫需求信息,我們會在24小時內與您取得聯系。