天天看點

雅虎14條性能優化(經典)

相信網際網路已經越來越成為人們生活中不可或缺的一部分。ajax,flex等等富用戶端的應用使得人們越加“幸福”地體驗着許多原先隻能在C/S實 現的功能。比如Google機會

已經把最基本的office應用都搬到了網際網路上。當然便利的同時毫無疑問的也使頁面的速度越來越慢。自己是做前端開發 的,在性能方面,根據yahoo的調查,背景隻占5%,而

前端高達95%之多,其中有88%的東西是可以優化的。

廢話不多說,貼規則:

相信很多人都聽過優化網站性能的14條規則。更多的資訊可見developer.yahoo.com

1. 盡可能的減少 HTTP 的請求數 [content]

2. 使用 CDN(Content Delivery Network) [server]

3. 添加 Expires 頭(或者 Cache-control ) [server]

4. Gzip 元件 [server]

5. 将 CSS 樣式放在頁面的上方 [css]

6. 将腳本移動到底部(包括内聯的) [javascript]

7. 避免使用 CSS 中的 Expressions [css]

8. 将 JavaScript 和 CSS 獨立成外部檔案 [javascript] [css]

9. 減少 DNS 查詢 [content]

10. 壓縮 JavaScript 和 CSS (包括内聯的) [javascript] [css]

11. 避免重定向 [server]

12. 移除重複的腳本 [javascript]

13. 配置實體标簽(ETags) [css]

14. 使 AJAX 緩存

在firefox下有一個插件yslow,內建在firebug中,你可以用它很友善地來看看自己的網站在這幾個方面的表現。

第一條、盡可能的減少 HTTP 的請求數 (Make Fewer HTTP Requests )

http請求是要開銷的,想辦法減少請求數自然可以提高網頁速度。常用的方法,合并css,js(将一個頁面中的css和js檔案分别合并)以及 Image maps和css sprites等。當然或許将css,js檔案拆分多個是因為css結構,共用等方面的考慮。阿裡巴巴中文站當時的做法是開發時依然分開開發,然後在背景 對js,css進行合并,這樣對于浏覽器來說依然是一個請求,但是開發時仍然能還原成多個,友善管理和重複引用。yahoo甚至建議将首頁的css和js 直接寫在頁面檔案裡面,而不是外部引用。因為首頁的通路量太大了,這麼做也可以減少兩個請求數。而事實上國内的很多門戶都是這麼做的。

而css sprites是指隻用将頁面上的背景圖合并成一張,然後通過css的background-position屬性定義不過的值來取他的背景。淘寶和阿裡巴巴中文站目前都是這樣做的。有興趣的可以看下淘寶和阿裡巴巴的背景圖。

http://www.csssprites.com/ 這是個工具網站,它可以自動将你上傳的圖檔合并并給出對應的background-position坐标。并将結果以png和gif的格式輸出。

第二條、使用CDN(内容分發網絡): Use a Content Delivery Network

說實話,對于CDN這一塊自己并不是很了解,簡單地講,通過在現有的Internet中增加一層新的網絡架構,将網站的内容釋出到最接近使用者的 cache伺服器内,通過DNS負載均衡的技術,判斷使用者來源就近通路cache伺服器取得所需的内容,杭州的使用者通路近杭州伺服器上的内容,北京的通路 近北京伺服器上的内容。這樣可以有效減少資料在網絡上傳輸的時間,提高速度。更詳細地内容大家可以參考百度百科上對于CDN的解釋。Yahoo!把靜态内 容分布到CDN減少了使用者影響時間20%或更多。

第三條、 添加Expire/Cache-Control 頭:Add an Expires Header

現在越來越多的圖檔,腳本,css,flash被嵌入到頁面中,當我們通路他們的時候勢必會做許多次的http請求。其實我們可以通過設定 Expires header 來緩存這些檔案。Expire其實就是通過header封包來指定特定類型的檔案在覽器中的緩存時間。大多數的圖檔,flash在釋出後都是不需要經常修 改的,做了緩存以後這樣浏覽器以後就不需要再從伺服器下載下傳這些檔案而是而直接從緩存中讀取,這樣再次通路頁面的速度會大大加快。一個典型的HTTP 1.1協定傳回的頭資訊:

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/

據我了解,目前阿裡巴巴中文站的Expires過期時間是30天。不過期間也有過問題,特别是對于腳本過期時間的設定還是應該仔細考慮下,不然相應 的腳本功能更新後用戶端可能要過很長一段時間才能“感覺”到這樣的變化。以前做[suggest項目] 的時候就遇到過這個問題。是以,哪些應該緩存,哪些不該緩存還是應該仔細斟酌一番。

第四條、啟用Gzip壓縮:Gzip Components

Gzip的思想就是把檔案先在伺服器端進行壓縮,然後再傳輸。這樣可以顯著減少檔案傳輸的大小。傳輸完畢後浏覽器會 重新對壓縮過的内容進行解壓縮,并執行。目前的浏覽器都能“良好”地支援 gzip。不僅浏覽器可以識别,而且各大“爬蟲”也同樣可以識别,各位seoer可以放下心了。而且gzip的壓縮比例非常大,一般壓縮率為85%,就是 說伺服器端100K的頁面可以壓縮到25K左右再發送到用戶端。具體的Gzip壓縮原理大家可以參考csdn上的《gzip壓縮算法》 這篇文章。雅虎特别強調, 所有的文本内容都應該被gzip壓縮: html (php), js, css, xml, txt… 這一點我們網站做得不錯,是一個A。以前我們的首頁也并不是A,因為首頁上還有很多廣告代碼投放的js,這些廣告代碼擁有者的網站的js沒有經過gzip 壓縮,也會拖累我們網站。

以上三點大多屬于伺服器端的内容,本人也是粗淺地了解而已。說得不對的地方有待各位指正。

第五條、将css放在頁面最上面 ( Put Stylesheets at the Top)

将css放在頁面最上面,這是為什麼?因為 ie,firefox等浏覽器在css全部傳輸完全之前不會去渲染任何的東西。理由誠如小馬哥說得那樣很簡單。css,全稱Cascading Style Sheets (層疊樣式表單)。層疊即意味這後面的css可以覆寫前面的css,級别高的css可以覆寫級别低的css。在[css之!important] 這篇文章的最下面曾簡單地提到過這層級關系,這裡我們隻需要知道css可以被覆寫的。既然前面的可以被覆寫,浏覽器在他完全加載完畢之後再去渲染無疑也是 合情合理的很多浏覽器下,如IE,把樣式表放在頁面的底部的問題在于它禁止了網頁内容的順序顯示。浏覽器阻止顯示以免重畫頁面元素,那使用者隻能看到空白頁 了。Firefox不會阻止顯示,但這意味着當樣式表下載下傳後,有些頁面元素可能需要重畫,這導緻閃爍問題。是以我們應該盡快讓css加載完畢

順着這層意思,如果我們再細究的話,其實還有可以優化的地方。比如本站上面包含的兩個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檔案是針對列印樣式的。從使用者的行為習慣上來将,要列印頁面的動作一定是發生在頁面頁面 顯示出來之後的。是以比較好的方法應該是在頁面加載完畢之後再動态地為這張頁面加上針對列印裝置的css,這樣又可以提高一點速度。

第六條、将script放在頁面最下面 (Put Scripts at the Bottom )

将腳本放在頁面最下面的目的有那麼兩點: 1、 因為防止script腳本的執行阻塞頁面的下載下傳。在頁面loading的過程中,當浏覽器讀到js執行語句的時候一定會把它全部解釋完畢後在會接下來讀下 面的内容。不信你可以寫一個js死循環看看頁面下面的東西還會不會出來。(setTimeout 和 setInterval的執行有點類似于多線程,在相應的響應時間之前也會繼續下面的内容渲染。)浏覽器這麼做的邏輯是因為js随時可能執 行 location.href或是其他可能完全中斷此頁面過程的函數,即如此,當然得等他執行完畢之後再加載咯。是以放在頁面最後,可以有效減少頁面可 視元素的加載時間。 2、腳本引起的第二個問題是它阻塞并行下載下傳數量。HTTP/1.1規範建議浏覽器每個主機的并行下載下傳數不超過2個(IE隻能為2個,其他浏覽器如ff等都 是預設設定為2個,不過新出的ie8可以達6個)。是以如果您把圖像檔案分布到多台機器的話,您可以達到超過2個的并行下載下傳。但是當腳本檔案下載下傳時,浏覽 器不會啟動其他的并行下載下傳。

當然對各個網站來說,把腳本都放到頁面底部加載的可行性還是值得商榷的。就比如阿裡巴巴中文站的頁面。很多地方有内聯的js,頁面的顯示嚴重依賴于此,我承認這和無侵入腳本的理念相差甚遠,但是很多“曆史遺留問題”卻不是那麼容易解決的。

第七條、避免在CSS中使用Expressions (Avoid CSS Expressions )

不過這樣就多了兩層無意義的嵌套,肯定不好。還需要一個更好的辦法。

第八條、把javascript和css都放到外部檔案中 (Make JavaScript and CSS External )

這點我想還是很容易了解的。不僅從性能優化上會這麼做,用代碼易于維護的角度看也應該這麼做。把css和js寫在頁面内容可以減少2次請求,但也增 大了頁面的大小。如果已經對css和js做了緩存,那也就沒有2次多餘的http請求了。當然,我在前面中也說過,有些特殊的頁面開發人員還是會選擇内聯 的css和js檔案。

第九條、減少DNS查詢 (Reduce DNS Lookups)

在 Internet上域名與IP位址之間是一一對應的,域名(kuqin.com)很好記,但計算機不認識,計算機之間的“相認”還要轉成ip位址。在網絡 上每台計算機都對應有一個獨立的ip位址。在域名和ip位址之間的轉換工作稱為域名解析,也稱DNS查詢。一次DNS的解析過程會消耗20-120毫秒的 時間,在dns查詢結束之前,浏覽器不會下載下傳該域名下的任何東西。是以減少dns查詢的時間可以加快頁面的加載速度。yahoo的建議一個頁面所包含的域 名數盡量控制在2-4個。這就需要對頁面整體有一個很好的規劃。目前我們這點做的不好,很多打點的廣告投放系統拖累了我們。

第十條、壓縮 JavaScript 和 CSS (Minify JavaScript )

壓縮js和css的左右很顯然,減少頁面位元組數。容量小頁面加載速度自然也就快。而且壓縮除了減少體積以外還可以起到一定的保護左右。這點我們做得 不錯。常用的壓縮工具有JsMin、YUI compressor等。另外像http://dean.edwards.name/packer/還給我們提供了一個非常友善的線上壓縮工具。你可以在 jQuery的網頁看到壓縮過的js檔案和沒有壓縮過的js檔案的容量差别:

當然,壓縮帶來的一個弊端就是代碼的可讀性沒了。相信很多做前端的朋友都遇到過這個問題:看Google的效果很酷,可是去看他的源代碼卻是一大堆 擠在一起的字元,連函數名都是替換過的,汗死!自己的代碼也這樣豈不是對維護非常不友善。所有阿裡巴巴中文站目前采用的做法是在js和css釋出的時候在伺服器端進行壓縮。這樣在我們很友善地維護自己的代碼。

第十一條、避免重定向 (Avoid Redirects )

不久前在ieblog上看到過《Internet Explorer and Connection Limits》 這篇文章,比如 當你輸入http://www.kuqin.com/ 的時候伺服器會自動産生一個301伺服器轉向 http://www.kuqin.com/ ,你看浏覽器的位址欄就能看出來。這種重定向自然也是需要消耗時間的。當然這隻是一個例子,發生重定向的原因還有很多,但是不變的是每增加一次重定向就會 增加一次web請求,是以因該盡量減少。

第十二條、移除重複的腳本 (Remove Duplicate Scripts )

這點我想不說也知道,不僅是從性能上考慮,代碼規範上看也是這樣。但是不得不承認,很多時候我們會因為圖一時之快而加上一些或許是重複的代碼。或許一個統一的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是動态産生的而且隻對一個使用者起作用,他們依然可以被緩存。

目前能做到的就是關于css方面的,拼圖,壓縮減少備援,合理書寫分類,讓咱們css在YSlow顯示都是"A",至于伺服器類的,來日方長,咱們慢慢學……隻要有熱情在,遲早都會學到手……

在Yslow上面可以看到有23條之多:

1、減少HTTP請求次數

合并圖檔、CSS、JS,改進首次通路使用者等待時間。

2、使用CDN

就近緩存==>智能路由==>負載均衡==>WSA全站動态加速

3、避免空的src和href

當link标簽的href屬性為空、script标簽的src屬性為空的時候,浏覽器渲染的時候會把目前頁面的URL作為它們的屬性值,進而把頁面的内容加載進來作為它們的值。測試

4、為檔案頭指定Expires

使内容具有緩存性。避免了接下來的頁面通路中不必要的HTTP請求。

5、使用gzip壓縮内容

壓縮任何一個文本類型的響應,包括XML和JSON,都是值得的。

6、把CSS放到頂部

7、把JS放到底部

防止js加載對之後資源造成阻塞。

8、避免使用CSS表達式

9、将CSS和JS放到外部檔案中

目的是緩存,但有時候為了減少請求,也會直接寫到頁面裡,需根據PV和IP的比例權衡。

10、權衡DNS查找次數

減少主機名可以節省響應時間。但同時,需要注意,減少主機會減少頁面中并行下載下傳的數量。

IE浏覽器在同一時刻隻能從同一域名下載下傳兩個檔案。當在一個頁面顯示多張圖檔時,IE 使用者的圖檔下載下傳速度就會受到影響。是以新浪會搞N個二級域名來放圖檔。

11、精簡CSS和JS

12、避免跳轉

同域:注意避免反斜杠 “/” 的跳轉;

跨域:使用Alias或者mod_rewirte建立CNAME(儲存域名與域名之間關系的DNS記錄)

13、删除重複的JS和CSS

重複調用腳本,除了增加額外的HTTP請求外,多次運算也會浪費時間。在IE和Firefox中不管腳本是否可緩存,它們都存在重複運算JavaScript的問題。

14、配置ETags

它用來判斷浏覽器緩存裡的元素是否和原來伺服器上的一緻。比last-modified date更具有彈性,例如某個檔案在1秒内修改了10次,Etag可以綜合Inode(檔案的索引節點(inode)數),MTime(修改時間)和 Size來精準的進行判斷,避開UNIX記錄MTime隻能精确到秒的問題。 伺服器叢集使用,可取後兩個參數。使用ETags減少Web應用帶寬和負載

15、可緩存的AJAX

“異步”并不意味着“即時”:Ajax并不能保證使用者不會在等待異步的JavaScript和XML響應上花費時間。

16、使用GET來完成AJAX請求

當使用XMLHttpRequest時,浏覽器中的POST方法是一個“兩步走”的過程:首先發送檔案頭,然後才發送資料。是以使用GET擷取資料時更加有意義。

17、減少DOM元素數量

是否存在一個是更貼切的标簽可以使用?标簽語義化,避免濫用無意義标簽

18、避免404

有些站點把404錯誤響應頁面改為“你是不是要找***”,這雖然改進了使用者體驗但是同樣也會浪費伺服器資源(如資料庫等)。最糟糕的情況是指向外部 JavaScript的連結出現問題并傳回404代碼。首先,這種加載會破壞并行加載;其次浏覽器會把試圖在傳回的404響應内容中找到可能有用的部分當 作JavaScript代碼來執行。

19、減少Cookie的大小

20、使用無cookie的域

比如圖檔 CSS 等,Yahoo! 的靜态檔案都在 yimg.com 上,用戶端請求靜态檔案的時候,減少了 Cookie 的反複傳輸對主域名 (yahoo.com) 的影響。

21、不要使用濾鏡

png24的在IE6半透明那種東西,别亂使,淡定的切成PNG8+jpg

22、不要在HTML中縮放圖檔

23、縮小favicon.ico并緩存

繼續閱讀