Web表現層性能優化

咱們先了解一下,從輸入URL地址或者點擊URL的一個連接到頁面呈現的一次請求,大體須要下面幾個步驟css

1:查找DNS,解析出URL對應的IP地址
2:初始化網絡鏈接
3:發送HTTP請求
4:網絡傳輸請求到服務器
5:Web服務器接收到請求,通過處理轉發到相應的Web應用
6:Web應用處理請求,並返回相應的應答
7:網絡傳輸應答內容到前端瀏覽器
8:瀏覽器開始解析從服務器端返回的內容,開始渲染和繪製
9:根據HTML內容來構建DOM(文檔對象模型)
10:加載和解析樣式,構建CSSOM(CSS對象模型)
11:根據DOM和CSSOM來構建渲染樹,這個過程是按照文檔順序從上到下依次進行的
12:會根據構建渲染樹的過程,在適當的時候,把已經構建好的部分繪製到界面上,中間還會伴隨着重
繪(repaint)和迴流(reflow)等,如此循環操做,直到渲染繪製完成
13:整個頁面加載完成,會觸發OnLoad事件

簡單分析一下上面這些步驟的這個過程:html

1:要經過URL請求服務器,瀏覽器就要知道這個URL對應的IP是什麼,只有知道了IP地址,瀏
覽器才能準備的把請求發送到指定的服務器的具體IP和端口號上面。瀏覽器的DNS解析器負
責把URL解析爲正確的IP地址。
這個解析工做是要花時間的,並且這個解析的時間段內,瀏覽器不能從服務器那裏
下載任何東西。瀏覽器和操做系統提供了DNS解析緩存支持。
2:當得到了IP地址以後,瀏覽器會請求與服務器的鏈接,TCP通過三次握手後創建鏈接通道
3:瀏覽器真正發送HTTP請求,這個請求包含了不少東西,如cookie和其餘的head頭信息。
4:網絡開始傳輸請求到服務器,這個會包括不少時間,好比網絡阻塞時間、網絡延遲時間和
真正傳輸內容的時間等,這是個很複雜的過程
5:Web服務器接收到請求,會根據URL裏面的上下文,轉交給相應的Web應用進行處理
6:Web應用會依次經過不少處理,好比:filter、aop的前置處理、IoC處理、真實處理對象的
尋找和建立等,這個根據每一個應用的具體實現而不一樣。而後會把請求轉交到真實的處理對象,進行相應的業務處理,並生成Response對象

7:經過網絡傳輸應答內容回到前端的瀏覽器。其實首先到達瀏覽器的是純粹的html代碼,不
包含什麼圖片,外部腳本,外部CSS等,也就是頁面主要的html結構。
8:接下來就是瀏覽器解析頁面,進行渲染和繪製的過程了,大體以下:
(1)裝載和解析Html文檔,構建DOM,若是在解析中發現須要其它的資源,好比圖片,那麼瀏
覽器會發出請求以獲取這個資源
(2)裝載和解析CSS,構建CSSOM
(3)根據DOM和CSSOM來構建渲染樹
(4)而後對渲染樹的節點進行佈局處理,肯定其在屏幕的位置
(5)把渲染好的節點繪製到界面上
以上步驟是一個漸進的過程,渲染引擎不會等到全部Html都被解析完才建立並佈局
渲染樹,它會在獲取文檔內容的同時把已經接收到的局部內容先展現出來。
9:重繪(repaint)的發生:若是渲染到後面,發現須要修改前面已經繪製元素的外觀,好比
背景色、文字顏色等,不影響它周圍和內部佈局的行爲,這就須要重繪這個元素
10:迴流(reflow)的發生:若是渲染到後面,發現須要修改前面已經繪製好的元素的某些行
爲,這些行爲引發了頁面上某些元素的佔位面積、定位方式、邊距等屬性的變化,都會引
起它內部、周圍甚至整個頁面的從新渲染,這就是迴流

什麼是延遲
  延遲指的是:消息或分組從信息源發送到目的地所需的總時間
延遲的構成前端

1:傳播延遲
指的是消息從發送端到接收端須要的時間,是信號傳播距離和速度的函數。取決於
距離和信號經過的媒介。
2:傳輸延遲
指的是把消息中的bit轉移到鏈路所須要的時間,是消息長度和鏈路速率的函數。取
決於鏈路的速率,跟客戶端到服務器的距離無關。
3:處理延遲
指的是處理分組頭部、檢查位錯誤、肯定分組目標所須要的時間。一般由硬件來完
成,如路由器要根據分組頭部來選擇出站路由。
4:排隊延遲
指的是分組排隊等待處理的時間。若是分組到達的速度超過了路由器的處理能力,
那麼分組就要進入緩衝區排隊。

DOM、CSSOM和JavaScript常常交織在一塊兒:
1:腳本執行過程當中可能會處理須要同步的功能,好比document.write,從而會阻塞DOM的解析
和構建;
2:腳本可能會查詢任何對象的計算樣式,從而阻塞CSS處理
結果就是DOM構建在JS執行完畢前沒法進行,而JS在CSSOM構建完成前也沒法進行。
瀏覽器對於HTML的解析是遞增的,對於JavaScript和CSS的解析執行,要等到整個文
件下載完畢。
web

最基本的優化思路,大體來講:
1:儘可能減小沒必要要的網絡延遲
2:儘可能減小請求數量
3:儘可能減小來回傳遞的數據量
4:提升後臺程序的響應速度
5:提升每一個環節和步驟的處理能力,以加快速
ajax

Web性能的基本指標
1:請求響應時間:從客戶端發起請求,到web應用對用戶請求做出響應,再發送反饋直至用戶
接收完畢所須要的時間,也被稱爲TTLB(Time to Last Byte),建議3/5/10秒。
2:最大併發用戶數:用來衡量可用性,就是在不出現系統崩潰的狀況下,能同時提供服務的
最大用戶數量,一般分紅兩種:
(1)嚴格意義上的併發:即全部的用戶在同一時刻作一樣的操做
(2)廣義的併發:多個用戶同時進行了操做,可是這些操做能夠是相同的,也能夠是不一樣的
3:事務響應時間:是針對業務的概念,事務可能由一系列請求組成,以完成業務功能
4:TPS(Transaction Per Second):每秒鐘系統可以處理的交易或者事務的數量,通用用來衡
量系統處理能力
5:吞吐量:在一次性能測試過程當中,經過網絡傳輸的數據量的總和。吞吐量/傳輸時間就是吞
吐率
正則表達式

Web性能測試的常見工具
1:用於測試頁面資源加載速度,好比:
Firebug、Chrome的開發者工具、HttpWatch等
2:用於測試頁面渲染呈現,以及js運行速度,好比:
dynaTrace Ajax、Speed Trace等
3:對頁面進行總體評價分析,好比:
WebPageTest、Page Speed、yslow等
4:專業的測試工具,好比:
Selenium、WebLoad、ab、LoadRunner等

JavaScript的常見優化數組

1:儘可能把JS放在頁面底部
2:循環中要屢次使用的表達式,好比:判斷長度的表達式、獲取對象的表達式,最
好在外面作個變量來保存
3:減小頁面重繪,好比:不要在循環中改變元素外觀,應該拼接好後,一次性的設
置給元素,這樣就只須要重繪一次
4:儘可能避免使用eval
5:把全局域的變量緩存成爲局部域的變量,全局變量實際上是window對象的成員,而
局部變量是放在函數的棧裏的,局部變量訪問更快
6:儘可能避免對象的嵌套查詢,好比:obj1.obj2.obj3這樣的表達式就會引發屢次查
找,應該把各個對象用局部變量緩存起來,這樣後續使用就直接使用
7:當須要將數字轉換成字符時,採用以下方式:「」 + 數字的方式最快
8:當須要將浮點數轉換成整型時,應該使用Math.floor()或者Math.round()。而不
是使用parseInt() ,Math是內部對象,速度是最快的

9:儘可能讓代碼簡潔,好比變量名、方法名在不影響語意的狀況下儘可能簡單
10:連加多個字符串的,可使用數組,把要鏈接的字符串放到數組中,而後使用
數組的join方法,形如:var str = myArr.join(「」);
11:儘可能用JSON格式來建立對象,而不是var obj=new Object(),由於前者是直接
複製,然後者須要調用構造器
12:儘可能使用JSON格式來建立數組,即直接使用:[parm,param,param...],而不是
採用 new Array(parm,param,param...)這種語法。由於使用JSON格式的語法是
引擎直接解釋的。然後者則須要調用Array的構造器
13:儘可能使用正則表達式來操做字符串,例如替換、查找等。由於JS的循環速度比
較慢,而正則表達式的操做是用C寫成的API,性能比較好
14:對於大的JS對象,由於建立時時間和空間的開銷都比較大,所以應儘可能緩存
15:避免使用document.write,可使用innerHTML來向頁面添加對象
16:避免使用setTimeOut方法,應用setInterval,setTimeout每次要重置定時器
17:避免with語句,with會建立自已的做用域,會增長其中執行代碼的做用域長度

18:儘可能減小對DOM的操做,避免迴流,引發迴流的操做常見的有:
(1)改變窗體大小
(2)更改字體
(3)添加移除stylesheet塊
(4)內容改變哪怕是輸入框輸入文字
(5)CSS虛類被觸發如 :hover
(6)更改元素的className
(7)當對DOM節點執行新增或者刪除操做或內容更改時
(8)動態設置一個style樣式時
(9)當獲取一個必須通過計算的CSS值時,好比訪問offsetWidth、clientHeight等
爲了不迴流的發生,建議:
(1)在對DOM進行操做以前,儘量把屢次操做內容準備好,而後儘可能1次操做完成
(2)在對DOM操做以前,把要操做的元素,先從當前DOM結構中刪除,等處理好事後再添加回
到DOM中。從DOM中刪除元素的方法有:
A:經過removeChild()或者replaceChild()實現真正意義上的刪除
B:設置該元素的display樣式爲「none」

(3)對獲取的那些會觸發迴流操做的屬性,好比offsetWidth等 緩存起來
(4)儘可能避免經過style屬性對元素的外觀進行修改,由於會觸發迴流操做
A:使用更改className的方式替換style.xxx=xxx的方式
B:使用style.cssText = ‘’;一次寫入樣式
C: 避免設置過多的行內樣式
(5)添加的結構外元素儘可能設置它們的位置爲fixed或absolute
(6)避免使用表格來佈局
(7)避免在CSS中使用JavaScript表達式
19:對局部使用的JS,採用異步裝載、按需裝載JS的方式,好比使用jQuery的:
jQuery.getScript(「t.js」,function(){t1();});
這個是沒有緩存js的,要緩存的話,以下:
jQuery.ajax({
   url: "t.js",
   dataType: "script",
   cache: true
}).done(function() {
    t1();
});

一,將腳本放在底部,腳本放在頂部帶來的問題:
   1:使用腳本時,對於位於腳本如下的內容,逐步呈現將被阻塞
   2:在下載腳本時會阻塞並行下載
        放在底部,當腳本沒加載進來,用戶就觸發腳本事件,可能會出現JS錯誤問題。
二, 將樣式文件放在頁面頂部
       樣式表加載完成後,纔會構建渲染樹,所以樣式文件放在頁面底部可能會
   出現兩種狀況:
  1:白屏
  2:無樣式內容的閃爍
三,CSS儘可能寫在<head>,不要出如今<body>中,不然會引發從新渲染
四 ,最小化 iframe 的數量
   iframe會致使重繪,同時iframe也是SEO的大忌。針對前端優化來講iframe
有其好處,能夠異步和併發加載資源瀏覽器

五,減小DOM訪問緩存

查找DOM會花費時間,若是更改了位置和外觀,可能會引發重繪和迴流,建議:
1:使用臨時變量(或數組)緩存已經訪問過的元素
2:「離線」更新節點, 再將它們添加到樹中
3:避免使用 JavaScript 輸出頁面佈局--應該是 CSS 的事兒
4:批量操做時,使用字符串拼接,用innerHTML開銷更小,速度更快,同時內存
也更安全安全

六,避免沒必要要的渲染

(1)position:fixed:fixed定位在滾動時會不停的進行渲染,特別是若是是頁面
頂部有個fiexd,頁面底部有個相似返回頂部的fixed,則在滾動時會整個頁面進
行渲染,效率很是低。能夠加transform: translateZ(0);解決。
(2)hover 特效:建議頁面滾動時,先取消hover效果,滾動中止後再加上hover效
果。這個能夠經過在外層加類名進行控制
(3)應該設置border:none,而不是border:0,設置爲0,仍然是會渲染的

七,使用 <link> 而不是@importChoose,在 IE 中 @import 指令等同於把 link 標記寫在 HTML 的底部。
八, 全部圖片都應該指定高寬屬性,不然瀏覽器會從新渲染網頁
九, 儘可能少用幀數過多過快的FLASH,GIF動畫
十, 儘可能避免使用CSS子選擇符,CSS子選擇符會形成一次瀏覽器的篩選和定位計算,
好比能用.div 的,就儘可能不要用.nav ul li a .div 這樣的寫法
十一, 儘可能避免渲染過程的」中斷」,好比等待js的執行
十二, 不要在 HTML 中使用縮放圖片
十三,避免使用 CSS 表達式

(1)position:fixed:fixed定位在滾動時會不停的進行渲染,特別是若是是頁面
頂部有個fiexd,頁面底部有個相似返回頂部的fixed,則在滾動時會整個頁面進
行渲染,效率很是低。能夠加transform: translateZ(0);解決。
(2)hover 特效:建議頁面滾動時,先取消hover效果,滾動中止後再加上hover效
果。這個能夠經過在外層加類名進行控制
(3)應該設置border:none,而不是border:0,設置爲0,仍然是會渲染的

現代的瀏覽器會作不少優化,典型如:

1:資源預取和排定優先次序
2:DNS預解析
3:TCP預鏈接
4:頁面預渲染
爲了更好的利用瀏覽器的這些機制,咱們能夠:
1:CSS和JavaScript等重要資源應該儘早在文檔中出現
2:應該儘早交付CSS,從而避免渲染阻塞並讓JavaScript執行
3:非關鍵性的JavaScript應該推遲,以免阻塞DOM和CSSDOM的構建
咱們能夠在文檔中嵌入提示,以觸發瀏覽器爲咱們採用其餘優化機制
1:預解析特定域名,如:<link rel=「dns-prefetch」 href=「//abc.com」>
2:預先獲取頁面後面要用的資源,如:<link rel=「subresource」 href=「/js/a.js」>
3:預先獲取未來導航要用的資源,如:<link rel=「prefetch」 href=「/img/a.jpg」>
4:根據對用戶下一個目標的預測,預渲染特定頁面,如:<link rel=「prerender」
href=「//abc.com/a/b/d.html」>
這些提示會觸發瀏覽器的優化機制,若是瀏覽器不支持,會當成空操做,沒有害處
相關文章
相關標籤/搜索