1. Content
1.1 Make Fewer HTTP Requests
Minimize HTTP Requests減少/最小化 http 請求數(shù)。
到終端用戶的響應(yīng)時(shí)間80%花在前端:大部分用于下載組件(js/css/image/flash等等)翅楼。減少組件數(shù)就是減少渲染頁面所需的http請求數(shù)援所。這是更快頁面的關(guān)鍵。
減少組件數(shù)的一個方法就是簡化頁面設(shè)計(jì)桐玻。保持富內(nèi)容的頁面且能減少http請求,有以下幾個技術(shù):
- Combined files闺骚。合并文件素标,如合并js瘸右,合并css都能減少請求數(shù)。如果頁面間腳本和樣式差異很大岩齿,合并會更具挑戰(zhàn)性太颤。
- CSS Sprites。雪碧圖可以合并多個背景圖片盹沈,通過
background-image
和background-position
來顯示不同部分龄章。 - Image maps。合并多個圖片到一個圖片乞封,一般用于如導(dǎo)航條做裙。由于定義坐標(biāo)的枯燥和易錯,一般不推薦肃晚。
- Inline images锚贱。使用
data:url scheme
來內(nèi)連圖片。
減少請求數(shù)是為第一次訪問頁面的用戶提高性能的最重要的指導(dǎo)关串。
1.2 Reduce DNS Lookups
減少DNS查詢拧廊。
就像電話簿监徘,你在瀏覽器地址欄輸入網(wǎng)址,通過DNS查詢得到網(wǎng)站真實(shí)IP吧碾。
DNS查詢被緩存來提高性能凰盔。這種緩存可能發(fā)生在特定的緩存服務(wù)器(ISP/local area network維護(hù)),或者用戶的計(jì)算機(jī)倦春。DNS信息留存在操作系統(tǒng)DNS緩存中(在windows中就是 DNS Client Serve )户敬。大多瀏覽器有自己的緩存,獨(dú)立于操作系統(tǒng)緩存睁本。只要瀏覽器在自己的緩存里有某條DNS記錄尿庐,它就不會向操作系統(tǒng)發(fā)DNS解析請求。
IE默認(rèn)緩存DNS記錄30分鐘添履,F(xiàn)ireFox默認(rèn)緩存1分鐘屁倔。
當(dāng)客戶端的DNS緩存是空的,DNS查找次數(shù)等于頁面中的唯一域名數(shù)暮胧。
減少DNS請求數(shù)可能會減少并行下載數(shù)锐借。避免DNS查找減少響應(yīng)時(shí)間,但減少并行下載數(shù)可能會增加響應(yīng)時(shí)間往衷。指導(dǎo)原則是組件可以分散在至少2個但不多于4個的不同域名钞翔。這是兩者的妥協(xié)。
1.3 Avoid Redirects
避免跳轉(zhuǎn)席舍。
跳轉(zhuǎn)用301
或302
狀態(tài)碼來達(dá)成布轿。一個301
響應(yīng)http頭的例子:
HTTP/1.1 301 Moved Permanently
Location: http://example.com/newuri
Content-Type: text/html
瀏覽器自動跳轉(zhuǎn)到Location
指定的路徑。跳轉(zhuǎn)所需的所有信息都在http頭来颤,所以http主體一般是空的汰扭。301``302
響應(yīng)一般不會被緩存,除非有額外的頭部信息福铅,比如Expires
或Cache-Control
指定要緩存萝毛。meta
刷新標(biāo)簽或 JavaScript 也可以跳轉(zhuǎn),但如果真要跳轉(zhuǎn)滑黔,3xx
跳轉(zhuǎn)更好笆包,主要是保證返回鍵可用。
跳轉(zhuǎn)顯然拖慢響應(yīng)速度略荡。在跳轉(zhuǎn)的頁面被獲取前瀏覽器沒什么能渲染庵佣,沒什么組件能下載。
最浪費(fèi)的跳轉(zhuǎn)之一發(fā)生在url尾部slash(/)缺失汛兜。比如http://astrology.yahoo.com/astrology
會301
跳轉(zhuǎn)到http://astrology.yahoo.com/astrology/
巴粪。這可以被Apache等服務(wù)器修復(fù),用Alias
,mod_rewrite
等等验毡。
1.4 Make Ajax Cacheable
讓Ajax可緩存衡创。
使用ajax的好處是可以向用戶提供很快的反饋,因?yàn)樗窍蚝笈_異步請求數(shù)據(jù)晶通。但是璃氢,這些異步請求不保證用戶等待的時(shí)間——異步不意味著瞬時(shí)。
提高ajax性能的最重要的方法是讓響應(yīng)被緩存狮辽,即在Add an Expires or a Cache-Control Header中討論的 Expires 一也。其它方法是:
- gzip組件
- 減少DNS查找
- 壓縮JS
- 避免跳轉(zhuǎn)
- 設(shè)置ETags
1.5 Post-load Components
延遲加載組件。
再看看你的頁面然后問問自己喉脖,“什么是頁面初始化必須的椰苟?”。剩下的內(nèi)容和組件可以延遲树叽。
JavaScript是理想的(延遲)候選者舆蝴,可以切分到onload
事件之前和之后。比如拖放的js庫可以延遲题诵,因?yàn)橥蟿颖仨氃陧撁娉跏蓟蠼嗾獭F渌裳舆t的包括隱藏的內(nèi)容,折疊起來的圖片等等性锭。
1.6 Preload Components
預(yù)加載組件赠潦。
預(yù)加載看起來與延遲加載相反,但它的確有個不同的目標(biāo)草冈。通過預(yù)加載你可以利用瀏覽器的空閑時(shí)間來請求你將來會用到的組件她奥。這樣當(dāng)用戶訪問下一個頁面時(shí),你會有更多的組件已經(jīng)在緩存中怎棱,這樣會極大加快頁面加載哩俭。
有幾種預(yù)加載類型:
- 無條件預(yù)加載:一旦
onload
觸發(fā),你立即獲取另外的組件拳恋。比如谷歌會在主頁這樣加載搜索結(jié)果頁面用到的雪碧圖凡资。 - 有條件預(yù)加載:基于用戶動作,你推測用戶下一步會去哪里并加載相應(yīng)組件诅岩。
- 預(yù)期的預(yù)加載:在發(fā)布重新設(shè)計(jì)(的網(wǎng)站)前提前加載。在舊網(wǎng)頁預(yù)加載新網(wǎng)頁的部分組件带膜,那么切換到新網(wǎng)頁時(shí)就不會是沒有任何緩存了吩谦。
1.7 Reduce the Number of DOM Elements
減少dom數(shù)。
一個復(fù)雜的頁面意味著更多的內(nèi)容要下載膝藕,以及更慢的dom訪問式廷。比如在有500dom數(shù)量的頁面添加事件處理就和有5000dom數(shù)量的不同。
如果你的頁面dom元素很多芭挽,那么意味著你可能需要刪除無用的內(nèi)容和標(biāo)簽來優(yōu)化滑废。
1.8 Split Components Across Domains
把組件分散到不同的域名蝗肪。
把組件分散到不同的域名允許你最大化并行下載數(shù)。由于DNS查詢的副作用蠕趁,最佳的不同域名數(shù)是2-4薛闪。
1.9 Minimize the Number of iframes
最小化iframe的數(shù)量。
iframe允許html文檔被插入到父文檔俺陋。
<iframe>
優(yōu)點(diǎn):
- 幫助解決緩慢的第三方內(nèi)容的加載豁延,如廣告和徽章
- 安全沙盒
- 并行下載腳本
<iframe>
缺點(diǎn):
- 即使空的也消耗(資源和時(shí)間)
- 阻塞了頁面的
onload
- 非語義化(標(biāo)簽)
1.10 No 404s
不要404。
http請求是昂貴的腊状,所以發(fā)出http請求但獲得沒用的響應(yīng)(如404)是完全不必要的诱咏,并且會降低用戶體驗(yàn)。
一些網(wǎng)站會有特別的404頁面提高用戶體驗(yàn)缴挖,但這仍然會浪費(fèi)服務(wù)器資源袋狞。特別壞的是當(dāng)鏈接指向外部js但卻得到404結(jié)果。這樣首先會降低(占用)并行下載數(shù)映屋,其次瀏覽器可能會把404響應(yīng)體當(dāng)作js來解析苟鸯,試圖從里面找出可用的東西。
2. Server
2.1 Use a Content Delivery Network
使用CDN秧荆。
用戶接近你的服務(wù)器會減少響應(yīng)時(shí)間倔毙。把你的內(nèi)容發(fā)布到多個,地理上分散的服務(wù)器可以讓頁面加載更快乙濒。但怎么開始陕赃?
首先不要試圖把你的架構(gòu)重新設(shè)計(jì)成分布式架構(gòu)。因?yàn)榭赡芤M(jìn)更多復(fù)雜性和不可控颁股。
記住80-90%的終端用戶響應(yīng)時(shí)間花費(fèi)在下載頁面中的所有組件:圖片么库、樣式、腳本甘有、falsh等等诉儒。這是Performance Golden Rule。不要從困難的重新設(shè)計(jì)后臺架構(gòu)開始亏掀,最好首先分發(fā)你的靜態(tài)內(nèi)容忱反。這不僅可以減少響應(yīng)時(shí)間,用CDN還很容易來做滤愕。
CDN是一群不同地點(diǎn)的服務(wù)器温算,可以更高效地分發(fā)內(nèi)容到用戶。一些大公司有自己的CDN间影。
2.2 Add an Expires or a Cache-Control Header
加Expires
或者Cache-Control
頭部注竿。
這條規(guī)則有兩個方面:
- 對靜態(tài)組件:通過設(shè)置
Expires
頭部來實(shí)現(xiàn)“永不過期”策略。 - 對動態(tài)組件:用合適的
Cache-Control
頭部來幫助瀏覽器進(jìn)行有條件請求。
頁面越來越豐富巩割,意味著更多腳本裙顽,樣式,圖片等等宣谈。第一次訪問的用戶可能需要發(fā)出多個請求愈犹,但使用Expires可以讓這些組件被緩存。這避免了訪問子頁面時(shí)沒必要的http請求蒲祈。Expires一般用在圖片上甘萧,但應(yīng)該用在所有的組件上。
瀏覽器(以及代理)使用緩存來減少http請求數(shù)梆掸,加快頁面加載扬卷。服務(wù)器使用http響應(yīng)的Expires
頭部來告訴客戶端一個組件可以緩存多久。比如下面:
Expires: Thu, 15 Apr 2010 20:00:00 GMT //2010-04-15之前都是穩(wěn)定的
注意酸钦,如果你設(shè)置了Expires
頭部怪得,當(dāng)組件更新后,你必須更改文件名卑硫。
2.3 Gzip Components
傳輸時(shí)用gzip等壓縮組件徒恋。
http請求或響應(yīng)的傳輸時(shí)間可以被前端工程師顯著減少。終端用戶的帶寬欢伏,ISP入挣,接近對等交換點(diǎn)等等沒法被開發(fā)團(tuán)隊(duì)控制,但是硝拧,壓縮可以通過減少http響應(yīng)的大小減少響應(yīng)時(shí)間径筏。
從HTTP/1.1
開始,客戶端通過http請求中的Accept-Encoding
頭部來提示支持的壓縮:
Accept-Encoding: gzip, deflate
如果服務(wù)器看到這個頭部障陶,它可能會選用列表中的某個方法壓縮響應(yīng)滋恬。服務(wù)器通過Content-Encoding
頭部提示客戶端:
Content-Encoding: gzip
gzip一般可減小響應(yīng)的70%。盡可能去gzip更多(文本)類型的文件抱究。html恢氯,腳本,樣式鼓寺,xml和json等等都應(yīng)該被gzip勋拟,而圖片,pdf等等不應(yīng)該被gzip妈候,因?yàn)樗鼈儽旧硪驯粔嚎s過敢靡,gzip它們只是浪費(fèi)cpu,甚至增加文件大小州丹。
2.4 Configure ETags
實(shí)體標(biāo)記(Entity tags醋安,ETag)是服務(wù)器和瀏覽器之間判斷瀏覽器緩存中某個組件是否匹配服務(wù)器端原組件的一種機(jī)制。實(shí)體就是組件:圖片墓毒,腳本吓揪,樣式等等。ETag被當(dāng)作驗(yàn)證實(shí)體的比最后更改(last-modified
)日期更高效的機(jī)制所计。服務(wù)器這樣設(shè)置組件的ETag:
HTTP/1.1 200 OK
Last-Modified: Tue, 12 Dec 2006 03:03:59 GMT
ETag: "10c24bc-4ab-457e1c1f"
Content-Length: 12195
之后柠辞,如果瀏覽器要驗(yàn)證組件,它用If-None-Match
頭部來傳ETag給服務(wù)器主胧。如果ETag匹配叭首,服務(wù)器返回304:
GET /i/yahoo.gif HTTP/1.1
Host: us.yimg.com
If-Modified-Since: Tue, 12 Dec 2006 03:03:59 GMT
If-None-Match: "10c24bc-4ab-457e1c1f"
HTTP/1.1 304 Not Modified
ETag的問題是它們被構(gòu)造來使它們對特定的運(yùn)行這個網(wǎng)站的服務(wù)器唯一。瀏覽器從一個服務(wù)器獲取組件踪栋,之后向另一個服務(wù)器驗(yàn)證焙格,ETag將不匹配。然而服務(wù)器集群是處理請求的通用解決方案夷都。
如果不能解決多服務(wù)器間的ETag匹配問題眷唉,那么刪除ETag可能更好。
2.5 Flush the Buffer Early
早一點(diǎn)刷新buffer(盡早給瀏覽器數(shù)據(jù))囤官。
當(dāng)用戶請求一個頁面冬阳,服務(wù)器一般要花200-500ms來拼湊整個頁面。這段時(shí)間党饮,瀏覽器是空閑的(等數(shù)據(jù)返回)肝陪。在php,有個方法flush()
允許你傳輸部分準(zhǔn)備好的html響應(yīng)給瀏覽器刑顺。這樣的話瀏覽器就可以開始下載組件氯窍,而同時(shí)后臺可以繼續(xù)生成頁面剩下的部分。這種好處更多是在忙碌的后臺或輕前端網(wǎng)站可以看到捏检。
一個比較好的flush的位置是在head
之后荞驴,因?yàn)闉g覽器可以加載其中的樣式和腳本文件,而后臺繼續(xù)生成頁面剩余部分贯城。
<!-- css, js -->
</head>
<?php flush(); ?>
<body>
<!-- content -->
2.6 Use GET for AJAX Requests
ajax請求用get熊楼。
Yahoo! Mail團(tuán)隊(duì)發(fā)現(xiàn)當(dāng)使用XMLHttpRequest
,POST 被瀏覽器實(shí)現(xiàn)為兩步:首先發(fā)送頭部能犯,然后發(fā)送數(shù)據(jù)鲫骗。所以使用GET最好,僅用一個TCP包發(fā)送(除非cookie太多)踩晶。IE的url長度限制是2K执泰。
POST但不提交任何數(shù)據(jù)根GET行為類似,但從語義上講渡蜻,獲取數(shù)據(jù)應(yīng)該用GET术吝,提交數(shù)據(jù)到服務(wù)器用POST计济。
2.7 Avoid Empty Image src
避免空src的圖片。
空src屬性的圖片的行為可能跟你預(yù)期的不一樣排苍。它有兩種形式:
- html標(biāo)簽:
<img src="">
- js:
var img = new Image(); img.src = "";
兩種都會造成同一種后果:瀏覽器會向你的服務(wù)器發(fā)請求沦寂。
- IE,向頁面所在的目錄發(fā)請求淘衙。
- Safari和Chrome传藏,請求實(shí)際的頁面。
- FireFox3及之前和Safari/Chrome一樣彤守,但從3.5開始修復(fù)問題毯侦,不再發(fā)請求。
- Opera遇到空圖片src不做任何事具垫。
為什么這種行為很糟糕侈离?
- 由于發(fā)送大量的意料之外的流量,會削弱服務(wù)器筝蚕,尤其那些每天pv上百萬的頁面霍狰。
- 浪費(fèi)服務(wù)器計(jì)算周期取生成不會被瀏覽的頁面。
- 可能會破壞用戶數(shù)據(jù)饰及。如果你在跟蹤請求狀態(tài)蔗坯,通過cookie或其它,你可能會破壞數(shù)據(jù)燎含。即使image的請求不會返回圖片宾濒,但所有的頭部數(shù)據(jù)都被瀏覽器讀取了,包括cookie屏箍。即使剩下的響應(yīng)體被丟棄绘梦,破壞可能已經(jīng)發(fā)生。
這種行為的根源是uri解析發(fā)生在瀏覽器赴魁。RFC 3986 定義了這種行為卸奉,空字符串被當(dāng)作相對路徑,F(xiàn)irefox, Safari, 和 Chrome都正確解析颖御,而IE錯誤榄棵。總之潘拱,瀏覽器解析空字符串為相對路徑的行為被認(rèn)為是符合預(yù)期的疹鳄。
html5在4.8.2添加了對標(biāo)簽src屬性的描述,指導(dǎo)瀏覽器不要發(fā)出額外的請求芦岂。
The src attribute must be present, and must contain a valid URL referencing a non-interactive, optionally animated, image resource that is neither paged nor scripted. If the base URI of the element is the same as the document's address, then the src attribute's value must not be the empty string.
幸運(yùn)的是將來瀏覽器不會有這個問題了(在圖片上)瘪弓。不幸的是,<script src="">
和<link href="">
沒有這樣的規(guī)范禽最。
3 Cookie
3.1 Reduce Cookie Size
http cookie的使用有多種原因腺怯,比如授權(quán)和個性化袱饭。cookie的信息通過http頭部在瀏覽器和服務(wù)器端交換。盡可能減小cookie的大小來降低響應(yīng)時(shí)間呛占。
- 消除不必要的cookie宁赤。
- 盡可能減小cookie的大小來降低響應(yīng)時(shí)間。
- 注意設(shè)置cookie到合適的域名級別栓票,則其它子域名不會被影響。
- 正確設(shè)置Expires日期愕够。早一點(diǎn)的Expires日期或者沒有會盡早刪除cookie走贪,優(yōu)化響應(yīng)時(shí)間。
3.2 Use Cookie-free Domains for Components
用沒有cookie的域名提供組件惑芭。
當(dāng)瀏覽器請求靜態(tài)圖片并把cookie一起發(fā)送到服務(wù)器時(shí)坠狡,cookie此時(shí)對服務(wù)器沒什么用處。所以這些cookie只是增加了網(wǎng)絡(luò)流量遂跟。所以你應(yīng)該保證靜態(tài)組件的請求是沒有cookie的逃沿。可以創(chuàng)建一個子域名來托管所有靜態(tài)組件幻锁。
比如凯亮,你域名是www.example.org
,可以把靜態(tài)組件托管在static.example.org
哄尔。不過假消,你如果把cookie設(shè)置在頂級域名example.org
下,這些cookie仍然會被傳給static.example.org
岭接。這種情況下富拗,啟用一個全新的域名來托管靜態(tài)組件。
另外一個用沒有cookie的域名提供組件的好處是鸣戴,某些代理可能會阻止緩存待cookie的靜態(tài)組件請求啃沪。
4. CSS
4.1 Put Stylesheets at the Top
把樣式放在頂部。
研究雅虎網(wǎng)頁性能時(shí)發(fā)現(xiàn)把樣式表移到<head>
里會讓頁面更快窄锅。這是因?yàn)榘褬邮奖硪频?code><head>里允許頁面逐步渲染创千。
關(guān)注性能的前端工程師希望頁面被逐步渲染,這時(shí)因?yàn)槿胪担覀兿M麨g覽器盡早渲染獲取到的任何內(nèi)容签餐。這對大頁面和網(wǎng)速慢的用戶很重要。給用戶視覺反饋盯串,比如進(jìn)度條的重要性已經(jīng)被大量研究和記錄氯檐。在我們的情況中,HTML
頁面就是進(jìn)度條体捏。當(dāng)瀏覽器逐步加載頁面頭部冠摄,導(dǎo)航條糯崎,logo等等,這些都是給等待頁面的用戶的視覺反饋河泳。這優(yōu)化了整體用戶體驗(yàn)沃呢。
把樣式表放在文檔底部的問題是它阻止了許多瀏覽器的逐步渲染,包括IE拆挥。這些瀏覽器阻止渲染來避免在樣式更改時(shí)需要重繪頁面元素薄霜。所以用戶會卡在白屏。
HTML規(guī)范清楚表明樣式應(yīng)該在<head>
里纸兔。
4.2 Avoid CSS Expressions
避免CSS表達(dá)式惰瓜。
CSS表達(dá)式是強(qiáng)大的(可能也是危險(xiǎn)的)設(shè)置動態(tài)CSS屬性的方法。IE5開始支持汉矿,IE8開始不贊成使用崎坊。例如,背景顏色可以設(shè)置成每小時(shí)輪換:
background-color: expression( (new Date()).getHours()%2 ? "#B8D4FF" : "#F08A00" );
CSS表達(dá)式的問題是它們可能比大多數(shù)人預(yù)期的計(jì)算的更頻繁洲拇。它們不僅在頁面載入和調(diào)整大小時(shí)重新計(jì)算奈揍,也在滾動頁面甚至是用戶在頁面上移動鼠標(biāo)時(shí)計(jì)算。比如在頁面上移動鼠標(biāo)可能輕易計(jì)算超過10000次赋续。
要避免CSS表達(dá)式計(jì)算太多次男翰,可以在它第一次計(jì)算后替換成確切值,或者用事件處理函數(shù)而不是CSS表達(dá)式纽乱。
4.3 Choose <link>
over @import
選擇<link>
而不是@import
奏篙。
之前的一個最佳原則是說CSS應(yīng)該在頂部來允許逐步渲染。
在IE用@import
和把CSS放到頁面底部行為一致迫淹,所以最好別用秘通。
4.4 Avoid Filters
避免使用(IE)過濾器。
IE專有的AlphaImageLoader
過濾器用于修復(fù)IE7以下版本的半透明真彩色PNG的問題敛熬。這個過濾器的問題是它阻止了渲染肺稀,并在圖片下載時(shí)凍結(jié)了瀏覽器。另外它還引起內(nèi)存消耗应民,并且它被應(yīng)用到每個元素而不是每個圖片话原,所以問題(的嚴(yán)重性)翻倍了。
最佳做法是放棄AlphaImageLoader
诲锹,改用PNG8來優(yōu)雅降級繁仁。
5. JavaScript
5.1 Put Scripts at the Bottom
把腳本放到底部。
腳本引起的問題是它們阻塞了并行下載归园。HTTP1.1規(guī)范建議瀏覽器每個域名下不要一次下載超過2個組件黄虱。如果你的圖片分散在不同服務(wù)器,那么你能并行下載多個圖片庸诱。但當(dāng)腳本在下載捻浦,瀏覽器不會再下載其它組件晤揣,即使在不同域名下。
有些情況下把腳本移動到底部并不簡單朱灿。比如昧识,腳本中用了document.write
來插入內(nèi)容,它就不能被移動到底部盗扒。另外有可能有作用域問題跪楞。但大多數(shù)情況,有方法可以解決這些問題侣灶。
一個替代建議是使用異步腳本甸祭。defer
屬性表明腳本不包含document.write
,是提示瀏覽器繼續(xù)渲染的線索炫隶。不幸的是,F(xiàn)irefox不支持阎曹。如果腳本能異步伪阶,那么也就可以移動到底部。
5.2 Make JavaScript and CSS External
使用外部JS和CSS处嫌。
這里的很多性能規(guī)則涉及外部組件怎么管理栅贴。但你首先要明白一個基本問題:JS和CSS是應(yīng)該包含在外部文件還是內(nèi)連在頁面本身?
真實(shí)世界中使用外部文件一般會加快頁面熏迹,因?yàn)镴S和CSS文件被瀏覽器緩存了檐薯。內(nèi)連的JS和CSS怎在每次HTML文檔下載時(shí)都被下載。內(nèi)連減少了http請求注暗,但增加了HTML文檔大小坛缕。另一方面,如果JS和CSS被緩存了捆昏,那么HTML文檔可以減小大小而不增加HTTP請求赚楚。
核心因素,就是JS和CSS被緩存相對于HTML文檔被請求的頻率骗卜。盡管這個因素很難被量化宠页,但可以用不同的指標(biāo)來計(jì)算。如果網(wǎng)站用戶每個session有多個pv寇仓,許多頁面重用相同的JS和CSS举户,那么有很大可能用外部JS和CSS更好。
許多網(wǎng)站用這些指標(biāo)計(jì)算后在中間位置遍烦。對這些網(wǎng)站來說俭嘁,最佳方案還是用外部JS和CSS文件。唯一例外是內(nèi)連更被主頁偏愛服猪,如http://www.yahoo.com/兄淫。主頁每個session可能只有少量的甚至一個pv屯远,這時(shí)候內(nèi)連可能更快。
對多個頁面的首頁來說捕虽,可以通過技術(shù)減少(其它頁面的)http請求慨丐。在首頁用內(nèi)連,初始化后動態(tài)加載外部文件泄私,接下來的頁面如果用到這些文件房揭,就可以使用緩存了。
5.3 Minify JavaScript and CSS
壓縮JS和CSS晌端。
壓縮就是刪除代碼中不必要的字符來減小文件大小捅暴,從而提高加載速度。當(dāng)代碼壓縮時(shí)咧纠,注釋刪除蓬痒,不需要的空格(空白,換行漆羔,tab)也被刪除梧奢。
混淆是對代碼可選的優(yōu)化。它比壓縮更復(fù)雜演痒,并且可能產(chǎn)生bug亲轨。在對美國top10網(wǎng)站的調(diào)查,壓縮可減小21%鸟顺,而混淆可減小25%惦蚊。
除了外部腳本和樣式,內(nèi)連的腳本和樣式同樣應(yīng)該被壓縮讯嫂。
5.4 Remove Duplicate Scripts
刪除重復(fù)的腳本蹦锋。
在頁面中引入相同的腳本兩次會傷害性能∨费浚可能超出你的預(yù)料晕粪,美國top10網(wǎng)站的2家有重復(fù)腳本引入。兩個主要因素造成同一頁面引入相同腳本:團(tuán)隊(duì)大小和腳本數(shù)量渐裸。當(dāng)確實(shí)引入重復(fù)腳本巫湘,會發(fā)出不必要的http請求和浪費(fèi)js執(zhí)行時(shí)間。
發(fā)出不必要的http請求發(fā)生在IE而不是Firefox昏鹃。在IE尚氛,如果外部腳本引入兩次且沒有緩存,它會發(fā)出2個請求洞渤。即使腳本被緩存阅嘶,刷新時(shí)也會發(fā)出額外請求。
除了增加http請求,時(shí)間被浪費(fèi)在執(zhí)行腳本多次上讯柔。不管IE還是Firefox都會執(zhí)行多次抡蛙。
一種避免多次引入腳本的方法是在模板系統(tǒng)實(shí)現(xiàn)一個腳本管理模塊。
5.5 Minimize DOM Access
最小化DOM訪問魂迄。
用JS訪問DOM元素是緩慢的粗截,所以為了響應(yīng)更好的頁面,你應(yīng)該:
- 緩存訪問過的元素的引用
- 在DOM樹外更新節(jié)點(diǎn)捣炬,然后添加到DOM樹
- 避免用JS實(shí)現(xiàn)固定布局
5.6 Develop Smart Event Handlers
開發(fā)聰明的事件處理
有時(shí)候頁面看起來不那么響應(yīng)(響應(yīng)速度慢)熊昌,是因?yàn)榻壎ǖ讲煌氐拇罅渴录幚砗瘮?shù)執(zhí)行太多次。這是為什么使用事件委托是一種好方法湿酸。
另外婿屹,你不必等到onload
事件來開始處理DOM樹,DOMContentLoaded
更快推溃。大多時(shí)候你需要的只是想訪問的元素已在DOM樹中昂利,所以你不必等到所有圖片被下載。
6 Images
6.1 Optimize Images
優(yōu)化圖片
在設(shè)計(jì)師建好圖片后铁坎,在上傳圖片到服務(wù)器前你仍可以做些事:
- 檢查gif圖片的調(diào)色板大小是否匹配圖片顏色數(shù)蜂奸。
- 可以把gif轉(zhuǎn)成png看看有沒有變小。除了動畫厢呵,gif一般可以轉(zhuǎn)成png8窝撵。
- 運(yùn)行
pngcrush
或其它工具壓縮png傀顾。 - 運(yùn)行
jpegtran
或其它工具壓縮jpeg襟铭。
6.2 Optimize CSS Sprites
優(yōu)化CSS雪碧圖
- 把圖片橫向合并而不是縱向,橫向更小短曾。
- 把顏色近似的圖片合并到一張雪碧圖寒砖,這樣可以讓顏色數(shù)更少,如果低于256就可以用png8.
- "Be mobile-friendly"并且合并時(shí)圖片間的間距不要太大嫉拐。這對圖片大小影響不是太大哩都,但客戶端解壓時(shí)需要的內(nèi)存更少。100×100是10000個像素婉徘,1000×1000是1000000個像素漠嵌。
6.3 Don't Scale Images in HTML
不要在html中縮放圖片
不要因?yàn)槟憧梢栽O(shè)置圖片的寬高就去用比你需要的大得多的圖片。如果你需要
<img width="100" height="100" src="mycat.jpg" alt="My Cat" />
那么盖呼,就用100x100px的圖片儒鹿,而不是500x500px的。
6.4 Make favicon.ico Small and Cacheable
favicon.ico小且緩存
favicon.ico是在你服務(wù)器根路徑的圖片几晤。邪惡的是即使你不關(guān)心它约炎,瀏覽器仍然會請求它。所以最好不要響應(yīng)404。另外由于在同一服務(wù)器圾浅,每次請求favicon.ico時(shí)也會帶上cookie掠手。這個圖片還會影響下載順序,比如在IE狸捕,如果你在onload
時(shí)下載額外的組件喷鸽,fcvicon會在這些組件之前被下載。
怎么減輕favicon.ico的缺點(diǎn)府寒?
- 小魁衙,最好1K以下
- 設(shè)置Expires頭部。也許可以安全地設(shè)置為幾個月株搔。
7 Mobile
7.1 Keep Components under 25K
保持組件小于25K
這個限制與iPhone不緩存大于25K的組件相關(guān)剖淀。注意,這是非壓縮(uncompressed)的文件大小纤房。在這里minification(壓縮纵隔,不要與compress混淆)很重要,因?yàn)間zip無法滿足(iPhone)炮姨。
7.2 Pack Components into a Multipart Document
打包組件到一個多部父文檔
打包組件到一個多部父文檔類似于帶附件的郵件捌刮。它幫助你在一個http請求中獲取多個組件,但注意舒岸,iPhone不支持绅作。