web性能優化規則

一、減小HTTP請求

why

減小響應時間。javascript

how

  • CSS Sprites
  • 合併樣式腳本
  • 內聯圖片(使用data:URL模式能夠在web頁面中包含圖片但不須要額外的HTTP請求)

二、使用內容發佈網絡(CDN)

why

瀏覽器是根據域(Domain)來緩存內容資源的,只要域不同,那麼它就須要重複下載這些資源,並且使用一樣的方式將它們緩存起來。css

帶來的問題:重複地下載,這會佔用網絡資源和緩存空間。html

how

若是有不少站點,它們之間能夠共享某些內容(例如javascript,css,image等),那麼與其每一個站點放一份,就不如將他們統一地存在在一個地方,這樣就能夠減小下載的次數和緩存的體積了。java

如:引用jquery cdnjquery

<script src="https://code.jquery.com/jquery-2.2.4.js"></script>

三、添加Expires頭

why

使內容具備緩存性web

how

Expires: Thu, 01 Dec 1994 16:00:00 GMT (必須是GMT格式)ajax

經過HTTP的META設置expires和cache-control算法

<meta http-equiv="Cache-Control" content="max-age=7200" />
<meta http-equiv="Expires" content="Mon, 20 Jul 2009 23:00:00 GMT" />

上述設置僅爲舉例,實際使用其一便可。這樣寫的話僅對該網頁有效,對網頁中的圖片或其餘請求無效,並不會作任何cache。瀏覽器

四、壓縮組件

why

減少文件體積,提高頁面加載速度緩存

how

壓縮腳本和樣式表

五、樣式置頂

why

放在底部可能會出現白屏,會阻塞頁面的逐步呈現

注意:使用link,不使用@import(可能出現白屏,以及下載組件無序性)

六、腳本置底

why

頁面既能夠逐步呈現,也能夠提升資源下載的並行度

最差狀況:放在頂部

  • 會阻塞後面內容的呈現
  • 會阻塞其它組件的下載

七、避免使用CSS表達式

why

表達式可能會運算不少遍、影響頁面性能

how

實現動態CSS可使用javascript控制

$(function () {
    $("dom").css("background-color",(new Date()).getHours()%2?"#EEE":"#BBB");
});

八、使用外鏈JavaScript和CSS

why

提升樣式和腳本複用性

注意:純粹而言,內聯速度比外鏈快,由於外鏈額外增長了http請求,可是因爲瀏覽器緩存,當多頁面引用了同一個樣式表或腳本文件時,反而減小了HTTP請求,實現複用。

how

<link rel="stylesheet" type="text/css" href="style.css" />
    <script type="text/javascript" src="main.js" />

九、減小DNS查找

why

查找DNS是須要花費時間的,一般瀏覽器在查找給定的IP地址要花費20~120毫秒的時間,在DNS完成查找以前,瀏覽器沒法從主機名下載任何東西。

how

最理想的狀況:只使用一個主機名,既減小了DNS查找,又最大化了並行下載。(只針對頁面組件不多(1個或2個)的狀況)

更現實的狀況:使用2個,但很少於4個主機名,這樣在減小DNS查找和容許高度並行下載之間作出了比較好的均衡。

十、精簡JavaScript和CSS

why

減少文件大小,改善加載時間

how

  • 從代碼中移除沒必要要的字符(包括空格、註釋、換行符等)
  • 精簡JS代碼可以使用JSMin
  • 精簡CSS代碼,合併相同的類,移除不使用的類,使用縮寫,如「#EEEEEE」寫成「#EEE」,「0px」寫成「0」。

十一、避免重定向

why

重定向是指用戶的原始請求從新轉向到了其它請求

301 Moved Permanently:這個狀態碼標識用戶所請求的資源被移動到了另外的位置,客戶端接收到此響應後,須要發起另一個請求去下載所需的資源。

302 Found:這個狀態碼標識用戶所請求的資源被找到了,但不在原始位置,服務器會回覆其餘的一個位置,客戶端收到此響應後,也須要發起另一個請求去下載所需的資源。

目前咱們一直只要區分301和302便可。他們本質上的區別究竟是什麼呢?301表示永久重定向,302表示臨時重定向。

how

在定義連接地址的href屬性的時候,儘可能使用最完整的、直接的地址。例如:
使用 www.google.com 而不是google.com
使用cn.xxxx.com而不是xxxx.com
使用www.google.com.hk而不是google.com
使用www.site.com/products/而不是www.site.com/products

十二、移除重複腳本

why

重複腳本損傷性能:沒必要要的HTTP請求及執行JS所浪費的時間

how

確保腳本只被加載一次。使用模塊化工具如requireJS或seaJS管理腳本。

1三、配置ETag(實體標籤)

它的做用是用一個特殊的字符串來標識某個資源的「版本」,客戶端(瀏覽器)請求的時候,比較ETag若是一致,則表示該資源並無被修改過,客戶端(瀏覽器)可使用本身緩存的版本,避免重複下載。

服務器檢測緩存組件和原始服務器組件匹配的方式

若是緩存組件過時了或者用戶明確地從新加載了頁面,瀏覽器在重用以前必須首先檢查它是否有效。這稱做一個條件GET請求。雖然瀏覽器必須產生這個http請求,可是仍比簡單地下載全部已過時的組件效率高。若是瀏覽器組件是有效的(相互匹配)原始服務器則不會返回整個組件,而是返回304 not modifed狀態碼。

檢測匹配有兩種方式

  • 比較最新修改日期

第一次請求響應

————>
GET /i/xx.jpg HTTP 1.1
HOST www.xxx.com
<————
HTTP 1.1 20 OK
Last-Modified:true .12 dec 2015 03:03:09 GMT
Content-Length:1024

第二次請求響應

————>
GET /i/xx.jpg HTTP 1.1
HOST www.xxx.com
If-Modified-Since:True,12 dec 2015 03:03:09 GMT
<————
HTTP 1.1 304 not modifed
  • 比較實體標籤

實體是咱們以前提到的組件的另外一種稱呼。ETag是惟一標識了一個組件的一個特定版本的字符串,必須帶上引號。這種爲驗證明體提供了更爲靈活的機制——能夠根據user-agent,accept-language頭而改變。

第一次請求響應

————>
GET /i/xx.jpg HTTP 1.1
HOST www.xxx.com
<————
HTTP 1.1 20 OK
Last-Modified:true .12 dec 2015 03:03:09 GMT
ETag:"10c34ba-8ba-abds3b3"
Content-Length:1024

第二次請求響應

————>
GET /i/xx.jpg HTTP 1.1
HOST www.xxx.com
If-Modified-Since:True,12 dec 2015 03:03:09 GMT
If-None-Match:"10c34ba-8ba-abds3b3"
<————
HTTP 1.1 304 not modifed

ETag帶來的問題

  • 若是部署在服務器場環境中,配置不當的話,可能每一個服務器會對相同的資源生成不同的ETag,這樣就增長了重複下載的可能性。

ETag的優點和特色

  • 能夠更加精確地判斷資源是否被修改,由於它不是一個時間值,而是對時間通過處理的一個長整型數值(固然具體算法咱們目前還不得而知)。
  • 瀏覽器發起新請求時須要包含 If-None-Match。

1四、使Ajax可緩存

why

因爲AJAX其實也是須要發起請求,而後服務器執行,並將結果(一般是JSON格式的)發送給瀏覽器進行最後的呈現或者處理,因此對於網站設計優化的角度而言,咱們一樣須要考慮對這些請求,是否能夠儘量的利用到緩存的功能來提升性能。

how

對於AJAX而言,有一些特殊性,並非全部的AJAX請求都是能夠緩存的。

  • POST的請求,是不能夠在客戶端緩存的,每次請求都須要發送給服務器進行處理,每次都會返回狀態碼200。(這裏能夠優化的是,服務器端對數據進行緩存,以便提升處理速度)
  • GET的請求,是能夠(而且默認)在客戶端進行緩存的,除非指定了不一樣的地址,不然同一地址的AJAX請求,不會重複再服務器執行,而是返回304。

有的時候,咱們可能但願GET請求不被緩存,有幾種作法來達到這樣的目的。

  • 每次調用的時候,請求不一樣的地址(能夠在原始地址後面添加一個隨機的號碼)。
  • 若是你所使用的是jquery的話,則能夠考慮禁用AJAX的緩存。
$.ajaxSetup({ cache: false });

1五、使用GET來完成Ajax請求

why

  • 一、POST請求,不能使用客戶端緩存
  • 二、GET請求,可使用客戶端緩存

這個意義上來說,使用GET會比POST而言,由於減小了請求數和數據的重複傳輸,有更好的一個性能表現。
在使用XMLHttpRequest(目前的AJAX都是基於它實現的)的時候,瀏覽器中的POST實現爲兩步走的過程,首先發送頭部信息,而後再發送數據。但若是是使用GET的話,就只有一個TCP的包發送出去(除非有大量的Cookie),這樣無疑能夠提升性能。

【備註】一個TCP包的尺寸大約爲1452字節。 除此以外,顯示的項目中,並非總能使用GET的,例如長度方面可能會有限制:The maximum URL length in IE is 2K, so if you send more than 2k data you might not be able to use GET.

1六、減小DOM元素數量

why

DOM(Document Object Model)文檔對象模型

HTML DOM 定義了訪問和操做 HTML 文檔的標準方法。
DOMHTML 文檔表達爲樹結構。
減小頁面的DOM元素數量,有助於減少頁面體積,而且也下降了維護這份DOM樹的成本。

how

  • 一、避免不正確地使用服務器控件。
  • 二、減小沒必要要的內容(並非全部的內容都必須放在頁面上面的)。

若是數據量大,能夠考慮分頁,或者按需加載

1七、避免404

why

什麼狀況下會發生404錯誤?

404 意味着Not Found,意思是說未找到資源。至少會有兩種緣由致使404錯誤:

  • 一、該資源按理說是要有,但咱們沒有提供。用戶按照正常的方式來請求,因此資源找不到。
  • 二、該資源原本就不存在,用戶按照不正常的方式來請求,固然仍是找不到。

404錯誤會有什麼影響?

① 看不到的影響:有時候,404錯誤發生了,用戶可能根本沒有感受到。

  • 例如請求favicon.ico文件,或者請求了某個不存在的腳本文件、樣式表、圖片文件,頁面仍是會按照正常的方式進行呈現。
  • 丟失的腳本文件、樣式表、圖片文件,會致使頁面的某些行爲、界面效果出現異常(也可能不是很明顯)
  • 最大的問題多是性能方面的影響。尤爲是若是請求一個不存在的腳本文件,由於瀏覽器在請求腳本文件的時候,即使是返回404,它也會嘗試去按照Javascript的方式解析響應中的內容。這無疑會增長不少處理的時間,而由於該文件不存在,因此這些都是無用功。

② 看獲得的影響:

  • 若是用戶請求的某個頁面不存在,那麼他將收到明確的迴應
  • 默認狀況下,他將收到一個標準的錯誤頁面(請注意:很多用戶會被這個頁面嚇到)

how

避免404錯誤發生的措施:

  • 爲網站提供favicon.ico。
  • 在發佈網站前的測試工做中,運行Link checker工具,確保全部連接都是可以訪問到的。這個工具是W3C發佈的,徹底免費,你值得擁有。
  • 爲了不用戶收藏絕對地址(customer.aspx),給後期更新帶來隱患。能夠考慮在設計階段採用 Url Rewriting 或者 Routing 等技術來實現更加友好和靈活的地址(例如/Customer),之後若是業務邏輯有變化,只須要修改一下路由規則便可。
第三條措施,一樣能夠儘量地減小用戶手工輸入地址出錯的機會。

1八、減小Cookie的大小

why

若是對某個域(Domain)保存了Cookie,那麼針對這個域的全部請求,都會發送這些全部的Cookie(哪怕當前請求根本用不着,例如針對圖片的請求),大量的、重複的發送Cookie毫無疑問會增長網絡的流量,並所以而下降請求被執行的性能。

how

從技術上說,這個文件的內容是由網站控制的,它能夠決定要寫什麼內容在裏面,他也能夠決定是否要加密。惟一的一個限制,這個文件的體積不容許超過4KB。

1九、使用無Cookie的域

why

好比圖片 CSS 等,Yahoo! 的靜態文件都在主域名之外,客戶端請求靜態文件的時候,減小了 Cookie的反覆傳輸對主域名的影響。
只有訪問主域名的時候才須要保存cookie,而cookie會自動地發送給當前域的全部請求。

20、不要使用濾鏡

why

Filters這個功能是IE當年爲了提供更加豐富的一些頁面效果而設計出來的。
不只僅是別的瀏覽器可能不支持,IE從9.0版本開始也放棄了這方面的支持。

2一、不要在HTML中縮放圖片

why

有時獲得的圖片尺寸和具體顯示尺寸不同,爲了在網頁中顯示出但願的尺寸,一般會經過下面的方法把圖片進行縮放:

<img width="100" height="100" src="pic.jpg" alt="my pic"/>

瀏覽器下載到原始圖片以後,若是原始尺寸與目標尺寸不符,就會須要對圖片進行縮放(拉伸或者縮小),以便實現剛纔所提到的目的。

how

咱們須要在網頁中顯示什麼尺寸的圖片,就請圖片設計人員提供什麼尺寸的圖片,而不是在網頁中進行縮放。

2二、縮小favicon.icon並緩存

why

  • 一、每一個網站都應該有該文件,瀏覽器在訪問任何頁面的時候,老是會嘗試去請求這個文件(若是本地沒有的話)。
  • 二、該文件一般應該命名爲favicon.ico ,若是但願使用別的名稱或者格式(例如PNG),則須要在頁面的頭部(Head)中定義引用(下面兩句中的第一句是必須的)
<link rel="shortcut icon" href="http://example.com/favicon.ico" type="image/vnd.microsoft.icon">
<link rel="icon" href="http://example.com/favicon.ico" type="image/vnd.microsoft.icon">
  • 三、該文件能夠直接放在網站根目錄,但也能夠放在其餘的主機,或者你想要的任何位置。若是不在默認的根目錄下面,也是須要經過上面所提到的引用方式定義。

how

使它儘可能在1KB左右。想比較其餘的格式(PNG,GIF等),該文件默認的格式爲ico,這種文件一般較小。要建立favicon.ico文件,可使用 http://www.favicon.cc/ 提供的在線免費服務。

使它可以緩存。 因爲該文件使用很頻繁,因此緩存顯得很重要。對於這個文件而言,能夠設置永不過時(或者過時時間長一些)。

將該文件放在單獨的主機中,能夠避免在請求該文件時發送cookie。

2三、避免空的src和href

why

空的src和href都會致使多餘的HTTP請求,雖然不影響加載時間,可是會對服務器產生沒必要要的流量和壓力,嚴重的以致於影響整個網站的用戶體驗。

例子:
在頁面加載的過程當中,一個有着空src屬性的img元素被JavaScript動態地賦值。這樣作的問題是,在腳本執行以前元素就被瀏覽器渲染了(尤爲是當你把腳本放到文檔最後的時候)。因此瀏覽器依然會發起一個HTTP 請求,雖然它是一個空值。

雅虎的團隊指出,若是你將img的src留空,可能你的本意是暫時不要顯示任何圖片,但在不一樣的瀏覽器其實仍是會有一些額外的請求發生。

例子:
一樣的問題也發生在href 這個屬性上。有些時候,開發人員想用超連接來觸發JavaScript的一個交互。這時問題就來了,當用戶觸發了「單擊」操做,若是 href 是空的那麼瀏覽器就向服務器發送一個HTTP 請求。

how

  • 避免空的src和herf值。
  • 解決留空src屬性的問題:
  • 你能夠將初始圖片設置爲一個很小的默認圖片(這個圖片設置永不過時),而不是留空。

解決留空href屬性的問題:

  • <a>標籤以href屬性,並不鏈接到實際的頁面:
<a href="#"></a>
<a href="#nogo"></a>
<a href="##"></a>
<a href="###"></a>
<a href="void(0);"></a>
<a href="void(0)"></a>
<a href=";"></a>
<a href=""></a>
  • 禁止跳轉,並添加cursor:pointer樣式
<style type="text/css">
  a{cursor: pointer}
</style>
<a>點擊一</a>
<a onclick="doSomething()">點擊二</a>
  • a 標籤建立一個帶有描述信息的href 屬性,並監控click事件調用preventDefault()函數。
<a href="#Something_De scriptive" id="my_id">Trigger</a>
<script>
  $("#my_id").click(function(e){
    e.preventDefault(); // 取消單擊事件的默認動做以阻止連接的跳轉。
      // 其餘的代碼
   });
</script>

優勢:

<a>夠響應鍵盤事件並得到焦點(從而屏幕閱讀器可以讀出背後的內容,加強可訪問性)

優雅降級,在網絡鏈接不好,尚未加載到CSS的時候,<a>依然有手型與正常的link樣式。


參考:YSlow團隊的23條「Web性能最佳實踐和規則」+《高性能網站建設指南》

相關文章
相關標籤/搜索