[轉] 瀏覽器渲染頁面的過程

 當了解web訪問原理後,與前端工程師或頁面重構師工作更爲關係密切的應該是瀏覽器,WEB 頁面運行在各種各樣的瀏覽器當中,瀏覽器載入、渲染頁面的速度直接影響着用戶體驗, 特別是瀏覽器渲染頁面的原理,頁面渲染就是瀏覽器將 HTML 代碼根據 CSS 定義的規則顯示在瀏覽器窗口中的這個過程,理解了原理就更會容易理解前端優化的一些準則。

          

           主要過程:(主要參考文章:http://www.webskys.com/artilc/228.html

           1. 用戶輸入網址(假設是個 HTML 頁面,第一次訪問,無緩存情況),瀏覽器向服務器發出HTTP請求,服務器返回 HTML 文件; (善用緩存,減少HTTP請求,減輕服務器壓力)

           2. 瀏覽器載入 HTML 代碼,發現 <head> 內有一個 <link> 引用外部 CSS 文件,則瀏覽器立即發送CSS文件請求,獲取瀏覽器返回的CSS文件;  (CSS文件合併,減少HTTP請求)

           3. 瀏覽器繼續載入 HTML 中 <body> 部分的代碼,並且 CSS 文件已經拿到手了,可以開始渲染頁面了;                              (CSS文件需要放置最上面,避免網頁重新渲染)

           4. 瀏覽器在代碼中發現一個 <img> 標籤引用了一張圖片,向服務器發出請求此時瀏覽器不會等到圖片下載完,而是繼續渲染後面的代碼;    (圖片文件合併,減少HTTP請求)

           5. 服務器返回圖片文件,由於圖片佔用了一定面積,影響了後面段落的排布,因此瀏覽器需要回過頭來重新渲染這部分代碼;   (最好圖片都設置尺寸,避免重新渲染)

           6. 瀏覽器發現了一個包含一行 JavaScript 代碼的 <script> 標籤,會立即運行該js代碼;              (script最好放置頁面最下面)                   

           7. js腳本執行了語句,它令瀏覽器隱藏掉代碼中的某個 <div>,突然就少了一個元素,瀏覽器不得不重新渲染這部分代碼;   (頁面初始化樣式不要使用js控制)   

           8. 終於等到了 </html> 的到來,瀏覽器淚流滿面……

           9. 等等,還沒完,用戶點了一下界面中的“換膚”按鈕,JavaScript 讓瀏覽器換了一下 <link> 標籤的 CSS 路徑;

          10. 瀏覽器召集了在座的各位 <div><span><ul><li> 們,“大夥兒收拾收拾行李,咱得重新來過……”,瀏覽器向服務器請求了新的CSS文件,重新渲染頁面。

          

           瀏覽器每天就這麼來來回回跑着,要知道不同的人寫出來的 HTML 和 CSS 代碼質量參差不齊,說不定哪天跑着跑着就掛掉了。

           好在這個世界還有這麼一羣人——頁面重構工程師,平時挺不起眼,也就幫視覺設計師們切切圖啊改改字,其實背地裏還是幹了不少實事的。

 

          影響頁面渲染速度主要有:reflow(迴流)和repaint(重繪) 

 

          reflow(迴流)

           說到頁面爲什麼會慢?那是因爲瀏覽器要花時間、花精力去渲染,尤其是當它發現某個部分發生了點變化影響了佈局,需要倒回去重新渲染, 該過程稱爲reflow(迴流)。

           reflow 幾乎是無法避免的。現在界面上流行的一些效果,比如樹狀目錄的摺疊、展開(實質上是元素的顯 示與隱藏)等,都將引起瀏覽器的 reflow。鼠標滑過、點擊……只要這些行爲引起了頁面上某些元素的佔位面積、定位方式、邊距等屬性的變化,都會引起它內部、周圍甚至整個頁面的重新渲 染。通常我們都無法預估瀏覽器到底會 reflow 哪一部分的代碼,它們都彼此相互影響着。

             repaint(重繪)

               如果只是改變某個元素的背景色、文 字顏色、邊框顏色等等不影響它周圍或內部佈局的屬性,將只會引起瀏覽器 repaint(重繪)。

            repaint 的速度明顯快於 reflow(在IE下需要換一下說法,reflow 要比 repaint 更緩慢)。

 

              儘量避免reflow(迴流)                

               reflow(迴流)是導致DOM腳本執行低效的關鍵因素之一。頁面上任何一個結點觸發reflow,都會導致它的子結點及祖先結點重新渲染。

            在哪些情況下會導致reflow發生:

    1. 改變窗囗大小
    2. 改變文字大小
    3. 添加/刪除樣式表
    4. 內容的改變,如用戶在輸入框中敲字
    5. 激活僞類,如:hover (IE裏是一個兄弟結點的僞類被激活)
    6. 操作class屬性
    7. 腳本操作DOM
    8. 計算offsetWidth和offsetHeight
    9. 設置style屬性

            reflow是不可避免的,只能將reflow對性能的影響減到最小。

    1. 儘可能限制reflow的影響範圍。需要改變元素的樣式,不要通過父級元素影響子元素。最好直接加在子元素上。
    2. 通過設置style屬性改變結點樣式的話,每設置一次都會導致一次reflow。所以最好通過設置class的方式。

 

  • 實現元素的動畫,它的position屬性應當設爲fixed或absolute,這樣不會影響其它元素的佈局。
  • 權衡速度的平滑。比如實現一個動畫,以1個像素爲單位移動這樣最平滑,但reflow就會過於頻繁,CPU很快就會被完全佔用。如果以3個像素爲單位移動就會好很多。
  • 不要用tables佈局的另一個原因就是tables中某個元素一旦觸發reflow就會導致table裏所有的其它元素reflow。在適合用table的場合,可以設置table-layout爲auto或fixed,這樣可以讓table一行一行的渲染,這種做法也是爲了限制reflow的影響範圍。
  • 很多情況下都會觸發reflow,如果css裏有expression,每次都會重新計算一遍。
  • 減少不必要的 DOM 層級(DOM depth)。改變 DOM 樹中的一級會導致所有層級的改變,上至根部,下至被改變節點的子節點。這導致大量時間耗費在執行 reflow 上面。
  • 避免不必要的複雜的 CSS 選擇器,尤其是後代選擇器(descendant selectors),因爲爲了匹配選擇器將耗費更多的 CPU。

 

 轉自:http://www.cnblogs.com/Peng2014/p/4687218.html

  深入學習:現代瀏覽器工作原理

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章