1.減小HTTP請求次數
- why
減小頁面的 HTTP 請求次數是你首先要作的一步。這是 改良首次拜訪用戶等候時間 的最主要的方法。猶如 Tenni Theurer 的他的博客 Browser Cahe Usage – Exposed!中所說,HTTP 請求在無緩存狀況下佔去了 40%到 60%的響應時間。
- how
改善響應時間的最簡單途徑就是 減小組件的數量 ,並由此減小HTTP請求的數量。
- 圖片地圖:在一個圖片上關聯多個URL。目標URL的選擇取決於用戶單擊了圖片上的哪一個位置。
- CSS Sprites :減小圖像請求的有效方法。把全部的背景圖像都放到一個圖片文件中,然後經過 CSS 的 background-image 和 background-position 屬性來顯示圖片的不一樣部分。
- 合併腳本和樣式表:適當地把多個腳本合併爲一個腳本,把多個樣式表合併爲一個樣式表。
2.使用CDN
whyjavascript
CDN, Content Delivery Network 內容分發網絡, 其基本思路是儘量避開互聯網上有可能影響數據傳輸速度和穩定性的瓶頸和環節,使內容傳輸的更快、更穩定。css
在很早的時候,是沒有CDN的概念和需求的。那時候咱們網站所須要的javascript等文件,就是放在咱們的網站目錄中,其實這也是一種內容交付的方式,並且每每仍是比較高效的。但直到有一天,咱們作了各類各樣的網站,咱們就會發現另一個問題:就是針對同一個javascript文件,瀏覽器可能會緩存多個版本。
之因此會這樣作,是由於瀏覽器是根據域(Domain)來緩存內容資源的,只要域不同,那麼它就須要重複下載這些資源,並且使用一樣的方式將它們緩存起來。
可是,這會帶來一些小的問題:重複地下載,緩存這些一樣的腳本文件是須要佔用帶寬和本地緩存文件空間的。
因而,人們想出來一個解決方法:既然瀏覽器是根據域來區分這些內容資源的,那麼是否能夠將這些內容都放在統一的一個域裏面呢?這樣就算是咱們有不少網站,咱們均可以使用一樣的地址引用這些內容資源,那麼就不會產生重複下載和緩存的問題了。html
- how
一個最直接也是最簡單的使用CDN的作法:若是你有不少站點,他們之間能夠共享某些內容(例如javascript,css,image等),那麼與其每一個站點放一份,就不如將他們統一地存在在一個地方,這樣就能夠減小下載的次數和緩存的體積了。
e.g. 在引用jquery.js的時候,你能夠下載後,引用本地地址,也能夠直接引用google CDN的內容。
<script type="text/javascript"src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
3.避免空的src和href
why
空的src和href都會致使多餘的HTTP請求,雖然不影響加載時間,可是會對服務器產生沒必要要的流量和壓力,嚴重的以致於影響整個網站的用戶體驗。
e.g.
在頁面加載的過程當中,一個有着空src屬性的img元素被JavaScript動態地賦值。這樣作的問題是,在腳本執行以前元素就被瀏覽器渲染了(尤爲是當你把腳本放到文檔最後的時候)。因此瀏覽器依然會發起一個HTTP 請求,雖然它是一個空值。 雅虎的團隊指出,若是你將img的src留空,可能你的本意是暫時不要顯示任何圖片,但在不一樣的瀏覽器其實仍是會有一些額外的請求發生。例如java
- Internet Explorer makes a request to the directory in which the page is located.
- Safari and Chrome make a request to the actual page itself.
- Firefox 3 and earlier versions behave the same as Safari and Chrome, but version 3.5 addressed this issue[bug 444931] and no longer sends a request.
Opera does not do anything when an empty image src is encountered.node
e.g.
一樣的問題也發生在href 這個屬性上。有些時候,開發人員想用超連接來觸發JavaScript的一個交互。這時問題就來了,當用戶觸發了「單擊」操做,若是 href 是空的那麼瀏覽器就向服務器發送一個HTTP 請求。jquery
- 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
樣式ajax
<style>
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樣式。
四、爲文件頭制定Expires
- why
是內容具備緩存性
- how
格式:
Expires = "Expires" ":" HTTP-date
e.g.
Expires: Thu, 01 Dec 1994 16:00:00 GMT (必須是GMT格式)
經過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" />
5.使用gzip壓縮內容
whyjson
Gzip是一種流行的文件壓縮算法,如今的應用十分普遍,尤爲是在Linux平臺。
當應用Gzip壓縮到一個純文本文件時,效果是很是明顯的,大約能夠減小70%以上的文件大小。這取決於文件中的內容。 除了節省流量,改善用戶的瀏覽體驗外,另外一個潛在的好處是Gzip與搜索引擎的抓取工具備着更好的關係。
Gzip開啓之後會將輸出到用戶瀏覽器的數據進行壓縮的處理,這樣就會減少經過網絡傳輸的數據量,提升瀏覽的速度。
- how
編輯 http.conf 文件
去掉 #LoadModule headers_module modules/mod_headers.so 前面的註釋#
去掉 #LoadModule deflate_module modules/mod_deflate.so 前面的註釋#
去掉 #LoadModule filter_module modules/mod_filter.so 前面的註釋#
文件末尾加上
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript application/x-javascript application/javascript application/json #對指定的內容進行壓縮,壓縮方式爲默認的一個方法
</IfModule>
詳情見:Apache2.4開啓GZIP功能
六、把css放到頂部
- why
提升渲染性能,避免瀏覽器重繪頁面元素。
在HTML文件<body>
中指定外部樣式表和內聯樣式塊可能對瀏覽器的渲染性能產生不利影響。
1)瀏覽器阻塞渲染網頁直到全部外部的樣式表都已被下載。
2)(用<style>
標記指定的)內聯樣式塊可能會致使reflows和頁面跳動。
所以,把外部樣式表和內聯樣式塊放在頁面的<head>
中是很重要的。經過確保樣式表首先被下載和解析,可讓瀏覽器逐步渲染頁面。
- how
將內聯樣式塊和<link>
元素從頁面<body>
移動到頁面<head>
中。
HTML 4.01規範(第12.3節)規定,始終把使用<link>
標籤的外部樣式表放在<head>
部分裏。不要使用@import。還要確保您指定的樣式有正確的順序。
把<style>
區塊放在<head>
部分裏。
7.把JS放到底部
- why
一、瀏覽器在加載JS時會阻塞瀏覽器的渲染操做,使頁面加載時間更長,形成頁面停滯。
二、dom操做在頁面加載完畢以前可能出錯。
- how
將腳本定義或引用放置到<body>
底部。
<script defer="defer">
defer 屬性規定是否對腳本執行進行延遲, 腳本將在頁面完成解析時執行。
8.避免使用CSS表達式
- why
- css表達式可能會運算不少遍。
- 更加符合標準。
- 更加有利於性能提高。
- 減小受攻擊面。
- how
爲了實現動態的css,可使用JavaScript來控制。
e.g.
<script src="Scripts/jquery-2.0.0.min.js"></script>
<script>
$(function () {
$("body").css("background-color", (new Date()).getHours() % 2 ? "#B8D4FF" : "#F08A00");
});
</script>
9.將CSS和JS放到外部文件中
- why
一、提升了腳本文件和樣式表的複用性。(無需再每一個頁面中都定義一次)
二、減小了頁面體積,能夠提升頁面加載速度。(腳本文件和樣式表能夠被瀏覽器單獨緩存)
三、提升了腳本和樣式表的可維護性。(這個雖然與性能無關,但其實也是很重要的)
缺點:由於有單獨的文件,因此可能會增長額外的請求。這違背了減小HTTP請求的原則。
- how
<link rel="stylesheet" href="style.css" type="text/css" />
<script src="myjs.js" type="text/javascript" />
10.權衡DNS查找次數
- why
查找DNS是須要花費時間的,經驗的總結是至少須要20毫秒左右的時間。在此期間,瀏覽器是沒法下載其餘任何內容資源的。因此瀏覽器會想辦法對DNS的查找結果進行緩存。而除了瀏覽器的緩存以外,操做系統也會對DNS查詢的結果作緩存。只不過,因爲瀏覽器使用太過頻繁,目前的主流瀏覽器都使用本身獨有的緩存,而不使用操做系統的緩存。
不一樣瀏覽器在緩存DNS的問題上也不盡相同(主要體如今時間上面)。
一、緩存時間較長,有利於重複利用DNS緩存,提升速度。
二、緩存時間較短,有利於及時地檢測到目標站點的IP地址更新,以進行正確的訪問。
- how
一、因爲DNS查找須要時間,並且只緩存必定時間,因此應該儘量地減小DNS查找的次數。
二、減小DNS查找次數,最理想的方法就是把因此的內容資源都放在同一個域(Domain)中,這樣訪問整個網站就只須要進行一次DNS查找,這樣能夠提升性能,節省響應時間。
三、HTTP/1.1中推薦客戶端針對每個域只有必定數量的並行度(它的建議是2),那麼就會出現下載資源的排隊現象,這樣就會下降性能。
四、折衷的作法:在一個網站裏面使用至少2個域,但很少於4個域來提供資源。
11.精簡CSS和JS
- why
儘量減小這兩種文件的體積,以便加快下載速度。
e.g.
一、去除沒必要要的格式符、空白符、註釋符。這個操做,能夠理解爲是一種格式化,雖然它操做的結果實際上是去除掉原始文件的那些格式。
二、模糊(obfuscation)處理JavaScript腳本源代碼。
- how
工具:
一、JSMin:能夠對JavaScript進行最小化處理
二、YUI Compressor:能夠對JavaScript進行壓縮,也能夠對CSS進行壓縮(java工具)。在線版本 Online JavaScript/CSS/HTML Compressor
三、JSLint:檢查腳本語法合法性工具
四、Absolute HTML Compressor:HTML最小化處理工具(主要是格式化)。
12.避免重定向
why
重定向的意思是,用戶的原始請求(例如請求A)被重定向到其餘的請求(例如請求B)。這是HTTP世界中原本就存在的技術和現象,它自己沒有所謂的好和壞,它的存在也確實有其理由,爲此HTTP協議中,規定了兩個狀態碼來標識着中場景。他們分別是:
301 Moved Permanently
,這個狀態碼標識用戶所請求的資源被移動到了另外的位置,客戶端接收到此響應後,須要發起另一個請求去下載所需的資源。
302 Found
,這個狀態碼標識用戶所請求的資源被找到了,但不在原始位置,服務器會回覆其餘的一個位置,客戶端收到此響應後,也須要發起另一個請求去下載所需的資源。
目前咱們一直只要區分301和302便可。他們本質上的區別究竟是什麼呢?301表示永久重定向,302表示臨時重定向。
凡是訪問地址中,沒有帶文件名後綴的(例如aspx,asp等等),服務器都會嘗試解析爲一個文件夾,自動加上一個路徑斜線,而後再查找內部的默認頁面。
重定向是沒法徹底避免的,適當的使用重定向能爲網站提供更好的功能。(例如本地化,用戶體驗等方面)。 可是過多的進行重定向也確定會給網站性能帶來顯著的印象。
how
在定義連接地址的href屬性的時候,儘可能使用最完整的、直接的地址。例如:
使用 www.cnblogs.com
而不是cnblogs.com
使用cn.bing.com
而不是bing.com
使用www.google.com.hk
而不是google.com
使用www.mysite.com/products/
而不是www.mysite.com/products
13.刪除重複的JS和CSS
- why
在一個頁面中重複引用一個腳本可能存在的問題:瀏覽器會重複下載並執行腳本文件。
- how
對腳本進行有效的管理,並在編寫頁面的時候,仔細的進行引用。
- why
ETag,全程爲:Entity Tag,意思是實體標籤,它屬於HTTP協議的一部分,也就是全部的Web服務器都應該支持這個特性。它的做用是用一個特殊的字符串來標識某個資源的「版本」,客戶端(瀏覽器)請求的時候,比較ETag若是一致,則表示該資源並無被修改過,客戶端(瀏覽器)可使用本身緩存的版本,避免重複下載。
它比last-modified date更具備彈性,例如某個文件在1秒內修改了10次,Etag能夠綜合Inode(文件的索引節點(inode)數),MTime(修改時間)和Size來精準的進行判斷,避開UNIX記錄MTime只能精確到秒的問題。 服務器集羣使用,可取後兩個參數。使用ETags減小Web應用帶寬和負載。
另外,下面對比Expires、Cache-Control、ETag。
15.可緩存的AJAX
why
AJAX=Asynchronous JavaScript And XML,AJAX不是新的編程語言,而是一種使用現有標準的新方法。
AJAX是與服務器交換數據並更新部分網頁的藝術,在不從新加載整個頁面的狀況下。
因爲AJAX其實也是須要發起請求,而後服務器執行,並將結果(一般是JSON格式的)發送給瀏覽器進行最後的呈現或者處理,因此對於網站設計優化的角度而言,咱們一樣須要考慮對這些請求,是否能夠儘量的利用到緩存的功能來提升性能。
- how
對於AJAX而言,有一些特殊性,並非全部的AJAX請求都是能夠緩存的。
一、POST的請求,是不能夠在客戶端緩存的,每次請求都須要發送給服務器進行處理,每次都會返回狀態碼200。(這裏能夠優化的是,服務器端對數據進行緩存,以便提升處理速度)
二、GET的請求,是能夠(而且默認)在客戶端進行緩存的,除非指定了不一樣的地址,不然同一地址的AJAX請求,不會重複再服務器執行,而是返回304。
有的時候,咱們可能但願GET請求不被緩存,有幾種作法來達到這樣的目的。
一、每次調用的時候,請求不一樣的地址(能夠在原始地址後面添加一個隨機的號碼)。
二、若是你所使用的是jquery的話,則能夠考慮禁用AJAX的緩存。
$.ajaxSetup({ cache: false });
16.使用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.
17.減小DOM元素數量
18.避免404
404 意味着Not Found,意思是說未找到資源。既然如此,那麼至少會有兩種緣由致使404錯誤:
- 該資源按理說是要有,但咱們沒有提供。用戶按照正常的方式來請求,因此資源找不到。
- 該資源原本就不存在,用戶按照不正常的方式來請求,固然仍是找不到。
404會有什麼影響
看不到的影響:有時候,404錯誤發生了,用戶可能根本沒有感受到。例如
- 例如請求favicon.ico文件,或者請求了某個不存在的腳本文件、樣式表、圖片文件,頁面仍是會按照正常的方式進行呈現。
- 丟失的腳本文件、樣式表、圖片文件,會致使頁面的某些行爲、界面效果出現異常(也可能不是很明顯)
- 最大的問題多是性能方面的影響。尤爲是若是請求一個不存在的腳本文件,由於瀏覽器在請求腳本文件的時候,即使是返回404,它也會嘗試去按照Javascript的方式解析響應中的內容。這無疑會增長不少處理的時間,而由於該文件不存在,因此這些都是無用功。
看獲得的影響:
19.減小cookie的大小
- why
若是對某個域(Domain)保存了Cookie,那麼針對這個域的全部請求,都會發送這些全部的Cookie(哪怕當前請求根本用不着,例如針對圖片的請求),大量的、重複的發送Cookie毫無疑問會增長網絡的流量,並所以而下降請求被執行的性能。
- how
從技術上上拉說,這個文件的內容是由網站控制的,它能夠決定要寫什麼內容在裏面,他也能夠決定是否要加密。惟一的一個限制,這個文件的體積不容許超過4KB。
20.使用無cookie的域
- why
好比圖片 CSS 等,Yahoo! 的靜態文件都在主域名之外,客戶端請求靜態文件的時候,減小了 Cookie的反覆傳輸對主域名的影響。
只有訪問主域名的時候才須要保存cookie,而cookie會自動地發送給當前域的全部請求。
21.不要使用濾鏡
- why
Filters這個功能是IE當年爲了提供更加豐富的一些頁面效果而設計出來的。
不只僅是別的瀏覽器可能不支持,IE從9.0版本開始也放棄了這方面的支持。
22.不要在HTML中縮放圖片
- why
有時獲得的圖片尺寸和具體顯示尺寸不同,爲了在網頁中顯示出但願的尺寸,一般會經過下面的方法把圖片進行縮放:
<img width="100" height="100" src="pic.jpg" alt="my pic"/>
瀏覽器下載到原始圖片以後,若是原始尺寸與目標尺寸不符,就會須要對圖片進行縮放(拉伸或者縮小),以便實現剛纔所提到的目的。
- how
咱們須要在網頁中顯示什麼尺寸的圖片,就請圖片設計人員提供什麼尺寸的圖片,而不是在網頁中進行縮放。
23.縮小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。