主要過程:css
1. 用戶輸入網址(假設是個 HTML 頁面,第一次訪問,無緩存狀況),瀏覽器向服務器發出HTTP請求,服務器返回 HTML 文件; (善用緩存,減小HTTP請求,減輕服務器壓力)html
2. 瀏覽器載入 HTML 代碼,發現 <head> 內有一個 <link> 引用外部 CSS 文件,則瀏覽器當即發送CSS文件請求,獲取瀏覽器返回的CSS文件; (CSS文件合併,減小HTTP請求)express
3. 瀏覽器繼續載入 HTML 中 <body> 部分的代碼,而且 CSS 文件已經拿到手了,能夠開始渲染頁面了; (CSS文件須要放置最上面,避免網頁從新渲染)瀏覽器
4. 瀏覽器在代碼中發現一個 <img> 標籤引用了一張圖片,向服務器發出請求。此時瀏覽器不會等到圖片下載完,而是繼續渲染後面的代碼; (圖片文件合併,減小HTTP請求)緩存
5. 服務器返回圖片文件,因爲圖片佔用了必定面積,影響了後面段落的排布,所以瀏覽器須要回過頭來從新渲染這部分代碼; (最好圖片都設置尺寸,避免從新渲染)服務器
6. 瀏覽器發現了一個包含一行 JavaScript 代碼的 <script> 標籤,會當即運行該js代碼; (script最好放置頁面最下面) 佈局
7. js腳本執行了語句,它令瀏覽器隱藏掉代碼中的某個 <div>,忽然就少了一個元素,瀏覽器不得不從新渲染這部分代碼; (頁面初始化樣式不要使用js控制) 性能
8. 終於等到了 </html> 的到來,瀏覽器淚流滿面……動畫
9. 等等,還沒完,用戶點了一下界面中的「換膚」按鈕,JavaScript 讓瀏覽器換了一下 <link> 標籤的 CSS 路徑;spa
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發生:
-
- 改變窗囗大小
- 改變文字大小
- 添加/刪除樣式表
- 內容的改變,如用戶在輸入框中敲字
- 激活僞類,如:hover (IE裏是一個兄弟結點的僞類被激活)
- 操做class屬性
- 腳本操做DOM
- 計算offsetWidth和offsetHeight
- 設置style屬性
reflow是不可避免的,只能將reflow對性能的影響減到最小。
-
- 儘量限制reflow的影響範圍。須要改變元素的樣式,不要經過父級元素影響子元素。最好直接加在子元素上。
- 經過設置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。