| 1. 盡可能的減少 HTTP 的請求數(shù) | content |
| 2. 使用 CDN(Content Delivery Network) | server |
| 3. 添加 Expires 頭(或者 Cache-control ) | server |
| 4. Gzip 組件 | server |
| 5. 將 CSS 樣式放在頁面的上方 | css |
| 6. 將腳本移動到底部(包括內(nèi)聯(lián)的) | javascript |
| 7. 避免使用 CSS 中的 Expressions | css |
| 8. 將 JavaScript 和 CSS 獨立成外部文件 | javascript css |
| 9. 減少 DNS 查詢 | content |
| 10. 壓縮 JavaScript 和 CSS (包括內(nèi)聯(lián)的) | javascript css |
| 11. 避免重定向 | server |
| 12. 移除重復的腳本 | javascript |
| 13. 配置實體標簽(ETags) | css |
| 14. 使 AJAX 緩存 |
[圖片上傳失敗...(image-83f0a5-1544661998400)]
在firefox下有一個插件yslow,集成在firebug中,你可以用它很方便地來看看自己的網(wǎng)站在這幾個方面的表現(xiàn)迹炼。
這是對用yslow對我的網(wǎng)站西風坊測評的結(jié)果奏篙,很遺憾窘俺,只有51分辈灼。呵呵沦疾。中國各大網(wǎng)站的分值都不高,剛測了一下纯赎,新浪和網(wǎng)易都是31分。然后yahoo(美國)的分值確實97分南蹂!可見yahoo在這方面作出的努力犬金。從他們總結(jié)的這14條規(guī)則,已經(jīng)現(xiàn)在又新增加的20個點來看六剥,有很多細節(jié)我們真得是怎么都不會去想晚顷,有些做法甚至是有些“變態(tài)”了。
第一條疗疟、盡可能的減少 HTTP 的請求數(shù) (Make Fewer HTTP Requests )
http請求是要開銷的该默,想辦法減少請求數(shù)自然可以提高網(wǎng)頁速度。常用的方法策彤,合并css栓袖,js(將一個頁面中的css和js文件分別合并)以及 Image maps和css sprites等。當然或許將css店诗,js文件拆分多個是因為css結(jié)構(gòu)裹刮,共用等方面的考慮。阿里巴巴中文站當時的做法是開發(fā)時依然分開開發(fā)庞瘸,然后在后臺 對js捧弃,css進行合并,這樣對于瀏覽器來說依然是一個請求擦囊,但是開發(fā)時仍然能還原成多個塔橡,方便管理和重復引用梅割。yahoo甚至建議將首頁的css和js 直接寫在頁面文件里面,而不是外部引用葛家。因為首頁的訪問量太大了户辞,這么做也可以減少兩個請求數(shù)。而事實上國內(nèi)的很多門戶都是這么做的癞谒。
而css sprites是指只用將頁面上的背景圖合并成一張底燎,然后通過css的background-position屬性定義不過的值來取他的背景。淘寶和阿里巴巴中文站目前都是這樣做的弹砚。有興趣的可以看下淘寶和阿里巴巴的背景圖双仍。
http://www.csssprites.com/ 這是個工具網(wǎng)站,它可以自動將你上傳的圖片合并并給出對應的background-position坐標桌吃。并將結(jié)果以png和gif的格式輸出朱沃。
**第二條、使用CDN(內(nèi)容分發(fā)網(wǎng)絡): **Use a Content Delivery Network
說實話茅诱,對于CDN這一塊自己并不是很了解逗物,簡單地講,通過在現(xiàn)有的Internet中增加一層新的網(wǎng)絡架構(gòu)瑟俭,將網(wǎng)站的內(nèi)容發(fā)布到最接近用戶的 cache服務器內(nèi)翎卓,通過DNS負載均衡的技術(shù),判斷用戶來源就近訪問cache服務器取得所需的內(nèi)容摆寄,杭州的用戶訪問近杭州服務器上的內(nèi)容失暴,北京的訪問 近北京服務器上的內(nèi)容。這樣可以有效減少數(shù)據(jù)在網(wǎng)絡上傳輸?shù)臅r間微饥,提高速度逗扒。更詳細地內(nèi)容大家可以參考百度百科上對于CDN的解釋。Yahoo!把靜態(tài)內(nèi)容分布到CDN減少了用戶影響時間20%或更多欠橘。
CDN技術(shù)示意圖:
[圖片上傳失敗...(image-4a257b-1544661998400)]
CDN組網(wǎng)示意圖:
[圖片上傳失敗...(image-a30bb1-1544661998400)]
第三條矩肩、 添加Expire/Cache-Control 頭:Add an Expires Header
現(xiàn)在越來越多的圖片,腳本简软,css蛮拔,flash被嵌入到頁面中,當我們訪問他們的時候勢必會做許多次的http請求痹升。其實我們可以通過設置Expires header 來緩存這些文件建炫。Expire其實就是通過header報文來指定特定類型的文件在覽器中的緩存時間。大多數(shù)的圖片疼蛾,flash在發(fā)布后都是不需要經(jīng)常修 改的肛跌,做了緩存以后這樣瀏覽器以后就不需要再從服務器下載這些文件而是而直接從緩存中讀取,這樣再次訪問頁面的速度會大大加快。一個典型的HTTP 1.1協(xié)議返回的頭信息:
HTTP/1.1 200 OK
Date: Fri, 30 Oct 1998 13:19:41 GMT
Server: Apache/1.3.3 (Unix)
Cache-Control: max-age=3600, must-revalidate
Expires: Fri, 30 Oct 1998 14:19:41 GMT
Last-Modified: Mon, 29 Jun 1998 02:28:12 GMT
ETag: “3e86-410-3596fbbc”
Content-Length: 1040
Content-Type: text/html
其中通過服務器端腳本設置Cache-Control和Expires可以完成衍慎。
如转唉,在php中設置30天后過期:
<!--pHeader("Cache-Control: must-revalidate"); $offset = 60 * 60 * 24 * 30; $ExpStr = "Expires: " . gmdate("D, d M Y H:i:s", time() + $offset) . " GMT"; Header($ExpStr);-->
也可以通過配置服務器本身完成,這些偶就不是很清楚了稳捆,呵呵赠法。想了解跟多的朋友可以參考http://www.web-caching.com/
據(jù)我了解,目前阿里巴巴中文站的Expires過期時間是30天乔夯。不過期間也有過問題砖织,特別是對于腳本過期時間的設置還是應該仔細考慮下,不然相應的腳本功能更新后客戶端可能要過很長一段時間才能“感知”到這樣的變化末荐。所以侧纯,哪些應該緩存,哪些不該緩存還是應該仔細斟酌一番甲脏。
第四條眶熬、啟用Gzip壓縮:Gzip Components
Gzip的思想就是把文件先在服務器端進行壓縮,然后再傳輸块请。這樣可以顯著減少文件傳輸?shù)拇笮∧仁稀鬏斖戤吅鬄g覽器會 重新對壓縮過的內(nèi)容進行解壓縮,并執(zhí)行负乡。目前的瀏覽器都能“良好”地支持 gzip牍白。不僅瀏覽器可以識別脊凰,而且各大“爬蟲”也同樣可以識別抖棘,各位seoer可以放下心了。而且gzip的壓縮比例非常大狸涌,一般壓縮率為85%切省,就是 說服務器端100K的頁面可以壓縮到25K左右再發(fā)送到客戶端。具體的Gzip壓縮原理大家可以參考csdn上的《gzip壓縮算法》 這篇文章帕胆。雅虎特別強調(diào)朝捆, **所有的文本內(nèi)容都應該被gzip壓縮: html (php), js, css, xml, txt… **這一點我們網(wǎng)站做得不錯,是一個A懒豹。以前我們的首頁也并不是A,因為首頁上還有很多廣告代碼投放的js,這些廣告代碼擁有者的網(wǎng)站的js沒有經(jīng)過gzip壓縮庶弃,也會拖累我們網(wǎng)站掌动。
以上三點大多屬于服務器端的內(nèi)容,本人也是粗淺地了解而已记餐。說得不對的地方有待各位指正驮樊。
**第五條、將css放在頁面最上面 **( Put Stylesheets at the Top)
將css放在頁面最上面,這是為什么囚衔?因為 ie挖腰,firefox等瀏覽器在css全部傳輸完全之前不會去渲染任何的東西。理由誠如小馬哥說得那樣很簡單练湿。css猴仑,全稱Cascading Style Sheets (層疊樣式表單)。層疊即意味這后面的css可以覆蓋前面的css肥哎,級別高的css可以覆蓋級別低的css宁脊。在[css之!important] 這篇文章的最下面曾簡單地提到過這層級關(guān)系贤姆,這里我們只需要知道css可以被覆蓋的榆苞。既然前面的可以被覆蓋,瀏覽器在他完全加載完畢之后再去渲染無疑也是合情合理的很多瀏覽器下霞捡,如IE坐漏,把樣式表放在頁面的底部的問題在于它禁止了網(wǎng)頁內(nèi)容的順序顯示。瀏覽器阻止顯示以免重畫頁面元素碧信,那用戶只能看到空白頁了赊琳。Firefox不會阻止顯示,但這意味著當樣式表下載后砰碴,有些頁面元素可能需要重畫躏筏,這導致閃爍問題。所以我們應該盡快讓css加載完畢
順著這層意思呈枉,如果我們再細究的話趁尼,其實還有可以優(yōu)化的地方。比如本站上面包含的兩個css文件猖辫,<link rel=“stylesheet” rev=“stylesheet”href=“http://www.space007.com/themes/google/style/google.css” type=“text/css” media=“screen”/> 和<link rel=“stylesheet” rev=“stylesheet” href=“http://www.space007.com/css/print.css”type=“text/css” media=“print” />酥泞。 從media就可以看出第一個css是針對瀏覽器的,第二個css文件是針對打印樣式的啃憎。從用戶的行為習慣上來將芝囤,要打印頁面的動作一定是發(fā)生在頁面頁面 顯示出來之后的。所以比較好的方法應該是在頁面加載完畢之后再動態(tài)地為這張頁面加上針對打印設備的css辛萍,這樣又可以提高一點速度悯姊。(哈哈)
**第六條、將script放在頁面最下面 **(Put Scripts at the Bottom )
將腳本放在頁面最下面的目的有那么兩點: 1贩毕、 因為防止script腳本的執(zhí)行阻塞頁面的下載悯许。在頁面loading的過程中,當瀏覽器讀到js執(zhí)行語句的時候一定會把它全部解釋完畢后在會接下來讀下 面的內(nèi)容耳幢。不信你可以寫一個js死循環(huán)看看頁面下面的東西還會不會出來岸晦。(setTimeout 和 setInterval的執(zhí)行有點類似于多線程欧啤,在相應的響應時間之前也會繼續(xù)下面的內(nèi)容渲染。)瀏覽器這么做的邏輯是因為js隨時可能執(zhí) 行 location.href或是其他可能完全中斷此頁面過程的函數(shù)启上,即如此邢隧,當然得等他執(zhí)行完畢之后再加載咯。所以放在頁面最后冈在,可以有效減少頁面可 視元素的加載時間倒慧。 2、腳本引起的第二個問題是它阻塞并行下載數(shù)量包券。HTTP/1.1規(guī)范建議瀏覽器每個主機的并行下載數(shù)不超過2個(IE只能為2個纫谅,其他瀏覽器如ff等都是默認設置為2個,不過新出的ie8可以達6個)溅固。因此如果您把圖像文件分布到多臺機器的話付秕,您可以達到超過2個的并行下載。但是當腳本文件下載時侍郭,瀏覽器不會啟動其他的并行下載询吴。
當然對各個網(wǎng)站來說,把腳本都放到頁面底部加載的可行性還是值得商榷的亮元。就比如阿里巴巴中文站的頁面猛计。很多地方有內(nèi)聯(lián)的js,頁面的顯示嚴重依賴于此爆捞,我承認這和無侵入腳本的理念相差甚遠奉瘤,但是很多“歷史遺留問題”卻不是那么容易解決的。
第七條煮甥、避免在CSS中使用Expressions ****(Avoid CSS Expressions )
不過這樣就多了兩層無意義的嵌套盗温,肯定不好。還需要一個更好的辦法苛秕。
第八條肌访、把javascript和css都放到外部文件中 ****(Make JavaScript and CSS External )
這點我想還是很容易理解的找默。不僅從性能優(yōu)化上會這么做艇劫,用代碼易于維護的角度看也應該這么做。把css和js寫在頁面內(nèi)容可以減少2次請求惩激,但也增 大了頁面的大小店煞。如果已經(jīng)對css和js做了緩存,那也就沒有2次多余的http請求了风钻。當然顷蟀,我在前面中也說過,有些特殊的頁面開發(fā)人員還是會選擇內(nèi)聯(lián) 的css和js文件骡技。
**第九條鸣个、減少DNS查詢 **(Reduce DNS Lookups)
在 Internet上域名與IP地址之間是一一對應的羞反,域名(kuqin.com)很好記,但計算機不認識囤萤,計算機之間的“相認”還要轉(zhuǎn)成ip地址昼窗。在網(wǎng)絡 上每臺計算機都對應有一個獨立的ip地址。在域名和ip地址之間的轉(zhuǎn)換工作稱為域名解析涛舍,也稱DNS查詢澄惊。一次DNS的解析過程會消耗20-120毫秒的 時間,在dns查詢結(jié)束之前,瀏覽器不會下載該域名下的任何東西富雅。所以減少dns查詢的時間可以加快頁面的加載速度掸驱。yahoo的建議一個頁面所包含的域 名數(shù)盡量控制在2-4個。這就需要對頁面整體有一個很好的規(guī)劃没佑。目前我們這點做的不好毕贼,很多打點的廣告投放系統(tǒng)拖累了我們。
**第十條蛤奢、壓縮 JavaScript 和 CSS **(Minify JavaScript )
壓縮js和css的左右很顯然帅刀,減少頁面字節(jié)數(shù)。容量小頁面加載速度自然也就快远剩。而且壓縮除了減少體積以外還可以起到一定的保護左右扣溺。這點我們做得不錯。常用的壓縮工具有JsMin瓜晤、YUI compressor等锥余。另外像http://dean.edwards.name/packer/還給我們提供了一個非常方便的在線壓縮工具。你可以在jQuery的網(wǎng)頁看到壓縮過的js文件和沒有壓縮過的js文件的容量差別:
[圖片上傳失敗...(image-6a09b2-1544661998399)]
當然痢掠,壓縮帶來的一個弊端就是代碼的可讀性沒了驱犹。相信很多做前端的朋友都遇到過這個問題:看Google的效果很酷,可是去看他的源代碼卻是一大堆 擠在一起的字符足画,連函數(shù)名都是替換過的雄驹,汗死!自己的代碼也這樣豈不是對維護非常不方便淹辞。所有阿里巴巴中文站目前采用的做法是在js和css發(fā)布的時候在 服務器端進行壓縮医舆。這樣在我們很方便地維護自己的代碼。
**第十一條象缀、避免重定向 **(Avoid Redirects )
不久前在ieblog上看到過《Internet Explorer and Connection Limits》這篇文章蔬将,比如 當你輸入http://www.kuqin.com/ 的時候服務器會自動產(chǎn)生一個301服務器轉(zhuǎn)向 http://www.kuqin.com/ ,你看瀏覽器的地址欄就能看出來央星。這種重定向自然也是需要消耗時間的霞怀。當然這只是一個例子,發(fā)生重定向的原因還有很多莉给,但是不變的是每增加一次重定向就會增加一次web請求毙石,所以因該盡量減少廉沮。
**第十二條、移除重復的腳本 **(Remove Duplicate Scripts )
這點我想不說也知道徐矩,不僅是從性能上考慮废封,代碼規(guī)范上看也是這樣。但是不得不承認丧蘸,很多時候我們會因為圖一時之快而加上一些或許是重復的代碼漂洋。或許一個統(tǒng)一的css框架和js框架可以比較好的解決我們的問題力喷。小豬的觀點很對刽漂,不僅是要做到不重復,更是要做到可重用弟孟。
**第十三條贝咙、配置實體標簽(ETags) **(Configure ETags )
這點我也不懂,呵呵拂募。在inforQ上找到一篇解釋得比較詳細的說明《使用ETags減少Web應用帶寬和負載》庭猩,有興趣的同學可以去看看。
**第十四條陈症、使 AJAX 緩存 **(Make Ajax Cacheable )
ajax還要去緩存蔼水?做ajax請求的時候往往還要增加一個時間戳去避免他緩存。It’s important to remember that “asynchronous” does not imply “instantaneous”.(記住“異步”不是“瞬間”這一點很重要)录肯。記住趴腋,即使AJAX是動態(tài)產(chǎn)生的而且只對一個用戶起作用,他們依然可以被緩 存论咏。