頁面渲染深刻解析

基本渲染過程

用戶請求的資源經過瀏覽器的網絡層到達渲染引擎後,渲染工做開始。每次渲染文檔一般不會超過8K的數據塊,其中基礎的渲染過程以下圖所示:       javascript

第一步:渲染引擎首先解析HTML文檔,轉換爲一棵DOM樹;css

第二步:接下來無論是內聯式,外聯式仍是嵌入式引入的CSS樣式也會被解析,渲染出另 外一棵用於渲染DOM樹的樹-渲染樹(render tree) ,渲染樹包含帶有顏色,尺寸等顯示屬性的矩形,這些矩形的順序與顯示順序一致;html

第三步:而後就是對渲染樹的每一個節點進行佈局處理,肯定其在屏幕上的顯示位置;java

第四步: 就是遍歷渲染樹並用UI後端層將每個節點繪製出來。web

以上步驟是一個漸進的過程,爲了提升用戶體驗,渲染引擎試圖儘量快的把結果顯示給最終用戶。它不會等到全部HTML都被解析完才建立並佈局渲染樹。它會在從網絡層獲取文檔內容的同時把已經接收到的局部內容先展現出來。後端

不一樣渲染引擎具體不一樣的渲染流程

上面只是介紹了渲染引擎通常的處理流程,針對不一樣的渲染引擎具體步驟可能有所不一樣,就拿常見的webkit跟gecko來講吧。瀏覽器

首先是webkit的詳細渲染流程:緩存

火狐等瀏覽器的gecko渲染流程:服務器

從上面兩幅圖能夠看出,儘管二者使用了不一樣的「專業術語」,可是從圖上能夠看出,二者的渲染過程可謂大同小異,正是於此,咱們能夠再把具體的過程統一分離出來。網絡

優化css部分

那麼如何寫出高效的css代碼呢?在這個問題以前咱們先來看看那些不高效的代碼的書寫方式:

       a、使用通配符

body * {...}
hide-scrollbars * {...}

b、 用標籤作關鍵選擇符

ul li a {...} 
#footer h3 {...} 
* html #atticPromo ul li a {...}

c、多此一舉的寫法

ul#top_blue_nav {...} form#UserLogin {...}

d、 給非鏈接標籤添加 :hover 僞類,這會對用了strict doctype的頁面在IE7和IE8下變的很慢。

h3:hover {...} .foo:hover {...} #foo:hover {...} div.faa :hover {...}

爲何不高效呢?

首先弄清瀏覽器解析html代碼的過程:構建一個dom樹,頁面要顯示的各元素都會建立到這個dom樹當中。每當一個新元素加入到這個dom樹當中,瀏覽器便會經過css引擎查遍css樣式表,找到符合該元素的樣式規則應用到這個元素上。css引擎查找樣式表,對每條規則都按從右到左的順序去匹配。

瞭解過程後,咱們能夠看出能夠從兩方面優化咱們的css代碼:

1,定義的css樣式規則條數越少越好,因此趕忙刪除css文件中沒必要要的樣式定 義;

2,優化每條規則的選擇符書寫方式,儘可能讓css引擎一看就知道這個規則是否須要應用到當前這個元素上,讓引擎少走沒必要要的彎路。

優化建議:

a, 避免使用通配符;

b, 讓css引擎快速辨別該規則是否適用於當前元素:多用id或class選擇符,少用標籤選擇符;

c, 不要多此一舉把id和class或標籤和class等連着寫;

d, 儘可能避免使用後代選擇符,去除沒必要要的祖先元素,能夠考慮使用class選擇符來替換後代選擇符;

/*給無序和有序的li定義不一樣顏色,你可能會這樣寫:*/ 
ul li {color: blue;} 
ol li {color: red;} 
/*給li添加class,這樣定義效率會更高:*/ 
.unordered-list-item {color: blue;} 
.ordered-list-item {color: red;}

e, 避免給非鏈接標籤添加 :hover 僞類。

接着還有下面幾個也是須要注意的:

一,避免使用css表達式

css表達式僅在ie瀏覽器下才起做用,微軟已在ie8後不推薦使用,由於它會嚴重影響頁面性能:任什麼時候候,無論任何一個事件被觸發,例如窗口的 resize 事件,鼠標的移動等等,css表達式都會從新計算一遍。

二,把css文件放在頁面頂部

把外聯或內聯樣式表放在body部分會影響頁面渲染的速度,由於瀏覽器只有在全部樣式表下載完成後纔會繼續下載頁面其餘內容。另外,內聯樣式表(放在<style>內的樣式)有可能會引發頁面從新渲染或顯示隱藏頁面中的某些元素,建議不要使用內聯樣式表。

三,指定頁面圖片的尺寸

指定頁面圖片尺寸,要符合圖片的真實尺寸(不要經過指定尺寸來縮放圖片),能夠避免尺寸改變致使的頁面結構效果的變化,因此對加快頁面渲染速度有益。

四,頁面頭部標明文檔編碼

HTML文檔是以包含文檔編碼信息的數據流方式在網絡間傳輸。頁面的編碼信息通常會在HTTP響應的頭部信息或在文檔內的HTML標記中指明。客戶端瀏覽器只有在肯定了頁面編碼後才能正確的渲染頁面, 因此在繪製頁面或執行任何的javascript代碼前,大部分的瀏覽器(ie六、ie七、ie8除外)都會緩衝必定字節的數據來從中查找編碼信息,不一樣 的瀏覽器當中預緩衝的字節數是不同的。若是瀏覽器在接收到了設定的預緩衝數據量後尚未找到頁面的編碼信息,便會根據各自指定的默認編碼開始渲染頁面,若是這時再獲取到頁面編碼信息,而又跟如今所用編碼不一致,那整個頁面就得從新渲染,某些狀況下甚至須要從新獲取數據。因此,對於大小超過1KB的頁面(根據在各瀏覽器的測試狀況,預緩衝數據量最多的也就1KB)應當儘早標明編碼信息。

瀏覽器加載和渲染html的順序(摘抄)

1.瀏覽器加載和渲染html的順序

一、IE下載的順序是從上到下,渲染的順序也是從上到下,下載和渲染是同時進行的。

二、在渲染到頁面的某一部分時,其上面的全部部分都已經下載完成(並非說全部相關聯的元素都已經下載完)

三、若是遇到語義解釋性的標籤嵌入文件(JS腳本,CSS樣式),那麼此時IE的下載過程會啓用單獨鏈接進行下載。

四、而且在下載後進行解析,解析過程當中,中止頁面全部往下元素的下載。阻塞加載

五、樣式表在下載完成後,將和之前下載的全部樣式表一塊兒進行解析,解析完成後,將對此前全部元素(含之前已經渲染的)從新進行渲染。

六、JS、CSS中若有重定義,後定義函數將覆蓋前定義函數

2. JS的加載

2.1 不能並行下載和解析(阻塞下載)

2.2 當引用了JS的時候,瀏覽器發送1個js request就會一直等待該request的返回。由於瀏覽器須要1個穩定的DOM樹結構,而JS中頗有可能有代碼直接改變了DOM樹結構,好比使用 document.write 或 appendChild,甚至是直接使用的location.href進行跳轉,瀏覽器爲了防止出現JS修改DOM樹,須要從新構建DOM樹的狀況,因此 就會阻塞其餘的下載和呈現.

3.如何加快HTML頁面加載速度

1,頁面減肥 

頁面的肥瘦是影響加載速度最重要的因素 

刪除沒必要要的空格、註釋 

將inline的script和css移到外部文件 

可使用HTML Tidy來給HTML減肥,還可使用一些壓縮工具來給JavaScript減肥 

2,減小文件數量 

減小頁面上引用的文件數量能夠減小HTTP鏈接數 

許多JavaScript、CSS文件能夠合併最好合並,人家財幫子都把本身的JavaScript. functions和Prototype.js合併到一個base.js文件裏去了 

3,減小域名查詢 

DNS查詢和解析域名也是消耗時間的,因此要減小對外部JavaScript、CSS、圖片等資源的引用,不一樣域名的使用越少越好 

4,緩存重用數據 

使用緩存吧 

5,優化頁面元素加載順序 

首先加載頁面最初顯示的內容和與之相關的JavaScript和CSS 

而後加載DHTML相關的東西 

像什麼不是最初顯示相關的圖片、flash、視頻等很肥的資源就最後加載 

6,減小inline JavaScript的數量 

瀏覽器parser會假設inline JavaScript會改變頁面結構,因此使用inline JavaScript開銷較大 

不要使用document.write()這種輸出內容的方法,使用現代W3C DOM方法來爲現代瀏覽器處理頁面內容 

7,使用現代CSS和合法的標籤 

使用現代CSS來減小標籤和圖像,例如使用現代CSS+文字徹底能夠替代一些只有文字的圖片 

使用合法的標籤避免瀏覽器解析HTML時作「error correction」等操做,還能夠被HTML Tidy來給HTML減肥 

8,Chunk your content 

不要使用嵌套tables 

<table>
  <table>
    <table>
      ..
    <table>
  <table>
<table>

而使用非嵌套tables或者divs 

<table>...</table>
<table>...</table>
<table>...</table>

將基於大塊嵌套的tables的layout分解成小tables,這樣顯示時不用加載整個頁面(或大table)的內容 

9,指定圖像和tables的大小 

若是瀏覽器能夠當即決定圖像或tables的大小,那麼它就能夠立刻顯示頁面而不要從新作一些佈局安排的工做 

這不只加快了頁面的顯示,也預防了頁面完成加載後佈局的一些不當的改變 

image使用height和width 

table使用table-layout: fixed並使用col和colgroup標籤指定columns的width 

10,根據用戶瀏覽器明智的選擇策略 

IE、Firefox、Safari等等等等 

11,頁面結構的例子 

· HTML
    · HEAD 
        · LINK ...
        CSS files required for page appearance. Minimize the number of files for performance while keeping unrelated CSS in separate files for maintenance. 
        · SCRIPT. ...
        JavaScript. files for functions required during the loading of the page, but not any DHTML that can only run after page loads. 
        Minimize the number of files for performance while keeping unrelated JavaScript. in separate files for maintenance. 
    · BODY 
    · User visible page content in small chunks (tables / divs) that can be displayed without waiting for the full page to download. 
        · SCRIPT. ...
        Any scripts which will be used to perform. DHTML. DHTML script. typically can only run after the page has completely loaded and all necessary objects have been initialized. There is no need to load these scripts before the page content. That only slows down the initial appearance of the page load. 
        Minimize the number of files for performance while keeping unrelated JavaScript. in separate files for maintenance. 
        If any images are used for rollover effects, you should preload them here after the page content has downloaded.

4.HTML頁面加載和解析流程

1.用戶輸入網址(假設是個html頁面,而且是第一次訪問),瀏覽器向服務器發出請求,服務器返回html文件; 

2.瀏覽器開始載入html代碼,發現<head>標籤內有一個<link>標籤引用外部CSS文件; 

3.瀏覽器又發出CSS文件的請求,服務器返回這個CSS文件; 

4.瀏覽器繼續載入html中<body>部分的代碼,而且CSS文件已經拿到手了,能夠開始渲染頁面了; 

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

6.服務器返回圖片文件,因爲圖片佔用了必定面積,影響了後面段落的排布,所以瀏覽器須要回過頭來從新渲染這部分代碼; 

7.瀏覽器發現了一個包含一行Javascript代碼的<script>標籤,趕快運行它; 

8.Javascript腳本執行了這條語句,它命令瀏覽器隱藏掉代碼中的某個<div> (style.display=」none」)。杯具啊,忽然就少了這麼一個元素,瀏覽器不得不從新渲染這部分代碼; 

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

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

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

英文版:http://developer.yahoo.com/performance/rules.html

中文翻譯:http://www.cnblogs.com/smjack/archive/2009/02/24/1396895.html

原文連接:http://renyongjie668.blog.163.com/blog/static/1600531201097062789/

相關文章
相關標籤/搜索