輸入完網址按下回車,到看到網頁這個過程中發生了什麼。
無意中看到寒冬關於前端的九個問題,細細想來我也只是對第一、二、九問有所瞭解,正好也趁著這個機會梳理一下自己的知識體系。由於本人對http協議以及dns對url的解析問題並不瞭解,所以這裡之探討url請求載入到瀏覽器端時,瀏覽器對html的解析到呈現過程,後來經過幾位道友分享,整理了一下url解析的過程,如下:
- 使用者輸入url地址,瀏覽器根據域名尋找IP地址
- 瀏覽器向伺服器傳送http請求,如果伺服器段返回以301之類的重定向,瀏覽器根據相應頭中的location再次傳送請求
- 伺服器端接受請求,處理請求生成html程式碼,返回給瀏覽器,這時的html頁面程式碼可能是經過壓縮的
- 瀏覽器接收伺服器響應結果,如果有壓縮則首先進行解壓處理,緊接著就是頁面解析渲染
解析渲染該過程主要分為以下步驟:
- 解析HTML
- 構建DOM樹
- DOM樹與CSS樣式進行附著構造呈現樹
- 佈局
- 繪製
解析與構建DOM樹
前兩步我們放在一起討論,瀏覽器的實際工作也是將他們放在一起進行的。對於HTML瀏覽器有專門的html解析器來解析HTML,並在解析的過程中構建DOM樹。在這裡我們討論兩種DOM元素的解析,即樣式(link、style)與指令碼檔案(script)。由於瀏覽器採用自上而下的方式解析,在遇到這兩種元素時都會阻塞瀏覽器的解析,直到外部資源載入並解析或執行完畢後才會繼續向下解析html。對於樣式與指令碼的先後順序同樣也會影響到瀏覽器的解析過程,究其原因主要在於:script指令碼執行過程中可能會修改html介面(如document.write函式);DOM節點的CSS樣式會影響js的執行結果。在我的測試中得到以下四條結論:
1)外部樣式會阻塞後續指令碼執行,直到外部樣式載入並解析完畢。
2)外部樣式不會阻塞後續外部指令碼的載入,但會阻塞外部指令碼的執行。
test
主頁程式碼
var loadTime = document.createElement('div');
loadTime.innerText = document.currentScript.src + ' executed @ ' + window.performance.now();
loadTime.style.color = 'blue';
document.body.appendChild(loadTime);
從瀑布圖中我們可以看到,外部指令碼與外部樣式是並行載入,但直到外部樣式載入完畢,外部指令碼才開始執行
3)如果後續外部指令碼含有async屬性(IE下為defer),則外部樣式不會阻塞該指令碼的載入與執行
test
從瀑布圖中可以看到外部指令碼的載入與執行並不受link的阻塞
4)對於動態建立的link標籤不會阻塞其後動態建立的script的載入與執行,不管script標籤是否具有async屬性,但對於其他非動態建立的script,以上三條結論仍適用
test
這是最終頁面結構
通過瀑布圖與頁面結果可以看到動態建立的外部指令碼並未受link的阻塞。
link或style標籤都會被解析成DOM節點。瀏覽器對於樣式表還會生成CSSStyleSheet物件(C++程式碼),他整合子CSSStyle,指標是樣式表物件而不管該物件來自於Style還是link。該物件主要包含以下幾個重要屬性和方法
- CSSRules 即css樣式程式碼
- type 表示樣式表型別的字串。對CSS樣式表而言,這個字串是“type/css”。
- href 通過link生成的為樣式連結,否則為undefined
- insertRule(rule,index):向cssRules集合中指定的位置插入rule字串。IE不支援這個方法,但支援一個類似的addRule()方法。
- deleteRule(index):刪除cssRules集合中指定的位置的規則。IE不支援這個方法,但支援一個類似的removeRule()方法。
文件中對於所有的樣式表集合可以通過document.styleSheets來訪問。同時對於style或link DOM元素可以通過element.sheet來訪問CSSStyleSheet物件,IE中則通過element.styleSheet來訪問。
html解析完畢,DOM樹建立完成後DOMContentLoaded事件即觸發,這時候可以用過script來操作DOM節點。
構建呈現樹
HTML解析完畢後,開始構建呈現樹RenderTree,這一步的主要工作在於將css樣式應用到DOM節點上,WebKit核心將這一過程稱為附著,其他瀏覽器有不同的概念。對前端工程師而言這個過程會涉及到CSS層疊問題。
首先將根據樣式重要性排序,由低到高依次為:
-
- 瀏覽器宣告
- 使用者普通宣告
- 作者普通宣告
- 作者重要宣告
- 使用者重要宣告
對於同一重要級別,則是根據CSS選擇符的特指度來判定優先順序;一條樣式宣告的特指度由以下四個部分決定:S-I-C-E
-
- 宣告來自內聯的style屬性則 S+1;
- 宣告中含有id屬性則 I+1;
- 宣告中含有類、偽類、屬性選擇器則 C+1;
- 生命中含有元素、偽元素選擇器則 E+1;
特指度的比較類似於兩個字串之間比較大小。
呈現樹的每一個節點即為與其相對應的DOM節點的CSS框,框的型別與DOM節點的display屬性有關,block元素生成block框,inline元素生成inline框。每一個呈現樹節點都有與之相對應的DOM節點,但DOM節點不一定有與之相對應的呈現樹節點,比如display屬性為none的DOM節點,而且呈現樹節點在呈現樹中的位置與他們在DOM樹中的位置不一定相同,比如float與絕對定位元素。
下圖為呈現樹與其相對應的DOM樹節點
佈局
呈現樹構造完成後瀏覽器便進行佈局處理,及計算每個呈現樹節點的大小和位置資訊。有道友可能要問,前面已將樣式附著到DOM節點上,不是已經有了樣式資訊為何還要計算大小。這裡可以這樣理解,以上包含大小的樣式資訊只是存在記憶體裡,並沒有實際使用,瀏覽器要根據視窗的實際大小以及注塑模具來處理呈現樹節點的實際顯示大小和位置,比如對於margin為auto的處理。
佈局是一個遞迴過程,從跟呈現節點開始,遞迴遍歷子節點,計算集合幾何資訊。具體過程還是比較複雜偶也不甚瞭解,道友們還是查閱其他資料吧。
繪製
佈局完成後,便是將呈現樹繪製出來顯示在螢幕上。對於每一個呈現樹節點來說,主要繪製順序如下:
- 背景顏色
- 背景圖片
- 邊框
- 子呈現樹節點
- 輪廓
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29443697/viewspace-1299375/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 終極解密輸入網址按回車到底發生了什麼解密
- 在瀏覽器位址列輸入url到按下回車發生了什麼?瀏覽器
- 從你輸入網址,到看到網頁——詳解中間發生的過程網頁
- 從瀏覽器輸入網址回車到看到頁面過程到底經歷了什麼?瀏覽器
- 在瀏覽器輸入一個網址回車後,發生了什麼?瀏覽器
- 當我們遊覽網頁的時候, 在輸入連結點選回車之後到看到新網頁這中間究竟發生了什麼?網頁
- 從輸入url到顯示網頁發生了什麼網頁
- 一個頁面從輸入 URL 到頁面載入顯示完成,這個過程中都發生了什麼
- 一個頁面從輸入 URL 到頁面載入顯示完成,這個過程中都發生了什麼?
- 網紅面試題:從輸入 url 到看到頁面發生了什麼面試題
- 在瀏覽器中輸入一個URL,按下回車會發生什麼?瀏覽器
- 當你在瀏覽器輸入一個網址,回車後究竟發生了什麼?瀏覽器
- 溫故知新-輸入網址-顯示網頁-到底到底到底到底-發生了什麼?網頁
- 當你在瀏覽器中輸入Google.com並且按下回車之後發生了什麼?瀏覽器Go
- 瀏覽器從輸入網址到顯示都發生了些什麼?瀏覽器
- 終極版:從開機聯網到輸入一個網址期間都發生了什麼?
- 從輸入URL到頁面載入完成的過程中都發生了什麼?
- 在瀏覽器裡輸入網址,按下Enter鍵之後發生了什麼瀏覽器
- 從輸入 URL 到頁面載入完成的過程中都發生了什麼事情?
- (詳解)從瀏覽器輸入 URL 到頁面展示過程發生了什麼?瀏覽器
- 從輸入 URL 到瀏覽器接收的過程中發生了什麼事情?瀏覽器
- 從輸入URL到頁面載入到底發生了什麼
- 從在瀏覽器中輸 URL 網址之後到底發生了什麼?瀏覽器
- 史上最詳細的經典面試題 從輸入URL到看到頁面發生了什麼?面試題
- 從輸入 URL 到瀏覽器接收的過程中發生了什麼事情----轉載瀏覽器
- 一個頁面從輸入URL到載入顯示完成,發生了什麼?
- 從輸入一個網址到瀏覽器顯示頁面的全過程詳細分析瀏覽器
- 在瀏覽器輸入一個網址到得到一個頁面的過程描述瀏覽器
- 從輸入頁面地址到展示頁面資訊都發生了些什麼?
- 網路程式設計(四):輸入一個URL後發生了什麼?程式設計
- 使用者輸入一個網址到頁面展示內容的這段時間內,瀏覽器和伺服器都發生了生麼事情?瀏覽器伺服器
- 經典面試題:當你輸入一個網址後回車,實際會發生什麼?面試題
- 【瀏覽器】從URL輸入到頁面展現到底發生了什麼?瀏覽器
- 從輸入url到傳送請求發生了什麼
- 一個網頁從輸入地址回車,到完整展示網頁內容這段時間裡,做了哪些工作網頁
- 使用者輸入網址到顯示對應的⻚面解析全過程
- RAG實戰4-RAG過程中發生了什麼?
- 瀏覽器位址列輸入url回車之後發生了些什麼瀏覽器