咱們假設HTTP響應後HTML和CSS、JavaScript文件已經齊備了,此時瀏覽器會怎麼作呢?當前HTTP響應瀏覽器的普適渲染方式:
首先,瀏覽器會根據HTML文件生成DOM樹,載入CSS文件構建CSS Object Model。而後,在DOM樹和CSS Object Model上創建渲染樹(render tree):渲染樹就是渲染時用到的樹。渲染樹其實就是DOM樹和CSS的組合,和DOM樹相同的是每一個HTML標籤對應一個渲染樹節點,不一樣的是,文本節點比較特殊,每一行文本對應一個渲染樹節點,而且,因爲渲染樹識別CSS,<head>標籤以及設置爲{display: none}的標籤不在DOM樹上。除此以外,渲染樹上的每一個節點該是什麼樣式也已經計算出來了,此時就涉及CSS選擇器的優先級了:瀏覽器默認樣式<外部樣式表<style內部樣式表,同同樣式表內部又有#id > .class > tagName > a:hover,important的樣式優先級最高。最後,渲染樹創建以後,就能夠在屏幕上開始繪製(paint)節點。javascript
固然這僅僅是第一次繪製,實際中會有交互行爲,所以頁面結構以及CSS會隨時變化,這就涉及到重繪(repaint)和迴流(reflow)。迴流是指渲染文檔的結構被改變了,此時要從新佈局了,致使迴流的操做包括:DOM元素的刪改、表單或文本內容變化、CSS屬性的更改或從新計算、修改class屬性、瀏覽器窗口變化(滾動或縮放)、僞類激活。重繪是指元素的樣式改變不影響文檔流總體結構時,渲染樹結構也就沒有變化,所以僅僅是從新顯示樣式。重繪的代價是比較小的。注意,這並非說樣式改變不會致使迴流,只是特定樣式(background-color, color, visibility)改變纔不會致使迴流。第二個須要注意的點是,迴流必定須要重繪,可是重繪卻不須要回流,我發現一些文章沒搞清順序。php
迴流以及重繪會形成沒必要要的開銷,這是瀏覽器要優化的問題之一,罪魁禍首就是JavaScript代碼執行時會改變DOM樹和CSS樣式,所以常見作法是緩存JavaScript操做,而後經過一次迴流或重繪解決幾個操做的問題,固然也能夠人爲改變這一瀏覽器自主行爲,方法就是經過獲取元素屬性迫使瀏覽器當即重繪和迴流,爲何會這樣呢?假設某一操做要讀取元素的height屬性,此時瀏覽器已經緩存了幾個操做,這些操做可能會改變height值,而此時瀏覽器要返回當前的精確值,就不得不當即執行迴流,不然是得不到這個精確值的。css
// 最終只有一次重繪和迴流被觸發 var $body = $('body'); $body.css('padding', '1px'); // 觸發重繪與迴流 $body.css('color', 'red'); // 觸發重繪 $body.css('margin', '2px'); // 觸發重繪與迴流 //兩次迴流 var $body = $('body'); $body.css('padding', '1px'); $body.css('padding'); // 此處觸發強制迴流 $body.css('color', 'red'); $body.css('margin', '2px');
另外一優化就是瀏覽器認爲position爲absolute或fixed的元素更改只會影響其自己和子元素,而static的元素變化則會影響以後的全部元素,具體請看https://segmentfault.com/a/11...,緣由在於absolute和fixed認爲元素從文檔流中清除了,怎麼操做是內部的事。java
理解瀏覽器重繪以及迴流的主要目的是爲了優化開發,或許這些開銷對瀏覽器不重要,可是瞭解了這些對一些優化實踐就會有更深刻的瞭解。
好比:批量的DOM操做能夠經過複製DOM節點,而後在複製的節點上進行一系列操做,再替換原節點便可,由於節點只要不加到DOM樹上就不影響渲染樹,因此怎麼折騰都沒事,最後添加以後只執行一次迴流。這就是「用innerHTML代替DOM操做,減小DOM操做次數,優化javascript性能。」的緣由。
樣式計算也是一樣的道理。(1)不要逐個修改CSS中的樣式,每次修改可能都是一次重繪或迴流,因此最好是在原始CSS裏定義不一樣的class,經過改變class實現樣式轉換。(2)只對position爲absolue/fixed的元素設置動畫,由於這些元素不在文檔流中,怎麼動都不會致使迴流,只會重繪。(3)當須要設置的樣式不少時設置className而不是直接操做style。(4)避免使用CSS Expression(css表達式)又稱Dynamic properties(動態屬性)。segmentfault
http://www.phpied.com/renderi...
http://taligarsiel.com/Projec...瀏覽器