一、減少HTTP請求
1.圖片地圖:
假設導航欄上有五幅圖片,點擊每張圖片都會進入一個鏈接,這樣五張導航的圖片在加載時會產生5個HTTP請求。然而,使用一個圖片地圖可以提高效率,這樣就只需要一個HTTP請求。
?
?
服務器端圖片地圖:將所有點擊提交到同一個url,同時提交用戶點擊的x、y坐標,服務器端根據坐標映射響應
客戶端圖片地圖:直接將點擊映射到操作
<img src="planets.jpg" border="0" usemap="#planetmap" alt="Planets" /><map name="planetmap" id="planetmap"><area shape="rect" coords="180,139,14" href ="venus.html" alt="Venus" /><area shape="rect" coords="129,161,10" href ="mercur.html" alt="Mercury" /><area shape="rect" coords="0,0,110,260" href ="sun.html" alt="Sun" /><area shape="rect" coords="140,0,110,260" href ="star.html" alt="Sun" />
</map>
使用圖片地圖的缺點:指定坐標區域時,矩形或圓形比較容易指定,而其它形狀手工指定比較難
?
2.CSS Sprites
CSS Sprites直譯過來就是CSS精靈,但是這種翻譯顯然是不夠的,其實就是通過將多個圖片融合到一副圖里面,然后通過CSS的一些技術布局到網頁上。特別是圖片特別多的網站,如果能用css sprites降低圖片數量,帶來的將是速度的提升。
?
<div><span id="image1" class="nav"></span><span id="image2" class="nav"></span><span id="image3" class="nav"></span><span id="image4" class="nav"></span><span id="image5" class="nav"></span>
</div>
?
.nav {width: 50px;height: 50px;display: inline-block;border: 1px solid #000;background-image: url('E:/1.png');
}
#image1 {background-position: 0 0;
}
#image2 {background-position: -95px 0;
}
#image3 {background-position: -185px 0;
}
#image4 {background-position: -275px 0;
}
#image5 {background-position: -366px -3px;
}
?
運行結果:
PS:使用CSS Sprites還有可能降低下載量,可能大家會認為合并后的圖片會比分離圖片的總和要大,因為還有可能會附加空白區域。實際上,合并后的圖片會比分離的圖片總和要小,因為它降低了圖片自身的開銷,譬如顏色表、格式信息等。
?
3.字體圖標
在可以大量使用字體圖標的地方我們可以盡可能使用字體圖標,字體圖標可以減少很多圖片的使用,從而減少http請求,字體圖標還可以通過CSS來設置顏色、大小等樣式,何樂而不為。
?
4.合并js和css
將多個樣式表或者腳本文件合并到一個文件中,可以減少HTTP請求的數量從而縮短效應時間。
然而合并所有文件對許多人尤其是編寫模塊化代碼的人來說是不能忍的,而且合并所有的樣式文件或者腳本文件可能會導致在一個頁面加載時加載了多于自己所需要的樣式或者腳本,對于只訪問該網站一個(或幾個)頁面的人來說反而增加了下載量,所以大家應該自己權衡利弊。
?
二、使用CDN
如果應用程序web服務器離用戶更近,那么一個HTTP請求的響應時間將縮短。另一方面,如果組件web服務器離用戶更近,則多個HTTP請求的響應時間將縮短。
CDN(內容發布網絡)是一組分布在多個不同地理位置的Web服務器,用于更加有效地向用戶發布內容。在優化性能時,向特定用戶發布內容的服務器的選擇基于對網絡慕課擁堵的測量。例如,CDN可能選擇網絡階躍數最小的服務器,或者具有最短響應時間的服務器。
CDN還可以進行數據備份、擴展存儲能力,進行緩存,同時有助于緩和Web流量峰值壓力。
CDN的缺點:
1、響應時間可能會受到其他網站流量的影響。CDN服務提供商在其所有客戶之間共享Web服務器組。
2、如果CDN服務質量下降了,那么你的工作質量也將下降
3、無法直接控制組件服務器
?
三、添加Expires頭
頁面的初次訪問者會進行很多HTTP請求,但是通過使用一個長久的Expires頭,可以使這些組件被緩存,下次訪問的時候,就可以減少不必要的HTPP請求,從而提高加載速度。
Web服務器通過Expires頭告訴客戶端可以使用一個組件的當前副本,直到指定的時間為止。例如:
Expires:?Fri, 18 Mar 2016 07:41:53 GMT
Expires缺點: 它要求服務器和客戶端時鐘嚴格同步;過期日期需要經常檢查
HTTP1.1中引入Cache-Control來克服Expires頭的限制,使用max-age指定組件被緩存多久。
Cache-Control: max-age=12345600
若同時制定Cache-Control和Expires,則max-age將覆蓋Expires頭
?
四、壓縮組件
從HTTP1.1開始,Web客戶端可以通過HTTP請求中的Accept-Encoding頭來表示對壓縮的支持
Accept-Encoding: gzip,deflate
如果Web服務器看到請求中有這個頭,就會使用客戶端列出來的方法中的一種來進行壓縮。Web服務器通過響應中的Content-Encoding來通知 Web客戶端。
Content-Encoding: gzip
代理緩存
當瀏覽器通過代理來發送請求時,情況會不一樣。假設針對某個URL發送到代理的第一個請求來自于一個不支持gzip的瀏覽器。這是代理的第一個請求,緩存為空。代理將請求轉發給服務器。此時響應是未壓縮的,代理緩存同時發送給瀏覽器。現在,假設到達代理的請求是同一個url,來自于一個支持gzip的瀏覽器。代理會使用緩存中未壓縮的內容進行響應,從而失去了壓縮的機會。相反,如果第一個瀏覽器支持gzip,第二個不支持,你們代理緩存中的壓縮版本將會提供給后續的瀏覽器,而不管它們是否支持gzip。
解決辦法:在web服務器的響應中添加vary頭Web服務器可以告訴代理根據一個或多個請求頭來改變緩存的響應。因為壓縮的決定是基于Accept-Encoding請求頭的,因此需要在vary響應頭中包含Accept-Encoding。
? vary:?Accept-Encoding
?
五、將樣式表放在頭部
首先說明一下,將樣式表放在頭部對于實際頁面加載的時間并不能造成太大影響,但是這會減少頁面首屏出現的時間,使頁面內容逐步呈現,改善用戶體驗,防止“白屏”。
我們總是希望頁面能夠盡快顯示內容,為用戶提供可視化的回饋,這對網速慢的用戶來說是很重要的。
將樣式表放在文檔底部會阻止瀏覽器中的內容逐步出現。為了避免當樣式變化時重繪頁面元素,瀏覽器會阻塞內容逐步呈現,造成“白屏”。這源自瀏覽器的行為:如果樣式表仍在加載,構建呈現樹就是一種浪費,因為所有樣式表加載解析完畢之前務虛會之任何東西
?
六、將腳本放在底部
跟樣式表相同,腳本放在底部對于實際頁面加載的時間并不能造成太大影響,但是這會減少頁面首屏出現的時間,使頁面內容逐步呈現。
js的下載和執行會阻塞Dom樹的構建(嚴謹地說是中斷了Dom樹的更新),所以script標簽放在首屏范圍內的HTML代碼段里會截斷首屏的內容。
下載腳本時并行下載是被禁用的——即使使用了不同的主機名,也不會啟用其他的下載。因為腳本可能修改頁面內容,因此瀏覽器會等待;另外,也是為了保證腳本能夠按照正確的順序執行,因為后面的腳本可能與前面的腳本存在依賴關系,不按照順序執行可能會產生錯誤。
?
七、使用外部的JavaScript和CSS
內聯腳本或者樣式可以減少HTTP請求,按理來說可以提高頁面加載的速度。然而在實際情況中,當腳本或者樣式是從外部引入的文件,瀏覽器就有可能緩存它們,從而在以后加載的時候能夠直接使用緩存,而HTML文檔的大小減小,從而提高加載速度。
影響因素:
1、每個用戶產生的頁面瀏覽量越少,內聯腳本和樣式的論據越強勢。譬如一個用戶每個月只訪問你的網站一兩次,那么這種情況下內聯將會更好。而如果該用戶能夠產生很多頁面瀏覽量,那么緩存的樣式和腳本將會極大減少下載的時間,提交頁面加載速度。
2、如果你的網站不同的頁面之間使用的組件大致相同,那么使用外部文件可以提高這些組件的重用率。
?
?
八、減少DNS查找
當我們在瀏覽器的地址欄輸入網址(譬如: www.linux178.com) ,然后回車,回車這一瞬間到看到頁面到底發生了什么呢?
域名解析 --> 發起TCP的3次握手 --> 建立TCP連接后發起http請求 --> 服務器響應http請求,瀏覽器得到html代碼 --> 瀏覽器解析html代碼,并請求html代碼中的資源(如js、css、圖片等) --> 瀏覽器對頁面進行渲染呈現給用戶。
DNS也是開銷,通常瀏覽器查找一個給定域名的IP地址要花費20~120毫秒,在完成域名解析之前,瀏覽器不能從服務器加載到任何東西。那么如何減少域名解析時間,加快頁面加載速度呢?
當客戶端DNS緩存(瀏覽器和操作系統)緩存為空時,DNS查找的數量與要加載的Web頁面中唯一主機名的數量相同,包括頁面URL、腳本、樣式表、圖片、Flash對象等的主機名。減少主機名的 數量就可以減少DNS查找的數量。
減少唯一主機名的數量會潛在減少頁面中并行下載的數量(HTTP 1.1規范建議從每個主機名并行下載兩個組件,但實際上可以多個),這樣減少主機名和并行下載的方案會產生矛盾,需要大家自己權衡。建議將組件放到至少兩個但不多于4個主機名下,減少DNS查找的同時也允許高度并行下載。
?
九、精簡JavaScript
精簡
精簡就是從代碼中移除不必要的字符以減少文件大小,降低加載的時間。代碼精簡的時候會移除不必要的空白字符(空格,換行、制表符),這樣整個文件的大小就變小了。
網上有很多在線壓縮,可以嘗試一下。
在以上提到了關于用gzip之類的壓縮方式來壓縮文件,這邊說明一下,就算使用gzip等方式來壓縮文件,精簡代碼依然是有必要的。一般來說,壓縮產生的節省是高于精簡的,在生產環境中,精簡和壓縮同時使用能夠最大限度的獲得更多的節省。
?
十、避免重定向
什么是重定向?
重定向用于將用戶從一個URL重新路由到另一個URL。
常用重定向的類型
301:永久重定向,主要用于當網站的域名發生變更之后,告訴搜索引擎域名已經變更了,應該把舊域名的的數據和鏈接數轉移到新域名下,從而不會讓網站的排名因域名變更而受到影響。
302:臨時重定向,主要實現post請求后告知瀏覽器轉移到新的URL。
304:Not Modified,主要用于當瀏覽器在其緩存中保留了組件的一個副本,同時組件已經過期了,這是瀏覽器就會生成一個條件GET請求,如果服務器的組件并沒有修改過,則會返回304狀態碼,同時不攜帶主體,告知瀏覽器可以重用這個副本,減少響應大小。
?
重定向如何損傷性能?
當頁面發生了重定向,就會延遲整個HTML文檔的傳輸。在HTML文檔到達之前,頁面中不會呈現任何東西,也沒有任何組件會被下載。
來看一個實際例子:對于ASP.NET webform開發來說,對于新手很容易犯一個錯誤,就是把頁面的連接寫成服務器控件后臺代碼里,例如用一個Button控件,在它的后臺click事件中寫上:Response.Redirect("");然而這個Button的作用只是轉移URL,這是非常低效的做法,因為點擊Button后,先發送一個Post請求給服務器,服務器處理Response.Redirect("")后就發送一個302響應給瀏覽器,瀏覽器再根據響應的URL發送GET請求。正確的做法應該是在html頁面直接使用a標簽做鏈接,這樣就避免了多余的post和重定向。
?
重定向的應用場景
1. 跟蹤內部流量
重定向經常用于跟蹤用戶流量的方向,當擁有一個門戶主頁的時候,同時想對用戶離開主頁后的流量進行跟蹤,這時可以使用重定向。例如: 某網站主頁新聞的鏈接地址http://a.com/r/news,點擊該鏈接將產生301響應,其Location被設置為http://news.a.com。通過分析a.com的web服務器日志可以得知人們離開首頁之后的去向。
我們知道重定向是如何損傷性能的,為了實現更好的效率,可以使用Referer日志來跟蹤內部流量去向。每個HTTP請求都有一個Referer表示原始請求頁(除了從書簽打開或直接鍵入URL等操作),記錄下每個請求的Referer,就避免了向用戶發送重定向,從而改善了響應時間。
?
2. 跟蹤出站流量
有時鏈接可能將用戶帶離你的網站,在這種情況下,使用Referer就不太現實了。
同樣也可以使用重定向來解決跟蹤出站流量問題。以百度搜索為例,百度通過將每個鏈接包裝到一個302重定向來解決跟蹤的問題,例如搜索關鍵字“前端性能優化”,搜索結果中的一個URL為https://www.baidu.com/link?url=pDjwTfa0IAf_FRBNlw1qLDtQ27YBujWp9jPN4q0QSJdNtGtDBK3ja3jyyN2CgxR5aTAywG4SI6V1NypkSyLISWjiFuFQDinhpVn4QE-uLGG&wd=&eqid=9c02bd21001c69170000000556ece297,即使搜索結果并沒有變,但這個字符串是動態改變的,暫時還不知道這里起到怎樣的作用?(個人感覺:字符串中包含了待訪問的網址,點擊之后會產生302重定向,將頁面轉到目標頁面(待修改,求大神們給我指正))
除了重定向外,我們還可以選擇使用信標(beacon)——一個HTTP請求,其URL中包含有跟蹤信息。跟蹤信息可以從信標Web服務器的訪問日記中提取出來,信標通常是一個1px*1px的透明圖片,不過204響應更優秀,因為它更小,從來不被緩存,而且絕不會改變瀏覽器的狀態。
?
十一、刪除重復腳本
在團隊開發一個項目時,由于不同開發者之間都可能會向頁面中添加頁面或組件,因此可能相同的腳本會被添加多次。
重復的腳本會造成不必要的HTTP請求(如果沒有緩存該腳本的話),并且執行多余的JavaScript浪費時間,還有可能造成錯誤。
?
十二、使Ajax可緩存
?
異步與即時
Ajax的一個明顯的有點就是向用戶提供了即時反饋,因為它異步的從后端web服務器請求信息。
用戶是否需要等待的關鍵因素在于Ajax請求是被動的還是主動的。被動請求是為了將來來使用而預先發起的,主動請求是基于用戶當前的操作而發起的
什么樣的AJAX請求可以被緩存?
POST的請求,是不可以在客戶端緩存的,每次請求都需要發送給服務器進行處理,每次都會返回狀態碼200。(可以在服務器端對數據進行緩存,以便提高處理速度)
GET的請求,是可以(而且默認)在客戶端進行緩存的,除非指定了不同的地址,否則同一個地址的AJAX請求,不會重復在服務器執行,而是返回304。
Ajax請求使用緩存
在進行Ajax請求的時候,可以選擇盡量使用get方法,這樣可以使用客戶端的緩存,提高請求速度。
?
如果是原創文章,轉載請注明出處:http://www.cnblogs.com/MarcoHan/?