雅虎十四條 - 14個優化網站性能提升網站訪問速度的技巧

14個優化網站性能提升網站訪問速度的技巧

又叫「雅虎十四條」,想起一年前那個懵懂的我,大四傻乎乎的跑到大學城面試前端,那個時候覺得寒暑假看了兩套CSS的視頻,就很牛B了,出發先還把視頻溫了一下,嗯嗯,這是滑動門,嗯嗯這是絕對定位,嗯嗯這是浮動清除……

當時是彪叔面試個人,當時我還不知道那我的,全身黑漆漆的,黑色T-shirt,黑色皮膚,黑色帽子,黑色墨鏡,還有點黑色鬍渣的人,就是彪叔,補作了試題後支支吾吾的跟他談了一下,發現徹底不行,第一個問題是「雅虎十四條」是什麼?而後我蒙了,pardon? 聽都沒聽過,接着就陣亡了,回家後發了篇日誌在QQ空間,不過當時也是隻知其一;不知其二,今天看了一成天,把它貼出來跟你們分享:


相信互聯網已經愈來愈成爲人們生活中不可或缺的一部分。ajax,flex等等富客戶端的應用使得人們越加「幸福」地體驗着許多原先只能在C/S實 現的功能。好比Google機會已經把最基本的office應用都搬到了互聯網上。固然便利的同時毫無疑問的也使頁面的速度愈來愈慢。本身是作前端開發 的,在性能方面,根據yahoo的調查,後臺只佔5%,而前端高達95%之多,其中有88%的東西是能夠優化的。




以上是一張web2.0頁面的生命週期圖。工程師很形象地講它分紅了「懷孕,出生,畢業,結婚」四個階段。若是在咱們點擊網頁連接的時候可以意識到 這個過程而不是簡單的請求-響應的話,咱們即可以挖掘出不少細節上能夠提高性能的東西。今天聽了淘寶小馬哥的一個對yahoo開發團隊對web性能研究的 一個講座,感受收穫很大,想在blog上作個分享。

相信不少人都聽過優化網站性能的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中,你能夠用它很方便地來看看本身的網站在這幾個方面的表現。




這是對用yslow對個人網站西風坊測評的結果,很遺憾,只有51分。呵呵。中國各大網站的分值都不高,剛測了一下,新浪和網易都是31分。而後 yahoo(美國)的分值確實97分!可見yahoo在這方面做出的努力。從他們總結的這14條規則,已經如今又新增長的20個點來看,有不少細節咱們真 得是怎麼都不會去想,有些作法甚至是有些「變態」了。



第一條、儘量的減小 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%或更多。

CDN技術示意圖:





CDN組網示意圖:





第三條、 添加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 )



將腳本放在頁面最下面的目的有那麼兩點: 一、 由於防止script腳本的執行阻塞頁面的下載。在頁面loading的過程當中,當瀏覽器讀到js執行語句的時候必定會把它所有解釋完畢後在會接下來讀下 面的內容。不信你能夠寫一個js死循環看看頁面下面的東西還會不會出來。(setTimeout 和 setInterval的執行有點相似於多線程,在相應的響應時間以前也會繼續下面的內容渲染。)瀏覽器這麼作的邏輯是由於js隨時可能執 行 location.href或是其餘可能徹底中斷此頁面過程的函數,即如此,固然得等他執行完畢以後再加載咯。因此放在頁面最後,能夠有效減小頁面可 視元素的加載時間。 二、腳本引發的第二個問題是它阻塞並行下載數量。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",至於服務器類的,來日方長,我們慢慢學……只要有熱情在,早晚都會學到手……


後補一下,由於如今十四條已經擴展了不少,在這篇文章上面能夠看到詳細的分析:

http://uicss.cn/yslow/#more-12319

在Yslow上面能夠看到有23條之多,看下圖:



減小HTTP請求次數
合併圖片、CSS、JS,改進首次訪問用戶等待時間。
使用CDN
就近緩存==>智能路由==>負載均衡==>WSA全站動態加速
避免空的src和href
當link標籤的href屬性爲空、script標籤的src屬性爲空的時候,瀏覽器渲染的時候會把當前頁面的URL做爲它們的屬性值,從而把頁面的內容加載進來做爲它們的值。測試
爲文件頭指定Expires
使內容具備緩存性。避免了接下來的頁面訪問中沒必要要的HTTP請求。
使用gzip壓縮內容
壓縮任何一個文本類型的響應,包括XML和JSON,都是值得的。
把CSS放到頂部
把JS放到底部
防止js加載對以後資源形成阻塞。
避免使用CSS表達式
將CSS和JS放到外部文件中
目的是緩存,但有時候爲了減小請求,也會直接寫到頁面裏,需根據PV和IP的比例權衡。
權衡DNS查找次數
減小主機名能夠節省響應時間。但同時,須要注意,減小主機會減小頁面中並行下載的數量。
IE瀏覽器在同一時刻只能從同一域名下載兩個文件。當在一個頁面顯示多張圖片時,IE 用戶的圖片下載速度就會受到影響。因此新浪會搞N個二級域名來放圖片。
精簡CSS和JS
避免跳轉
同域:注意避免反斜槓 「/」 的跳轉;
跨域:使用Alias或者mod_rewirte創建CNAME(保存域名與域名之間關係的DNS記錄)
刪除重複的JS和CSS
重複調用腳本,除了增長額外的HTTP請求外,屢次運算也會浪費時間。在IE和Firefox中無論腳本是否可緩存,它們都存在重複運算JavaScript的問題。
配置ETags
它用來判斷瀏覽器緩存裏的元素是否和原來服務器上的一致。比last-modified date更具備彈性,例如某個文件在1秒內修改了10次,Etag能夠綜合Inode(文件的索引節點(inode)數),MTime(修改時間)和 Size來精準的進行判斷,避開UNIX記錄MTime只能精確到秒的問題。 服務器集羣使用,可取後兩個參數。使用ETags減小Web應用帶寬和負載
可緩存的AJAX
「異步」並不意味着「即時」:Ajax並不能保證用戶不會在等待異步的JavaScript和XML響應上花費時間。
使用GET來完成AJAX請求
當使用XMLHttpRequest時,瀏覽器中的POST方法是一個「兩步走」的過程:首先發送文件頭,而後才發送數據。所以使用GET獲取數據時更加有意義。
減小DOM元素數量
是否存在一個是更貼切的標籤可使用?標籤語義化,避免濫用無心義標籤
避免404
有些站點把404錯誤響應頁面改成「你是否是要找***」,這雖然改進了用戶體驗可是一樣也會浪費服務器資源(如數據庫等)。最糟糕的狀況是指向外部 JavaScript的連接出現問題並返回404代碼。首先,這種加載會破壞並行加載;其次瀏覽器會把試圖在返回的404響應內容中找到可能有用的部分當 做JavaScript代碼來執行。
減小Cookie的大小
使用無cookie的域
好比圖片 CSS 等,Yahoo! 的靜態文件都在 yimg.com 上,客戶端請求靜態文件的時候,減小了 Cookie 的反覆傳輸對主域名 (yahoo.com) 的影響。
不要使用濾鏡
png24的在IE6半透明那種東西,別亂使,淡定的切成PNG8+jpg
不要在HTML中縮放圖片
縮小favicon.ico並緩存javascript

相關文章
相關標籤/搜索