實踐一下前端性能分析


最近在讀一本經典書《高性能網站建設進階指南》。

雖然書籍很多年前就出版了,但里面的內容還是耐人尋味,這次就好好的實踐了一下。

紙上得來終覺淺,絕知此事要躬行,實踐中將會發現一些問題。

有個官方網址《Even Faster Web Sites》,點擊“Run the Examples”按鈕,就能進入在線demo。

在Github上面有個叫awesome-wpo的項目,里面記錄了各個方面關於性能的資源,有書籍、文章、工具等。

下面所有的實驗都是在Chrome 49瀏覽器中執行的。

 

一、瀏覽器並行下載數量

瀏覽器的並發請求數目限制是針對同一域名的。

同一時間針對同一域名下的請求有一定數量限制,超過限制數目的請求會被阻塞。

所以我們經常能看到不同靜態資源會有不同域名,例如圖片、JavaScript、CSS等。

HTTP1.1與HTTP1.0,限制的數量還不一樣。

1)HTTP1.1

先來看看browserscope網上的數量限制的統計結果,比IE6、IE7那會兒進步了很多。

接下來做一個對比,分別是一個域名兩個域名,分別加載圖片。

當一個域名的時候最多只能並發6個請求,而兩個域名的時候能並發10個請求。

 

2)長連接

由於長連接的關系,HTTP1.1建議每個服務器建立少量的連接。

如果瀏覽器支持 keep-alive(長連接),它會在請求的包頭中添加:

長連接的原理是使用同一個TCP連接來發送和接收多個HTTP請求/應答,而不是為每一個新的請求/應答打開新的連接的方法。

當客戶端發送另一個請求時,它會使用同一個連接。這一直繼續到客戶端或服務器端認為會話已經結束,其中一方中斷連接。

下圖左邊每次請求后都會斷開,右邊就是請求后不會馬上斷開。

所以想要高並發量還可以降級到HTTP1.0,不過具體情況如何,我還沒試驗過。

 

3)Cookie-free Domains

YSlow中有23條規則,第20條就是“Use Cookie-Free Domains for Components”。

在請求下載靜態小圖片、靜態小文件的時候,瀏覽器會把它當成普通請求一樣,在request的header信息里附加cookie信息。

如果每個header都附加1kB的cookie,那么對於一個有50個小文件的復雜網頁來講,就白白增加了50kB的傳輸量。

網上有很多相關的解決方案,可以嘗試一下。

 

二、行內腳本阻塞並行下載

覽器會保持css和js的解析順序,如果把行內腳本放在樣式表之后,會明顯地延遲資源的下載(結果是樣式表下載完成並且行內腳本執行完畢時,后續資源才能開始下載)。

這是因為行內腳本可能含有依賴於樣式表中樣式的代碼,比如document.getElementsByClassName()

行內腳本就是將腳本直接寫在HTML頁面中。

<head>
  <link rel="stylesheet" href="css/all-normal.css" type="text/css" />
</head>
<body>
  <div id="content"></div>
  <script>
    var content = '';
    for(i=1; i<1000000; i++)
        content += '寫入頁面';
    document.getElementById('content').innerHTML = content;
  </script>
  <img src="images/ui.png" />
</body>

下面通過Chrom的工具查看下:

再來看看ui.png這個請求的詳細情況,可以參考下Google中的文檔,不過需要翻一下才能看到。

Stalled:瀏覽器得到要發出這個請求的指令,到請求可以發出的等待時間,一般是代理協商、以及等待可復用的TCP連接釋放的時間,不包括DNS查詢、建立TCP連接等時間等。

Request sent:請求第一個字節發出前到最后一個字節發出后的時間,也就是上傳時間。

Waiting(TTFB) :請求發出后,到收到響應的第一個字節所花費的時間(Time To First Byte)。

Content Download:收到響應的第一個字節,到接受完最后一個字節的時間,就是下載時間。

 

的確出現了延時下載,我將“script”標簽去掉后,看到的確是並行下載的。

 

三、圖像優化

平時就會做圖像優化,例如制作Sprite圖等。這里是介紹下壓縮圖片。

關於壓縮的原理,涉及到些算法,可以上網查詢下。

網友Jia在《圖片原理與優化》說:

常見的格式中JPG、PNG、GIF亦屬於位圖,所以它們的數據結構大致相同,只是每一種圖片格式都有不同的壓縮算法,不同的掃描方式,但是優化的方法都有一個共同點,都是圍繞着每個像素顏色值來下手。

1)工具

公司現在開發都用gulp構建工具,里面就有個插件“gulp-image”,用這個工具壓png圖片,能壓掉很多,jpg就不多了。

關於構建工具可以參考《前端自動化構建工具gulp記錄

網上還提供很多在線工具,例如國外的tinypng,國內的tuhaokuai

下圖來自於tinypng網,國寶熊貓幫我壓縮了54%的質量,不過這個網站我上了好久才上去。

 

2)webP

WebP,是一種支持有損壓縮和無損壓縮的圖片文件格式,派生自圖像編碼格式 VP8。

根據 Google 的測試,無損壓縮后的 WebP 比 PNG 文件少了 45% 的文件大小,即使這些 PNG 文件經過其他壓縮工具壓縮之后,WebP 還是可以減少 28% 的文件大小。

兼容性方面,Android兼容性較好,畢竟是自己的東西,不過IOS Safrai完全不支持,下圖中顯示中國的瀏覽器已經覆蓋到了67.37%。

 

四、iframe

在多年前曾經寫過一篇基礎概念的iframe,叫《iframe的一些記錄》。

一直能看到iframe的種種缺點,但是並沒有通過數據表達出來,這次用數據說明一下。

1)阻塞onload事件

在“Iframes Blocking”這個頁面中,通過iframe加載一個頁面,這個頁面要4秒后才加載完,直接導致的父頁面也要4秒后才能加載成功。

 

2)腳本位於iframe之前

在“Script Before Iframe”這個頁面中,script腳本標簽寫在了iframe之前。

圖中紅色框框中的就是iframe中的內容,的確被阻塞了。

后面又試驗了一下將CSS放在iframe之前之后,並不會被阻塞。

 

3)iframe中連接共享

在“Parent and Iframe Connections”這個頁面中,父頁面和iframe中的頁面都包含了5張圖片。

這五張圖片並不是並行下載,而是有先后順序的,紅色方框中的圖片來自於iframe。

 

五、CSS選擇符

下面這些就是CSS選擇符

#toc { margin-left: 20px; }
.chapter { font-weight: bold; }
A { text-decoration: none; }
H1 + #toc { margin-top: 40px; }
#toc > LI { font-weight: bold; }
#toc A { color: #444; }
* { font-family: Arial; }
[href="#index"] { font-style: italic; }
[title~="Index"] { font-style: italic; }
A:hover { text-decoration: underline; }

歸納下來有5種選擇符,元素、關系、屬性、偽類和偽對象選擇符。

CSS選擇符是從右向左匹配的,在MDN的《編寫高效的 CSS》中介紹了幾種高效CSS指南。

 

1)選擇器測試結構

在“Selector Tests”頁面中有6種寫好的,頁面中1000個那種結構。

1. Baseline設置了CSS類,但不會匹配

2. Tag就多了個A標簽CSS設置

3. Class設置了A中的class屬性

4. Child使用了關系選擇符中的子選擇符“>”

5. Descendant使用了關系選擇符中的包含選擇符

6. Universal使用了通配符

<div>
  <div>
    <div> <p> <a id='id0001' class='class0001'>0001</a> </p> </div>
    ...
    <div> <p> <a id='id1000' class='class1000'>1000</a> </p> </div>
  </div>
</div> 

 

2)耗時記錄

 

Baseline

Tag

Class Child Descendant Universal
CSS類

.noclass0001 {

  background: #CFD; 

}
...
.noclass1000 {

  background: #CFD;

}

A {

  background: #CFD;  

}
.noclass0001 {

  background: #CFD;

}
...
.noclass1000 {

  background: #CFD;

}

.class0001 {

  background: #CFD;  

}
...
.class1000 {

  background: #CFD;

}

DIV > DIV > DIV > P > A.class0001 {  

  background: #CFD;

}
...
DIV > DIV > DIV > P > A.class1000 {

  background: #CFD;

}

DIV DIV DIV P A.class0001 {  

  background: #CFD;

}
...
DIV DIV DIV P A.class1000 {

  background: #CFD;

}

P.pclass0001 * {

  background: #CFD;

}
...
P.pclass1000 * {

  background: #CFD;

}

耗時

85ms

63ms 71ms 101ms 77ms 501ms

耗時

60ms

67ms 479ms 185ms 444ms 76ms

耗時

59ms

1116ms 64ms 73ms 67ms 54ms

耗時

69ms

62ms 68ms 67ms 62ms 83ms

耗時

52ms

63ms 68ms 78ms 68ms 77ms

耗時

60ms

62ms 72ms 87ms 67ms 81ms

去掉最高和最低后

平均耗時

62ms

63.75ms 69.75ms 84.75ms 69.75ms 79.25

 還有一個“create your own”自定義類:

 

還附贈了4個選擇器:“A.class DIV”,“id > A”,“.class [href]”,“DIV:first-child”。

 

行內腳本阻塞並行下載demo:

http://download.csdn.net/download/loneleaf1/9519133

 

參考資料:

瀏覽器允許的並發請求資源數是什么意思?

HTTP持久連接

chrome的timeline的問題?

了解無阻塞加載javascript腳本技術

無損壓縮網站上的圖片

圖片原理與優化

圖片格式與設計那點事兒

Clever PNG Optimization Techniques

WebP 探尋之路

提升網站用戶體驗—WebP 圖片的高效使用


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM