首先,先說一下爲何要進行前端優化?
當咱們打開一個網頁時,事實上,只有10%-20%的最終用戶響應時間是花在從web服務器獲取HTML文檔並傳送到瀏覽器的,至少80%的最終用戶響應時間是花在了頁面中的組件上(圖片、腳本、樣式表、Flash等)、太慢的網站常常會形成訪客再也不回返,所以,把精力放在這80%的時間能夠極大的改善web的性能。而請求組件須要伴隨着HTTP請求,而減小HTTP請求、減少HTTP請求大小等都是改善web性能的最佳實踐
下面,讓咱們來學學雅虎的14條軍規把~
一、規則1:減小HTTP請求
改善響應時間的最簡單途徑就是減小組件(圖片,腳本,樣式表、Flash等)的數量,並由此減小http請求的數量
(1)CSS Sprites:將多個圖片合併到一個單獨的圖片中,再結合css的background-position屬性一塊兒使用,經過合併圖片減小http請求(合併後的圖片會比分離的圖片的總和要小,由於它下降了圖片自身的開銷(顏色表,格式信息等))
適用場景:若須要在頁面中爲背景,按鈕,導航欄,連接等提供大量圖片,可以使用CSS Sprites
(2)合併腳本和樣式表:若將css代碼和javascript代碼分別放在多個文件中,每一個文件都會致使一個額外的http請求,將這些文件合併到一個文件中,能夠減小http請求的數量並縮短最終用戶時間
注:若不一樣頁面須要不一樣的腳本,可能腳本合併的組合數會比較多
二、規則2:使用內容發佈網絡
一般來講,Web客戶端離當前Web服務器越近,響應時間會更快
(1)內容發佈網絡:內容發佈網絡是一組分佈在多個不一樣地理位置的Web服務器,用於更加有效地向用戶發佈內容
(2)一些大型公司都擁有他們本身的CDN,但使用一個CDN服務提供商更爲有效
優勢:對於地理上分散的用戶人羣來講,CDN能輕易地獲得響應速度上的提升
除了縮短響應時間以外,CDN還提供備份,擴展存儲功能和進行緩存等服務
缺點:CDN服務開銷可能比較大,且CDN服務提供商在其全部客戶之間共享其Web服務組,可能會受到其它網站流量的影響
沒法直接控制組件服務器所帶來的特殊麻煩,如修改HTTP響應頭必須經過服務器提供商來完成
三、規則3:添加Expires頭
(1)主要經過配置組件,使用一個長久的Expires頭,使這些組件可以被緩存,使在後續的頁面瀏覽中避免沒必要要的http請求(瀏覽器能夠直接從硬盤上讀取組件而無需生成任何http流量),web服務器使用Expires頭來告訴web客戶端它可使用一個組件的當前副本,直到指定的時間爲止
(2)長久的Expires頭最經常使用於圖片,但應該將其應用在全部組件上,包括腳本、樣式表和Flash等不常常變化的組件,但添加長久的Expires會帶來額外的開發成本
(3)瀏覽器(和代理)經過使用緩存來減小http請求的數量,並減少http響應的大小,從而使頁面加載得更快,Expires在http響應中發送,web服務器經過使用Expires頭來告訴Web客戶端它可使用一個組件的當前副本
(4)Expires頭的限制:Expires頭使用一個特定的時間,它要求服務器和客戶端的時鐘嚴格同步,另外,若是到了過時時間,須要在服務器配置中提供一個新的日期
(5)Cache-Control頭:http1.1引入的,主要用來克服Expires的限制
主要使用max-age指令指定組件被緩存多久
注:能夠同時指定Expires和Cache-Control兩個響應頭,由於有些瀏覽器不支持http1.1
(6)修訂文件名:
爲了確保用戶可以獲取組件的最新版本,須要在全部HTML頁面中修改組件的文件名
(7)一個具備長久的Expires頭的組件將會被緩存,在後續請求時瀏覽器直接從磁盤上讀取它,避免了一個http請求
若是一個組件沒有長久的Expires頭,它仍然會存儲在瀏覽器的緩存中,在後續請求中,瀏覽器會檢查緩存並發現組件以及過時。爲了提升效率,瀏覽器會向原始服務器發送一個條件GET請求,若是組件沒有改變,原始服務器能夠免於發送整個組件,而是發送一個很小的頭,告訴瀏覽器可使用其緩存的組件
四、規則4:壓縮組件(使用gzip編碼壓縮http響應包)
(1)主要經過http響應的大小來減小響應時間,從http1.1開始,Web客戶端能夠經過http請求中的Accept-Encoding來標識對壓縮的支持
若是Web服務器看到請求中有這個頭,就會使用客戶端列出來的方法中的一種來壓縮響應,Web服務器經過響應中的Content-Encoding頭來通知Web客戶端
(2)壓縮什麼:通常壓縮HTML文檔、樣式表和腳本
(3)壓縮的成本:服務器端會花費額外的CPU週期來完成壓縮,客戶端要對壓縮文件進行解壓縮
五、規則5:將樣式表放在頂部
(1)將樣式表放在底部,可能會延遲頁面的加載,會出現「白屏」和「無樣式閃爍」,將樣式表放在頂部,可使頁面逐步呈現,避免頁面出現」白屏「和「無樣式閃爍」
(2)白屏:瀏覽器延遲內容呈現,直到全部的樣式表都下載完畢後纔開始開始顯示內容,即頁面徹底空白,直到頁面全部內容同時涌上屏幕
無樣式閃爍:樣式表被正確地下載及解析,已經呈現的頁面和圖片要用新的樣式重繪
(3)link和@import:
注:使用@import規則可能會致使白屏現象,即便是放在<head>中
通常組件都是按照它們在頁面中出現的順序下載的,而使用@import會帶來下載時的無序性
六、規則6:將腳本放在底部
(1)將腳本放在底部,既可使頁面逐步呈現,也能夠提升下載的並行度
(2)將樣式表放在<head>中,能夠首先下載它們而不會阻止頁面呈現,使用腳本時,對於全部位於腳本如下的內容,逐步呈現都被阻塞了。將腳本放在頁面越靠下的地方,意味着越多的內容可以逐步地呈現
(3)http1.1建議瀏覽器從每一個主機名並行地下載兩個組件。然而,在下載腳本時並行下載實際上是被禁用的,即便是用了不一樣的主機名,瀏覽器也不會啓動其餘的下載
(4)腳本對web頁面的影響:腳本會阻塞其後面內容的呈現,腳本會阻塞其後面組件的下載(腳本會阻塞並行下載)
七、規則7:避免CSS表達式
(1)CSS表達式不僅在頁面呈現和大小改變時求值,當頁面滾動,甚至連用戶鼠標的頁面移動時都要求值
八、規則8:使用外部的JavaScript和CSS
(1)在某種程度上,內聯會快一些,儘管總下載量時是相同的,但外部示例須要承擔多個http請求帶來的開銷。可是現實中仍是使用外部文件會產生比較快的頁面,由於javascript和css文件有可能被瀏覽器緩存起來
(2)使用外部文件能夠提升組件的重用率
九、規則9:減小DNS查找
(1)Internet是經過IP地址來查找服務器的,因爲IP地址很難記憶,一般使用包含主機名的URL來代替它,但當瀏覽器發送其請求時,IP地址仍然是必需的,這就是Domain Name System(DNS)所處的角色。DNS將主機名映射到IP地址上,在輸入一個URL時,鏈接到瀏覽器的DNS解析器會返回服務器的IP地址
(2)DNS也是開銷,在DNS查找完成以前,瀏覽器不能從主機名那裏下載到任何東西,響應時間依賴於DNS解析器(一般由你的ISP提供)
(3)DNS緩存:DNS查找能夠被緩存起來以提升性能,在用戶請求了一個主機名後,DNS信息會留在操做系統的DNS緩存中,以後對於該主機名的請求將無需進行過多的DNS查找
(4)經過使用keep-Alive和較少的域名來減小DNS查找,keep-Alive經過重用現有鏈接避免了重複的DNS查找,減小惟一主機名的數量能夠減小DNS查找
(5)建議:能夠將組件分別放在至少2個,但不要超過4個主機名下,這是在減小DNS查找和容許高度並行下載之間做出的很好的權衡
十、規則10:精簡Javascript
(1)精簡是從代碼中移除沒必要要的字符以減少其大小進而改善加載時間,在代碼被精簡後,全部的註釋以及沒必要要的空白字符都將被移除
(2)內聯的javascript也應該被精簡
(3)精簡CSS可以帶來的節省一般要小於精簡javascript,由於css中的註釋和空白比javascript中的少,最大的潛在節省來自於優化CSS——合併相同的類,移除不適用的類等
十一、規則11:避免重定向
(1)重定向就是,在網頁上設置一個約束條件,條件知足,就自動轉入到其它網頁、網址
(2)重定向用於將用戶從一個url從新路由到另外一個url,重定向有不少種——301和302是最經常使用的兩種,重定向會使你的頁面變慢,javascript能夠經過document.location設置爲指望的URL執行重定向
(3)當web服務器向瀏覽器返回一個重定向時,響應中就會返回一個範圍在3xx的狀態碼,這表示用戶代理必需執行進一步操做才能完成請求
注:304並非真的重定向,它用來響應條件GET請求,避免下載已經存在於瀏覽器緩存中的數據
(4)重定向是如何損傷性能的:重定向會延遲整個HTML文檔的傳輸,在HTML文檔到達以前,頁面中不會呈現出任何東西,也沒有任何組件會被下載
十二、規則12:移除重複腳本
(1)重複腳本損傷性能的方式有兩種——沒必要要的HTTP請求和執行javascript所浪費的時間
(2)在頁面中屢次包含相同的腳本會使頁面變慢
在IE中,若是腳本沒有被緩存,或在從新加載頁面時,會產生額外的http請求
在火狐和IE中,腳本會被屢次求值
1三、規則13:配置ETag
(1)ETag(實體標籤)是web服務器和瀏覽器用於確認緩存組件的一種機制
(2)瀏覽器下載組件時,會將它們存儲到緩存中,在後續的頁面查看中,若是緩存的組件是「新鮮」的,瀏覽器就會從磁盤上讀取它,避免產生http請求,若是緩存的組件過時了(或者用戶明確地從新加載了頁面),瀏覽器在重用它以前必須首先檢查它是否仍然有效,這稱爲一個條件get請求,若是瀏覽器緩存中的組件是有效的(即它可以和原始服務器上的組件相匹配),原始服務器不會返回整個組件,而是返回一個304的狀態碼
(3)服務器在檢測緩存的組件是否和原始服務器上的組件匹配時有兩種方式:比較最新修改日期,比較實體標籤(ETag是惟一標識了一個組件的一個特定版本的字符串)
(4)ETag帶來的問題,當瀏覽器向一臺服務器獲取了原始組件,又向另外一臺不一樣的服務器發起條件get請求時,ETag是不會匹配的
(5)即便組件具備長久的Expires頭,一旦用戶單擊了Reload或Refresh按鈕。依然會產生條件get請求
1四、規則14:使Ajax可緩存