從輸入 URL 到頁面加載完成發生了什麼事
DNS解析
TCP鏈接
發送HTTP請求
服務器處理請求並返回HTTP報文
瀏覽器解析渲染頁面
瀏覽器應該有的功能
網絡;資源管理;網頁瀏覽;多頁面管理;插件與管理;帳戶和同步;安全機制;開發者工具
瀏覽器的主要功能總結起來就是一句話:
將用戶輸入的url轉變成可視化的圖像
瀏覽器的內核(渲染引擎)
在瀏覽器中有一個最重要的模塊,它主要的做用是將頁面轉變爲可視化的圖像結果。這個模塊就是瀏覽器內核,一般它也被稱爲渲染引擎。
IE----->Trident
Safari------>WebKit
Chrome;Opera----->Blink
Firefox------>Gecko
渲染引擎
一個渲染引擎主要包括:HTML解析器,CSS解析器,佈局layout模塊,javascript引擎,繪圖模塊
渲染過程
1.網頁URL到構建DOM樹的整個過程
1) 當用戶輸入URL的時候,Webkit調用資源加載器加載URL對應的網頁
2) 加載器依賴網絡模塊創建鏈接,發送請求並接收答覆
3) Webkit接收到各類網頁或者資源的數據,其中某些資源多是同步的或異步獲取的
4) 網頁被交給HTML解析器轉變一系列的詞語(Token)
5) 解析器根據詞語構建節點(node),造成DOM樹
6) 若是節點須要依賴於其餘資源,
例如js css 圖片 視頻等,調用資源加載器來加載他們,可是這些都是異步的,
不會阻礙dom樹的繼續建立;順序執行 併發加載
若是資源是css的話
調用CSS解析器解釋將CSS解釋成內部表示結構(CSSDOM)
若是資源是javascript的話
調用Javascript引擎解釋並執行,
7)阻塞
css阻塞
css 在head中經過link的形式引入會阻塞頁面的渲染
爲何?
避免閃屏現象
js阻塞
直接引入的js會阻塞頁面的渲染
爲何?
Javascript代碼可能會修改DOM樹的結構
8) 預解析
WebKit 和 Firefox 都進行了這項優化。在執行js腳本時,其餘線程會解析文檔的其他部分,找出並加載須要經過網絡加載的其餘資源。經過這種方式,資源能夠在並行鏈接上加載,從而提升整體速度。請注意,預解析器不會修改 DOM 樹,而是將這項工做交由主解析器處理;
預解析器只會解析外部資源(例如外部腳本、樣式表和圖片)的引用。
2.從DOM樹到可視化圖像
1) CSS文件被CSS解析器解釋成內部表示結構(CSSDOM)
2) CSS解析器工做完成以後,在DOM樹上附加解釋後的樣式信息,這就是RenderObject樹
3) RenderObject在建立的同時,Webkit會根據網頁的結構建立RenderLayer,同時構建一個繪圖上下文
4) 根據繪圖上下文生成最終的圖像(這一過程須要依賴圖形庫)
3.上面介紹的是一個完整的渲染過程,但現代網頁不少都是動態的,這意味着在渲染完成以後,因爲網頁的動畫或者用戶的交互,
瀏覽器其實一直在不停地重複執行渲染過程。(重繪重排),以上的數字表示的是基本順序,這不是嚴格一致的,
這個過程可能重複也可能交叉。瀏覽器是一個邊解析邊渲染的過程
css圖層
瀏覽器在渲染一個頁面時,會將頁面分爲不少個圖層,圖層有大有小,每一個圖層上有一個或多個節點。
在渲染DOM的時候,瀏覽器所作的工做其實是:
1. 獲取DOM後分割爲多個圖層
2. 對每一個圖層的節點計算樣式結果 (Recalculate style--樣式重計算)
3. 爲每一個節點生成圖形和位置 (Layout--重排,迴流)
4. 將每一個節點繪製填充到圖層位圖中 (Paint--重繪)
5. 圖層做爲紋理上傳至GPU
6. 符合多個圖層到頁面上生成最終屏幕圖像 (Composite Layers--圖層重組)
圖層建立的條件
Chrome中知足如下任意狀況就會建立圖層:
1. 擁有具備3D變換的CSS屬性
2. 使用加速視頻解碼的<video>節點
3. <canvas>節點
4. CSS3動畫的節點
5. 擁有CSS加速屬性的元素(will-change)
6. 元素有一個z-index較低且包含一個複合層的兄弟元素(換句話說就是該元素在複合層上面渲染)
重繪(Repaint)
重繪是一個元素外觀的改變所觸發的瀏覽器行爲,例如改變outline、背景色等屬性。瀏覽器會根據元素的新屬性從新繪製,
使元素呈現新的外觀。重繪不會帶來從新佈局,因此並不必定伴隨重排。
須要注意的是,若是圖層中某個元素須要重繪,那麼整個圖層都須要重繪。
好比一個圖層包含不少節點,其中有個gif圖,gif圖的每一幀,都會重回整個圖層的其餘節點,而後生成最終的圖層位圖。
因此這須要經過特殊的方式來強制gif圖屬於本身一個圖層(translateZ(0)或者translate3d(0,0,0)
CSS3的動畫也是同樣(好在絕大部分狀況瀏覽器本身會爲CSS3動畫的節點建立圖層)
重排(Reflow 迴流)
渲染對象在建立完成並添加到渲染樹時,並不包含位置和大小信息。計算這些值的過程稱爲佈局或重排
"重繪"不必定須要"重排",好比改變某個網頁元素的顏色,就只會觸發"重繪",不會觸發"重排",由於佈局沒有改變。
可是,"重排"必然致使"重繪",好比改變一個網頁元素的位置,就會同時觸發"重排"和"重繪",由於佈局改變了。
觸發重繪的屬性
* 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
觸發重排(迴流)的屬性
盒子模型相關屬性會觸發重佈局 定位屬性及浮動也會觸發重佈局: 改變節點內部文字結構也會觸發重佈局:
* 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
常見的觸發重排的操做
Reflow 的成本比 Repaint 的成本高得多的多。DOM Tree 裏的每一個結點都會有 reflow 方法,
一個結點的 reflow 頗有可能致使子結點,甚至父點以及同級結點的 reflow。在一些高性能的電腦上也許還沒什麼,
可是若是 reflow 發生在手機上,那麼這個過程是很是痛苦和耗電的。
因此,下面這些動做有很大可能會是成本比較高的。
當你增長、刪除、修改 DOM 結點時,會致使 Reflow , Repaint。
當你移動 DOM 的位置
當你修改 CSS 樣式的時候。
當你 Resize 窗口的時候(移動端沒有這個問題)
當你修改網頁的默認字體時。
獲取某些屬性時(width,height...)
注:display:none 會觸發 reflow,而 visibility:hidden 只會觸發 repaint,由於沒有發生位置變化。
優化
若是咱們須要使得動畫或其餘節點渲染的性能提升,須要作的就是減小瀏覽器在運行時所須要作的工做(減小1234中的步驟)
1. 計算須要被加載到節點上的樣式結果(Recalculate style--樣式重計算)
2. 爲每一個節點生成圖形和位置(Layout--迴流和重佈局)
3. 將每一個節點填充到圖層中(Paint Setup和Paint--重繪)
4. 組合圖層到頁面上(Composite Layers--圖層重組)
1.元素位置移動變換時儘可能使用CSS3的transform來代替對top left等的操做
變換(transform)和透明度(opacity)的改變僅僅影響圖層的組合
2.使用opacity來代替visibility
透明度居然不會觸發重繪?
透明度的改變時,GPU在繪畫時只是簡單的下降以前已經畫好的紋理的alpha值來達到效果,並不須要總體的重繪。
不過這個前提是這個被修改opacity自己必須是一個圖層,若是圖層下還有其餘節點,GPU也會將他們透明化
3.不要使用table佈局
4.將屢次改變樣式屬性的操做合併成一次操做
不要一條一條地修改DOM的樣式,預先定義好class,而後修改DOM的className
5.將DOM離線後再修改
因爲display屬性爲none的元素不在渲染樹中,對隱藏的元素操做不會引起其餘元素的重排。
若是要對一個元素進行復雜的操做時,能夠先隱藏它,操做完成後再顯示。這樣只在隱藏和顯示時觸發2次重排。
6.利用文檔碎片
7.不要把某些DOM節點的屬性值放在一個循環裏當成循環的變量
當你請求向瀏覽器請求一些 style信息的時候,就會讓瀏覽器flush隊列,好比:
1. offsetTop, offsetLeft, offsetWidth, offsetHeight
2. scrollTop/Left/Width/Height
3. clientTop/Left/Width/Height
4. width,height
當你請求上面的一些屬性的時候,瀏覽器爲了給你最精確的值,須要flush隊列,
由於隊列中可能會有影響到這些值的操做。即便你獲取元素的佈局和樣式信息跟最近發生或改變的佈局信息無關,
瀏覽器都會強行刷新渲染隊列。
8.動畫實現過程當中,啓用GPU硬件加速
9.爲動畫元素新建圖層,提升動畫元素的z-index