原文地址:http://developer.yahoo.com/performance/rules.html
本文在尊重原文基礎(chǔ)上,,盡量翻譯得通俗易懂一些。
本文內(nèi)容
下面是使頁面更快的35個最佳實(shí)踐,,它們被劃分為7個類別,。 類別: content、server,、cookie,、css、javascript,、images,、mobile (Yahoo 開發(fā)的瀏覽器插件 YSLOW,利用這七個類作為評價頁面的指標(biāo))
最大限度減少 HTTP 請求類別: content 最終用戶(the end-user)80%的響應(yīng)時間花費(fèi)在前端(the front-end),。大部分時間用來下載頁面中的所有組件:圖像,、CSS、JS,、Flash 等,。因此,反過來,,減少頁面組件的數(shù)量,,就可以減少渲染(呈現(xiàn))頁面所需的 HTTP 請求的數(shù)量,。這是加快頁面的關(guān)鍵。 一個方法當(dāng)然是簡化頁面設(shè)計(jì),,減少頁面組件的數(shù)量,。但是否有方法,既構(gòu)建具有豐富內(nèi)容的網(wǎng)頁,,也實(shí)現(xiàn)了快速響應(yīng),?下面是減少 HTTP 請求數(shù)量的技巧,也提供了豐富的網(wǎng)頁設(shè)計(jì),。
CSS Sprites 是一種 CSS 圖像拼合技術(shù),一種網(wǎng)頁圖片應(yīng)用處理方式,。
減少頁面的HTTP請求的數(shù)量首選要做的事,,對于改善用戶初次訪問頁面的性能,,這是最重要準(zhǔn)則。正如 Tenni Theurer 在其文章 Browser Cache Usage - Exposed! 指出的,,每天訪問你網(wǎng)站的 40-60% 人都是無緩存的(都是初次訪問,,無本地緩存)。使頁面對初次訪問更快,,是更好的用戶體驗(yàn)的關(guān)鍵,。這些首次訪問者的頁面快速更好的用戶體驗(yàn)是關(guān)鍵。 批注一個頁面往往包含很多資源,,比如圖像,、JS、CSS 等,,而這些資源都在服務(wù)器上,,客戶端若想顯示這個頁面,必須通過網(wǎng)絡(luò)從服務(wù)器下載資源到本地,??上攵m然每個資源都很小,,也就在幾十 K 左右,,但是數(shù)量很多,客戶端每次需要這樣資源,,都會到服務(wù)器上下載,,因此,減少下載的次數(shù),,或是下載完后,,直接從瀏覽器緩存里獲得,將很有意義,。 本節(jié)的技巧:合并文件,、CSS Sprites、Image maps,、Inline images 都是為了減少下載次數(shù),。比如,如果一個頁面需要三個 CSS,,那么在用戶初次訪問頁面時,,需要向服務(wù)器請求三次,。因此,若將這三個 CSS 合并成一個,,那么只需下載一次,;圖像也是如此,一個頁面最多的就是圖像,,試想網(wǎng)站的導(dǎo)航條,,與其為每個操作都搞一個圖片,倒不如將這些圖片合并在一個圖像上,,再通過 CSS 獲得圖片局部區(qū)域,。
使用內(nèi)容分發(fā)網(wǎng)絡(luò)(CDN)類別: server 用戶“接近”你Web服務(wù)器的程度會影響響應(yīng)時間。把內(nèi)容部署在多個,、地理位置分散的服務(wù)器上,,會使頁面加載的速度從用戶角度看更快。但是我們應(yīng)該從哪里開始,? 作為實(shí)現(xiàn)地理位置分散內(nèi)容的第一步,,不要試圖重新設(shè)計(jì)你的Web應(yīng)用程序,使它運(yùn)行在一個分布式的結(jié)構(gòu)中,。根據(jù)應(yīng)用程序,,改變結(jié)構(gòu),包括跨服務(wù)器同步會話狀態(tài)和復(fù)制數(shù)據(jù)庫事務(wù)等,,這些艱巨的任務(wù),。根據(jù)不同的應(yīng)用,改變結(jié)構(gòu)可以包括跨服務(wù)器的位置同步會話狀態(tài)和復(fù)制數(shù)據(jù)庫交易等艱巨任務(wù),。嘗試減少用戶和內(nèi)容之間的距離,,可以延遲,或從不通過,,這是應(yīng)用程序結(jié)構(gòu)的步驟,。 記住,最終用戶的80-90% 響應(yīng)時間花費(fèi)在下載所有頁面的組件:圖像,、CSS,、JS、Flash 等,,這是提高性能的黃金法則,。最好先分散你的靜態(tài)內(nèi)容,,如圖像,、CSS、JS,、Flash 等,,而不是重新設(shè)計(jì)應(yīng)用程序結(jié)構(gòu)艱巨的工作開始,。由于內(nèi)容發(fā)布網(wǎng)絡(luò),不僅大幅度減少了響應(yīng)時間,,而且簡化了應(yīng)用程序,。 一個 CDN 是一個處于多個位置的 Web 服務(wù)器的集合,更有效地向用戶發(fā)送內(nèi)容,。選擇哪個服務(wù)器發(fā)送內(nèi)容給特定用戶通常是基于一個網(wǎng)絡(luò)評估,。例如,選擇最少的網(wǎng)絡(luò)跳數(shù)或最快的響應(yīng)時間,。 一些大型的互聯(lián)網(wǎng)公司擁有自己的 CDN,,而通過 CDN 服務(wù)提供商,如 Akamai Technologies,, EdgeCast 或 level3,,成本則很高。對于剛成立的公司和私人站點(diǎn),,一個 CDN 服務(wù)的成本可以讓人望而卻步,,但當(dāng)你越來越受關(guān)注,并全球化時,,一個 CDN 是必需的,,以便快速響應(yīng)。以 Yahoo! 為例,,他們把靜態(tài)內(nèi)容從應(yīng)用程序中移到 CDN(上面提到 CDN 服務(wù)提供商,,以及他們自己的 CDN)上,提高了最終用戶 20% 以上的響應(yīng)時間,。使用 CDN 是一個只需要相對簡單地修改代碼,,顯著改善站點(diǎn)速度的方法。 批注客戶端訪問服務(wù)器,,要經(jīng)過路由,,是要計(jì)算代價的,最小跳數(shù)也好,,最少響應(yīng)時間也罷,,所以將自己的網(wǎng)站內(nèi)容部署在多個地理位置是有必要的。
添加 Expires 或 Cache – Control 頭類別: server 此規(guī)則有兩個方面:
隨著頁面越來越豐富,,這意味著更多的 JS,、CSS、圖像和 Flash。一個初次訪問頁面的用戶會發(fā)出很多 HTTP 請求,,但是通過 Expires 頭,,你可以使那些組件被瀏覽器緩存。在之后的頁面瀏覽,,就避免了不必要的 HTTP 請求,。Expires 頭經(jīng)常用在圖像,但也可以用在包括 JS,、CSS 和 Flash 所有組件,。 瀏覽器(和代理)使用緩存來減少 HTTP 請求的次數(shù)和規(guī)模,使頁面加載速度更快,。一個 Web 服務(wù)器在 HTTP 響應(yīng)中使用 Expires 頭,,會告訴客戶端這個組件被緩存多長時間。下面 Expires 頭告訴瀏覽器,,這個響應(yīng)直到 2011年4月15日 都是可靠的,。 Expires: Thu, 15 Apr 2011 20:00:00 GMT 如果你的服務(wù)器是 Apache,使用 ExpiresDefault 指令來設(shè)置相對于當(dāng)前日期的過期時間,。下面例子 ExpiresDefault 指令設(shè)置過期時間為發(fā)出請求后的 10年,。 ExpiresDefault "access plus 10 years" 記住,如果使用 Expires 頭,,那么當(dāng)組件改變時,,你必須改變組件的文件名。以 Yahoo 為例,,常常使這步作為生成過程的一部分:一個版本號內(nèi)置在組件文件名,,如 yahoo_2.0.6.js。 使用 Expires 頭只影響那些用戶已經(jīng)瀏覽過的頁面,。當(dāng)用戶初次訪問,,瀏覽器緩存為空時,不會影響 HTTP 請求的數(shù)量,。因此,,這種性能改善的影響取決于用戶多長時間會在 primed cache (primed cache 是已經(jīng)包含頁面中的所有組件,它與 Empty Cache 相對)命中你的頁面,。我們在 Yahoo 做了測試,,發(fā)現(xiàn)在 primed cache 瀏覽頁面的頻率是 75-85 %。通過使用 Expires 頭,,增加被瀏覽器緩存的組件數(shù)量,,在接下來的瀏覽中可以重用,而無需通過用戶的網(wǎng)絡(luò)連接發(fā)送任何字節(jié),。 批注根據(jù) Yahoo 的統(tǒng)計(jì),,用戶從緩存中獲得頁面所有組件的頻率在 75-85 %,,那么我們很有必要告訴瀏覽器如何緩存頁面資源。比如圖像,、CSS 這樣的靜態(tài)資源,就告訴瀏覽器永不過期,。而對動態(tài)資源,,則告訴瀏覽器,要有條件的請求,,別重新請求,。
Gzip 組件類別: server 通過網(wǎng)絡(luò)傳輸 HTTP 請求和響應(yīng)所花費(fèi)的時間,可以通過前端機(jī)制而得到顯著減少,。事實(shí)上,,最終用戶的寬帶速度、Internet 服務(wù)器提供商,、點(diǎn)對點(diǎn)交換接近程度等等,,因素不是開發(fā)團(tuán)隊(duì)能控制的,但是,,還有其他影響響應(yīng)時間的因素(這些是可以控制的),。壓縮,通過減小 HTTP 響應(yīng)的大小,,來減少響應(yīng)時間,。 從 HTTP/1.1 開始,Web 客戶端用 HTTP 請求中的 Accept – Encoding 頭來指示是否支持壓縮,。 Accept-Encoding: gzip, deflate 如果 Web 服務(wù)器在請求中看到這個頭,,它可以利用客戶端列出的方法之一壓縮響應(yīng)。Web服 務(wù)器通過響應(yīng)的 Content – Encoding 頭通知客戶端,。 Content-Encoding: gzip Gzip 是目前最流行和最有效的壓縮方法,。它是由 GNU 開發(fā)的項(xiàng)目,并通過 RFC 1952 標(biāo)準(zhǔn)化,。你可能看過其他壓縮格式——deflate,,但它的效率較差,不太流行,。 Gzip 壓縮一般可以減少約 70% 的響應(yīng)大小,。目前大約有 90% 通過瀏覽器的互聯(lián)網(wǎng)流量,都聲稱支持Gzip,,今天的互聯(lián)網(wǎng)流量約 90% 穿過聲稱支持 gzip 的瀏覽器,。如果你使用 Apache,配置 Gzip 模塊取決于你的版本:Apache 1.3 使用 mod_gzip ,,而 Apache 2.x mod_deflate,。 總所周知,瀏覽器和代理帶來的問題是,可能會導(dǎo)致瀏覽器期望的與它收到的壓縮內(nèi)容不匹配,。幸好,,這種特殊情況隨著舊式瀏覽器使用的減少在減少。Apache 模塊會自動添加變化的響應(yīng)頭來解決這個問題,。 服務(wù)器選擇什么壓縮成 gzip,,要根據(jù)文件類型,但通常很有限,。大多數(shù)網(wǎng)站壓縮他們的 HTML 文件,,腳本和 CSS 也很值得壓縮,但是很多站點(diǎn)錯過了這個機(jī)會,。事實(shí)上,,壓縮任何文本響應(yīng),包括 XML 和 JSON,,都是值得的,。圖像和 PDF 文件不應(yīng)該被壓縮,因?yàn)樗鼈円呀?jīng)被壓縮了,。試圖壓縮他們,,不僅浪費(fèi) CPU,還會潛在增加文件的大小,。 用 Gzip 壓縮盡可能多的文件類型是一種減小頁面大小,,加速用戶體驗(yàn)的簡單方法。 批注如果你了解 HTTP 協(xié)議,,或是用相關(guān)網(wǎng)頁測試工具,,那么一定知道服務(wù)器對客戶端都響應(yīng)了些什么。瀏覽器接收這些內(nèi)容后,,解析,,并呈現(xiàn)給用戶。無論是接收 CSS ,、腳本文件,,還是圖像,那么服務(wù)器的響應(yīng)的時候,,將它們壓縮,,再發(fā)送給客戶端,就是很符合邏輯的結(jié)果,。
CSS 放在頁面頂部類別:css 在研究 Yahoo! 的性能時,,我們發(fā)現(xiàn),把 CSS 放到 HEAD 標(biāo)記使得頁面加載快了,。這是因?yàn)?,?CSS 放在 HEAD 標(biāo)記使得頁面逐漸地呈現(xiàn),。 關(guān)心性能的前端工程師期望一個頁面能逐漸加載。也就是說,,我們希望瀏覽器盡快顯示內(nèi)容,。這對于擁有較多內(nèi)容的頁面和網(wǎng)速較慢的用戶來說特別重要。給用戶返回可見的反饋的重要性,,比如進(jìn)度指示,,已經(jīng)做了很好的研究,并形成了正式文檔,。在我們看來,,HTML 頁面就是進(jìn)度指示器,。當(dāng)瀏覽器逐漸加載頁面,,頭部、導(dǎo)航條,、頂部 logo 等等,,對于等待頁面加載的用戶來說,都可以作為可見的反饋信息,。這便從整體上改善了用戶體驗(yàn),。 把CSS放在接近文檔底部的問題是,阻止在很多瀏覽器上逐漸呈現(xiàn),,包括 Internet Explorer,。這些瀏覽器阻塞呈現(xiàn)是為了避免,如果式樣改變,,那么必須重繪頁面元素,。用戶不得不面對一個空白頁面,。 HTML 規(guī)范清楚地指出 CSS 要包含在頁面的 HEAD 區(qū)域:“與 A 不同,<link />只能出現(xiàn)在文檔的 HEAD 區(qū)域,盡管它可以出現(xiàn)很多次,。”無論是白屏,,還是出現(xiàn)沒有式樣的內(nèi)容,,都是不值得的。最好的解決方法就是按照 HTML 規(guī)范,,在文檔的 HEAD 里加載 CSS,。 批注有種情況,你一定見過:當(dāng)很多人下載電影,,占了帶寬,,網(wǎng)頁要么打不開,要么打開了,,有內(nèi)容沒式樣,。瀏覽器解析服務(wù)器發(fā)過來的頁面,,總是有個順序問題的。比如,,在沒獲得 CSS 文件前,,就準(zhǔn)備呈現(xiàn)頁面是沒有意義的。
腳本放在頁面底部類別:javascript 腳本帶來的問題是它阻止了并行下載,。HTTP/1.1 規(guī)范建議,,瀏覽器并行下載,每個主機(jī)不能超過 2 個組件,。如果你的圖片放在多個主機(jī)上,,那么你可以從每個主機(jī)并行下載兩個資源。然而,,當(dāng)下載腳本時,,瀏覽器就不會下載其他資源,即便資源位于不同的主機(jī),。 在某些情況下,,把腳本放在底部不太容易。比如,,如果腳本使用 document.write 向頁面插入內(nèi)容,,它就不能被往下移。這里還會有作用域問題,。很多情況下,,都會遇到這方面問題。 一個經(jīng)常用的方法是使用延遲腳本(deferred scripts),。DEFER 屬性指示,,腳本不包含 document.write,告訴瀏覽器可以繼續(xù)呈現(xiàn),。不幸的是,,F(xiàn)irefox 并不支持 DEFER 屬性。在 Internet Explorer 中,,腳本可以被延遲,,但效果可能不像期望的那樣。如果腳本可以被延遲,,那么它就可以被移到頁面的底部,,這將使頁面加載加快。 批注這點(diǎn)很容易理解,。如果不考慮上面提到 document.write 情況,,那么絕大多數(shù)腳本,要么是創(chuàng)建頁面標(biāo)記(控件),,要么修改頁面標(biāo)記,,無論從那個角度講,,腳本最后執(zhí)行都是最合適的。 比如,,你在 HEAD 里的腳本使用了頁面的元素,,那估計(jì)腳本會報錯,因?yàn)樵啬菚r還沒有被創(chuàng)建,。所以,,CSS、JS 等頁面資源,,別亂放,。 現(xiàn)在的 Ajax 框架,比如 jQuery 的 ready 方法,,Ext.Net 的 Ext.onReady 方法等都是處于這個目的,。
避免 CSS 表達(dá)式類別:css CSS 表達(dá)式是動態(tài)設(shè)置 CSS 屬性強(qiáng)大(而危險)的方法。從 Internet Explorer 5 開始支持 CSS 表達(dá)式,,但從 IE 8 開始被廢棄,。下面例子,,使用 CSS 表達(dá)式實(shí)現(xiàn)每隔一個小時設(shè)置一次背景顏色: background-color: ( (new Date()).getHours()%2 ? "#B8D4FF" : "#F08A00" ); 如上所示,,CSS 表達(dá)式使用了一個 JavaScript 表達(dá)式。CSS 屬性根據(jù) JavaScript 表達(dá)式的計(jì)算結(jié)果來設(shè)置,。表達(dá)式在其它瀏覽器中不起作用,,因此,在跨瀏覽器的設(shè)計(jì)中,,針對 Internet Explorer 設(shè)置屬性會比較有用,。 CSS 表達(dá)式的問題在于它的計(jì)算頻率比我們想象得多。不僅在頁面顯示和縮放時,,也在頁面滾動,,甚至在界面上移動鼠標(biāo),都會重新計(jì)算,。給 CSS 表達(dá)式增加一個計(jì)數(shù)器可以讓我們跟蹤表達(dá)式何時計(jì)算以及計(jì)算頻率,。隨便在頁面里移動鼠標(biāo)都可以輕松達(dá)到 10000 次以上。 減少 CSS 表達(dá)式計(jì)算次數(shù)的一個方法是使用一次性的表達(dá)式,。當(dāng)?shù)谝淮斡?jì)算表達(dá)式時,,它將結(jié)果賦值給式樣屬性,并用這個值代替 CSS 表達(dá)式,。如果樣式屬性必須在頁面周期內(nèi)動態(tài)地改變,,那么一個可行的方法是使用事件處理,而不是 CSS 表達(dá)式,。如果你必須使用 CSS 表達(dá)式,,那么一定要記住,,它們可能要運(yùn)行成千上萬次,有可能會影響以哦面性能,。 批注雖然有用,,但存在的問題很突出、更要命,。所以,,還是不要使用的好。
使用外部 JavaScript 和 CSS類別:javascript,,css 很多性能規(guī)則都是如何管理外部文件,?但在你思考這些問題前,你應(yīng)該問一個更基本的問題:JavaScript 和 CSS 是應(yīng)該放在外部文件中,,還是應(yīng)該內(nèi)嵌在頁面里,? 實(shí)際中,使用外部文件通??梢蕴岣唔撁嫠俣?,因?yàn)椋琂avaScript 和 CSS 文件可以被瀏覽器緩存,。而內(nèi)嵌在 HTML 文檔中的 JavaScript 和 CSS 會在每次請求 HTML 文檔時被重新下載,。這雖然減少了所需的 HTTP 請求次數(shù),卻增加了 HTML 文檔的大小,。而另一方面,,如果 JavaScript 和 CSS 在外部文件,并被瀏覽器緩存,,那么在沒有增加 HTTP 請求次數(shù)情況下,,減少 HTML 文檔的大小。 然而,,關(guān)鍵問題是,,被緩存的外部 JavaScript 和 CSS 組件的頻率,與請求 HTML 文檔的次數(shù)有關(guān),。盡管很難量化,,但還是有很多指標(biāo)來測量它。如果用戶在每次會話中瀏覽你網(wǎng)站的多個頁面,,而這些頁面重用了 腳本 和CSS,,那么使用可以被瀏覽器緩存的外部文件將會帶來很大好處。 很多的網(wǎng)站沒能建立起這些指標(biāo),。對這些網(wǎng)站,,一般來說,最好的解決方法是把 JavaScript 和 CSS 作為外部文件來部署。適合采用內(nèi)嵌代碼的唯一例外是網(wǎng)站的主頁,,如 和 My Yahoo!,。主頁在每次會話中很少被瀏覽,你會發(fā)現(xiàn),,在主頁嵌入 JavaScript 和 CSS 對最終用戶的響應(yīng)時間更快,。 對于擁有較大訪問量的首頁,有一種技術(shù)可以平衡嵌入代碼帶來的減少 HTTP 請求,,與使用外部文件帶來緩存的好處,。其中一個技術(shù)就是在首頁中嵌入 JavaScript 和 CSS,但完成加載后,,動態(tài)下載外部文件,。接下來的頁面就會使用已經(jīng)被瀏覽器緩存的外部文件。 批注既然只有外部文件才可以被瀏覽器緩存,,那么何樂不為呢,。而且嵌入到頁面腳本代碼,也不好維護(hù),,同時,,會增大頁面大小。
減少 DNS 查詢類別:content 域名解析系統(tǒng)(DNS)提供域名和 IP 的映射,,就像電話本映射人名與他們的電話號碼一樣,。當(dāng)你在瀏覽器地址欄鍵入 www. 時,DNS 解析會返回給瀏覽器對應(yīng)的 IP,。DNS 解析是有時間代價的,。一般情況下,,查找給定域名對應(yīng)的 IP,,需要 20 到 120 毫秒。在這個過程中,,瀏覽器不會下載任何東西,,直到 DNS 查詢完畢。 緩存 DNS 查詢可以改善性能,。DNS 緩存發(fā)生在要一個特定的緩存服務(wù)器,,由用戶的 ISP 或本地網(wǎng)絡(luò)維護(hù),但也會緩存在用戶自己的機(jī)器上,。DNS 信息保存在操作系統(tǒng)的 DNS 緩存中(微軟 Windows 操作系統(tǒng)的 "DNS Client Service"),。大多數(shù)瀏覽器都有自己的緩存,它獨(dú)立于操作系統(tǒng)之外,。只要瀏覽器在自己的緩存維護(hù)一個 DNS 信息,,在一次請求中就不會受到操作系統(tǒng)的影響。 默認(rèn)情況下,,Internet Explorer 的 DNS 緩存為 30 分鐘,,由注冊表的 DnsCacheTimeout 規(guī)定,。Firefox 的 DNS 緩存為 1 分鐘,由配置文件 network.dnsCacheExpiration 控制(Fasterfox 為 1 小時),。 當(dāng)客戶端的 DNS 緩存為空(瀏覽器和操作系統(tǒng)的 DNS 緩存都為空),,DNS 查詢的次數(shù)等于頁面中主機(jī)的數(shù)量。這包括頁面中的 URL,、圖像,、JS、CSS,、Flash 等使用的主機(jī),。減少唯一主機(jī)名的數(shù)量就可以減少 DNS 查詢的次數(shù)。 但減少唯一主機(jī)名的數(shù)量潛在地減少了并行下載的數(shù)量,。雖然避免 DNS 查詢次數(shù)節(jié)省了響應(yīng)時間,,但是減少并行下載卻增加了響應(yīng)時間。我的原則是,,把頁面組件分割在 2 個到 4 個主機(jī)之間,。這樣就是在減少 DNS 查詢次數(shù)與較高的并行下載之間獲得了權(quán)衡。 批注Yahoo 還真是,,任何一個環(huán)節(jié)都不放過,。但是試想一下,DNS 查詢在 20-120 毫秒之間,,這個時間里相當(dāng)于可以從服務(wù)器上下載 1-2 個幾十k的資源,,也許是 CSS 文件,也許是腳本文件,,也許是圖片,,所以減少 DNS 查詢還是很有必要的。
精簡 JavaScript 和 CSS類別:javascript,,css “精簡”是工程實(shí)踐的結(jié)論,,從代碼中去掉不必要的字符,以減少文件大小,,從而節(jié)省加載時間,。去掉代碼的所有注釋、空白字符(包括空格,、換行,、tab)。在 JavaScript 中,,這會提高響應(yīng)時間,,因?yàn)闇p少了下載文件的大小。精簡 JavaScript 代碼最流行、最廣泛的兩個工具是 JSMin 和 YUI Compressor,。YUI Compressor 還可用于精簡 CSS,。 “混淆”是另外一種可用于源代碼優(yōu)化的方法。該方法要比精簡復(fù)雜一些,,并且混淆很可能產(chǎn)生 BUG,。在對美國前 10 名的網(wǎng)站調(diào)查中發(fā)現(xiàn),“精簡”可以縮小源代碼 21% 的體積,,而“混淆”可以達(dá)到 25%,。盡管“混淆”可以更大程度減少代碼大小,但精簡 JavaScript 的風(fēng)險更小,。 除了精簡外部 JavaScript 和 CSS,,內(nèi)嵌的 <script> 和 <style> 代碼塊也可以(應(yīng)該)精簡。即使使用 Gzip 壓縮過的 JavaScript 和 CSS,,“精簡”文件仍然可以減少 5% 以上的大小,。隨著使用的 JavaScript 和 CSS 大小的增加,精簡代碼將會獲得更大的益處,。 批注無論是 JavaScript,,還是 CSS,所有頁面資源都是要從服務(wù)器下載的,,它們當(dāng)然是越小越好,。所以往往,三方框架,,比如 jQuery 等,,都會提供腳本文件的正式版本(精簡過的,如果你打開看一下,,密密麻麻一坨)和它們的debug版本,。
避免重定向類別:content “重定向”是通過 HTTP 狀態(tài)碼 301 和 302 完成的。下面是一個 301 響應(yīng)的 HTTP 頭: HTTP/1.1 301 Moved Permanently Location: http:///newuri Content-Type: text/html 瀏覽器會自動地把用戶定向到 Location 中指定的 URL,。所有重定向需要的信息位于頭中,。響應(yīng)的內(nèi)容可以是空的。無論是 301 響應(yīng),,還是 302,它們都不會被緩存,,除非增加一個額外的頭選項(xiàng),,如 Expires 或者 Cache-Control,來指定可以被緩存,。meta 標(biāo)記和 JavaScript 是另一個實(shí)現(xiàn)重定向的方法,,但是如果你必須要跳轉(zhuǎn),那最好的方法是使用標(biāo)準(zhǔn)的 3XX HTTP 狀態(tài)碼,這主要是為了確?!昂笸恕卑粹o可以正確地使用,。 需要記住的主要事情是,重定向會降低用戶體驗(yàn),。在用戶和 HTML 文檔之間插入一個跳轉(zhuǎn),,會延遲頁面中所有元素的呈現(xiàn),因?yàn)?,?HTML 文件被加載前,,頁面的任何東西都不會被呈現(xiàn),組件也不會被下載,。 經(jīng)常發(fā)生,,最浪費(fèi)的重定向,也經(jīng)常被網(wǎng)頁開發(fā)者忽略,。那就是,,URL 缺少斜杠(/),可本應(yīng)該有,。例如,,訪問 http://astrology.yahoo.com/astrology 會導(dǎo)致 301 響應(yīng)代碼的跳轉(zhuǎn),連接應(yīng)該是 http://astrology.yahoo.com/astrology/ (注意末尾的斜杠),。在 Apache 中,,可以使用 Alias 或者 mod_rewrite,或者 DirectorySlash 檢測來避免,。 另一個經(jīng)常使用重定向的情況是,,把舊網(wǎng)站連接到新網(wǎng)站。其他情況如連接網(wǎng)站的不同部分,,或根據(jù)一定條件(瀏覽器類型,、用戶賬號類型等)來引導(dǎo)用戶。使用重定向連接兩個網(wǎng)站很簡單,,只需要很少的代碼,。盡管該方法對開發(fā)者來說,減少了復(fù)雜度,,但是缺降低了用戶體驗(yàn),。一個可替代的方法是,如果兩者在同一臺服務(wù)器上,,那么可以使用 Alias 和 mod_rewrite,。如果是因?yàn)橛蛎淖兌褂弥囟ㄏ颍敲纯梢越Y(jié)合 Alias 或 mod_rewrite,,使用 CNAME(創(chuàng)建從一個域名指向另外一個域名的 DNS 記錄),。 批注這個是有切身體會的,,尤其是使用客戶端重定向(瀏覽器重定向)時,頁面跳轉(zhuǎn)的速度實(shí)在是有點(diǎn)慢,。
刪除重復(fù)腳本類別:javascript 在一個頁面中引用同一個 JavaScript 文件兩次會影響性能,。這種情況可能并不常見。在對于美國前 10 名網(wǎng)站的調(diào)查中顯示,,其中的兩家存在重復(fù)引用腳本的情況,。有兩個主要因素增加一個頁面中重復(fù)引用腳本的幾率:團(tuán)隊(duì)規(guī)模和腳本數(shù)量。當(dāng)發(fā)生這種情況時,,重復(fù)引用腳本會創(chuàng)建不必要的 HTTP 請求,,以及延緩腳本執(zhí)行,從而損害性能,。 這種不必要的 HTTP 請求發(fā)生在 Internet Explorer,,而不會在 Firefox。在 Internet Explorer 中,,如果包含引用一個外部腳本兩次,,并且它還不可緩存,那么在頁面加載期間,,它會產(chǎn)生兩次 HTTP 請求,。即使腳本可被緩存,當(dāng)頁面重新加載時,,也會產(chǎn)生額外的 HTTP 請求,。 除了產(chǎn)生多余的 HTTP 請求,多次檢查腳本也會浪費(fèi)時間,。無論腳本是否可被緩存,,在 Internet Explorer 和 Firefox 中都會發(fā)生多余的腳本執(zhí)行。 一個避免意外地引用同一個腳本兩次的方法是,,在你的系統(tǒng)中,,開發(fā)腳本管理模塊。在 HTML 頁面中包含腳本的常見方法是使用 <script > 標(biāo)記: <script type="text/javascript" src="menu_1.0.17.js"></script> 而在 PHP 中,,通過創(chuàng)建名為 insertScript 方法: <?php insertScript("menu.js") ?>
為了防止多次插入同一個腳本,,該方法可以解決其他腳本問題,例如依賴檢查,,為腳本文件名添加版本號,,以便使用 Expire 頭。
配置 ETags類別:server “實(shí)體標(biāo)記(Entity tags,,ETags)”是 Web 服務(wù)器和瀏覽器用于確定,,瀏覽器緩存中的組件與服務(wù)器的一個原始內(nèi)容是否匹配的一種機(jī)制?!皩?shí)體”就是“組件”:圖像,、腳本、CSS 等,。添加 ETags 會提供一種驗(yàn)證實(shí)體的機(jī)制,,這比最后修改日期 last-modified date 更加靈活。一個 ETags 是一個唯一標(biāo)識一個特定版本組件的字符串,。字符串必須用雙引號括起來,。服務(wù)器通過 ETag 響應(yīng)頭來指定組件的 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ù)器。如果 ETags 匹配,,那么會返回 304 HTTP 狀態(tài)碼,,減少了 12195 字節(jié)的響應(yīng)。 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 ETags 的問題在于,,它們通常使用網(wǎng)站服務(wù)器的唯一的屬性來構(gòu)造,。當(dāng)瀏覽器從一臺服務(wù)器上獲得原始組件,之后,,嘗試驗(yàn)證另一臺服務(wù)器上的組件時,,ETags 就不會匹配。這種情況在使用集群服務(wù)器來處理請求的 Web 站點(diǎn)上相當(dāng)普遍,。默認(rèn)情況下,,Apache 和 IIS 都把數(shù)據(jù)嵌入入到 ETag 中,這樣能顯著減少在多服務(wù)器情況下,,成功在一臺服務(wù)器驗(yàn)證的幾率,。 Apache 1.3 和 2.x 的 ETag 格式是 inode-size-timestamp。即使一個給定的文件在多個服務(wù)器的相同目錄,,且具有相同的大小,、權(quán)限、時間戳等,,但它的 inode 仍然是不同的,。. IIS 5.0 和 IIS 6.0 的 ETags 具有類似的問題。IIS 的 ETag 格式是 Filetimestamp:ChangeNumber,。ChangeNumber 是一個計(jì)數(shù)器,,用來跟蹤 IIS 配置的改變。不同的是,,ChangeNumber 在一個 Web 站點(diǎn)的所有 IIS 都是相同的,。 對于完全相同的組件,在不同的服務(wù)器上,,由 Apache 和 IIS 產(chǎn)生的 ETags 不同,。如果 ETags 不匹配,,那么用戶不會收到一個小而快的 304 響應(yīng);而是,,會得到一個正常的 200 響應(yīng),,并下載全部內(nèi)容。如果你的網(wǎng)站只在一臺服務(wù)器上,,那不會有問題,。但是如果你的網(wǎng)站架設(shè)在多個服務(wù)器,并且使用 Apache,,或默認(rèn) ETag 配置的 IIS,,那么用戶獲得頁面會相對較慢,你的服務(wù)器負(fù)載較高,,帶寬消耗較大,,代理不會有效地緩存你的內(nèi)容。即使你的組件具有 Expires 頭,,無論用戶何時點(diǎn)擊“重載”或者“刷新”,,都會發(fā)送一個有條件的 GET 請求。 如果你沒有利用 ETag 提供的靈活驗(yàn)證模式,,那么最好把 ETag 刪掉,。Last-Modified 頭是基于組件時間戳來驗(yàn)證。刪掉 ETag 會在響應(yīng)和接下來的請求中減少 HTTP 頭的大小,。Microsoft Support article 文檔描述如何刪掉 ETag,。在 Apache 中,只需要在配置文件中簡單添加下面一行代碼就可以: FileETag none 批注這種為資源的生成唯一標(biāo)識的做法很常見,。如果文件有改動,,那么唯一標(biāo)識一定不同。
使 Ajax 可緩存類別:content Ajax 被提到的一個好處是,,由于它從服務(wù)器異步請求信息,,能為用戶提供即時反饋。然而,,使用 Ajax 并不能保證用戶不用等待那些返回的異步 JavaScript 和 XML 響應(yīng),。在很多應(yīng)用中,用戶是否等待取決于如何使用 Ajax,。例如,,在一個基于 Web 的 Email 客戶端中,用戶必須等待 Ajax 請求的結(jié)果,,返回符合查找條件的郵件信息,。很重要的一點(diǎn),“異步”并不意味著“即時”,。 為了提高性能,,優(yōu)化 Ajax 響應(yīng)很重要,。提高 Ajxa 性能的最重要的方法是使響應(yīng)可緩存,如“添加 Expires 和 Cache-Control 頭”小節(jié)描述的,。其他幾條規(guī)則也適用于 Ajax:
讓我們看一個例子:一個 Web2.0 Email 客戶端會使用 Ajax 自動下載該用戶的地址簿,。如果用戶在上次使用 Email Web 應(yīng)用程序后,,沒有修改地址簿,,那么,如果用 Expire 或者 Cacke-Control 頭設(shè)置 Ajax 可緩存,,就可以直接從緩存中讀取地址薄,。必須告訴瀏覽器,是使用緩存中的地址薄,,還是發(fā)送一個新的請求,。這可以通過給地址薄的 Ajax URL 添加一個時間戳,指示用戶最后修改地址簿的時間,,例如,,&t=11900241612。如果地址薄在上次讀取后沒有被修改過,,那么時間戳不變,,從瀏覽器的緩存中讀取地址簿,以減少額外的 HTTP 請求,。如果用戶修改了地址薄,,那么時間戳?xí)_保新的 URL 與緩存中的響應(yīng)不匹配,瀏覽器將請求新的地址簿,。 即便你的 Ajxa 響應(yīng)是動態(tài)生成的,,哪怕它只應(yīng)用于一個用戶,那也應(yīng)該把它們緩存起來,。這樣可以使你的 Web2.0 應(yīng)用程序響應(yīng)速度更快,。
盡早強(qiáng)制地發(fā)送緩沖給客戶端類別:server 當(dāng)用戶請求一個頁面時,無論如何后端都會花 200 到 500 毫秒,,以便組織 HTML 頁面,。期間,瀏覽器會一直是空閑的,,直到數(shù)據(jù)到達(dá),。在 PHP 中,你可以使用 flush() 方法,,它允許你把部分 HTML 響應(yīng)發(fā)送給瀏覽器,,這樣,瀏覽器就可以開始獲取組件,,同時后臺處理 HTML 頁面的剩余部分,。這樣做好處在后端繁忙,,而前端空閑時最明顯。 考慮強(qiáng)制發(fā)送的一個最好的地方是 HEAD 后,,因?yàn)?HTML 頭通常最容易生成,,讓你可以包含任何 CSS 和 JavaScript 文件,以便瀏覽器在開始并行下載的同時,,后端仍然在處理,。 例子: ... <!-- css, js --> </head> <?php flush(); ?> <body> ... <!-- content --> Yahoo! search 率先進(jìn)行了研究,真實(shí)的用戶測試表明了該技術(shù)的好處,。 批注不用等到全部內(nèi)容都有了,,再發(fā)給客戶端,這期間用戶都看不到,。有的話,,就立刻發(fā)出去,讓頁面“慢慢”呈現(xiàn)出來,。
使用 GET 發(fā)送 Ajax 請求類別:server Yahoo!Mail 團(tuán)隊(duì)發(fā)現(xiàn),,當(dāng)使用 XMLHttpRequest 時,瀏覽器中 POST 的實(shí)現(xiàn)是兩步過程:首先發(fā)送頭,,然后才發(fā)送數(shù)據(jù),。這樣,使用 GET 最好,,因?yàn)?,它只發(fā)送一個 TCP 包(除非你有很多 cookie)。IE URL 的最大長度為 2K,,因此,,如果你要發(fā)送一個超過 2K 的數(shù)據(jù),那就不能使用 GET,。 一個有趣的副作用是,,沒有真正發(fā)送任何數(shù)據(jù)的 POST 的行為有點(diǎn)像 GET。根據(jù) HTTP 規(guī)范,,GET 意味著“檢索”數(shù)據(jù),,因此,當(dāng)你只是查詢數(shù)據(jù)時,,GET 更加有意義(從語意上也是如此),,相反,發(fā)送并在服務(wù)端保存數(shù)據(jù)時使用 POST,。
延遲加載組件類別:content 你可以仔細(xì)看一下你的網(wǎng)頁,,問問自己“哪些內(nèi)容是頁面初次呈現(xiàn)所必需的?”。剩下的內(nèi)容和組件可以稍后加載,。 JavaScript 是一個理想的選擇,,按照 onload 事件分成兩部分,之前和之后,。例如,,如果你有用于完成拖拽效果的 JavaScript 和庫,那么它們可以稍后加載,,因?yàn)轫撁娴耐献г厥窃陧撁娉跏汲尸F(xiàn)后才發(fā)生的,。其他稍后加載的選擇包括隱藏的內(nèi)容(這些內(nèi)容是用戶操作后才出現(xiàn)的),以及處于折疊的圖像,。 幫你減輕該工作的工具:YUI Image Loader 可以讓你推遲加載折疊部分的圖片,。YUI Get utility 是包含 JS 和 CSS 的便捷方法。例如,,你可以用 Firebug 的 Net 選項(xiàng)卡看一下 Yahoo! Home Page。 當(dāng)性能目標(biāo)體現(xiàn)在 Web 開發(fā)的最佳實(shí)踐時,,就會有很好的效果,。這種情況下,通過漸進(jìn)增強(qiáng)(progressive enhancement )的思想告訴我們,,在支持 JavaScript 的情況下,,JavaScript 可以改進(jìn)用戶體驗(yàn),但是必須確保頁面沒有JavaScript 也可以正常工作,。因此,,在確保頁面運(yùn)行正常后,用延遲加載腳本來增強(qiáng)頁面,,比如拖拽和動畫腳本,。 批注剛開始只加載最基本,暫時不需要的組件,,就不用加載,。遵循“漸進(jìn)增強(qiáng)”原則。
預(yù)加載組件類別:content “預(yù)加載”和“延遲加載”看似相反,,但實(shí)際上“預(yù)加載”是為了實(shí)現(xiàn)另外一種目標(biāo),。通過預(yù)加載,你可以利用瀏覽器空閑的時間,,請求將來需要的組件(如圖像,、CSS 和腳本)。使用這種方法,,當(dāng)用戶要訪問下一個頁面時,,頁面的大部分組件都已經(jīng)在緩存中了,這會打打改善用戶加載頁面的速度。 下面是幾種“預(yù)加載”的方法:
批注最明顯的情況是,,“翻轉(zhuǎn)”效果。
減少 DOM 元素數(shù)量類別:content 一個復(fù)雜的頁面意味下載更多的數(shù)據(jù),,也就意味著 JavaScript 訪問 DOM 會變慢,。例如,當(dāng)你添加一個事件處理時,,遍歷頁面的 500 或 5000 個元素是不一樣的,。 大量的 DOM 元素是一個征兆,它意味著,,可以使用頁面標(biāo)記,,而無需刪除內(nèi)容。你是否布局而采用內(nèi)置表格,?是否僅僅為了自適應(yīng)而使用很多 DIV,?也許有一個更好,更符合語義的方法。 用 YUI CSS utilities 來布局很方便:grids.css 可以幫你整體布局,,font.css 和 reset.css 可以幫助你移除瀏覽器默認(rèn)的格式,。這提供了一個重新審視和思考標(biāo)記的機(jī)會,例如,,只有當(dāng)在語義上說得通時才使用<div>,,而不是因?yàn)樗艹尸F(xiàn)一個新行才使用。 DOM 元素數(shù)量很容易計(jì)算,,只需要在 Firebug 控制臺內(nèi)輸入: document.getElementsByTagName('*').length
那么多少個 DOM 元素算多,?可以對比一下好的頁面。比如 Yahoo! Home Page 是一個內(nèi)容很多的頁面,,但它只有 700 個元素(HTML 標(biāo)簽),。 批注頁面好看與頁面復(fù)雜總是很矛盾。夠炫的頁面往往都很復(fù)雜,,元素很多,,元素很多的話,JavaScript 訪問起來就會變慢,。
根據(jù)域名分割組件類別:content 分割組件可以使你最大限度地并行下載,。由于 DNS 查找的影響,確保你使用的域名在2到4個之間,。例如,你可以把 HTML 和動態(tài)內(nèi)容放在 www.example.org 上,,而把分割的靜態(tài)組件(圖片,、腳本、CSS)放在 statics1.example.org 和 statics.example.org,。 你可以在 Tenni Theurer 和 Patty Chi 合寫的文章 "Maximizing Parallel Downloads in the Carpool Lane" 找到更多相關(guān)信息,。 批注既然在 HTML 規(guī)范中規(guī)定資源是可以并行下載的,那么我們當(dāng)然可以將網(wǎng)站的資源分別存在不同的地方,。
最小化 iframe 數(shù)量類別:content ifrmae 元素可以在父文檔中插入一個新的 HTML 文檔,。了解 iframe 如何工作,才能有效地使用它,。 <iframe> 優(yōu)點(diǎn):
<iframe> 缺點(diǎn):
不要出現(xiàn) 404 錯誤類別:content HTTP 請求很昂貴。因此,,發(fā)送一個 HTTP 請求,,卻獲得一個無用的響應(yīng)(如,404 Not Found)是完全沒必要的,,它只會降低用戶體驗(yàn),,而不會有一點(diǎn)好處。 有些站點(diǎn)把 404 錯誤響應(yīng)頁面改為“你是不是要找***?”,,這雖然改進(jìn)了用戶體驗(yàn),,但卻浪費(fèi)了服務(wù)器資源(像數(shù)據(jù)庫等)。最糟糕的情況是指向一個外部 JavaScript 鏈接,,返回 404 錯誤,。首先,這個下載會阻塞并行下載,。其次,,瀏覽器會試圖解析 404 響應(yīng)的內(nèi)容,就像它是 JavaScript 代碼,,嘗試在里邊查找有用的東西,。
減小 Cookie 大小類別:cookie 使用 HTTP coockie 有很多原因,比如認(rèn)證(authentication )和個性化,。在 Web 服務(wù)器與瀏覽器之間,,通過 HTTP 頭來交換 coockie 信息。盡可能維持 coockie 的大小,,以減少對用戶響應(yīng)時間的影響,,很重要。 有關(guān)更多信息,,可以查看 Tenni Theurer 和 Patty Chi 的文章 "When the Cookie Crumbles",。該文內(nèi)容的研究包括:
對組件使用無 coockie 域名類別:cookie 當(dāng)瀏覽器請求一個靜態(tài)圖像,,并且隨請求發(fā)送 coockie 時,服務(wù)器并不會使用這些 coockie,。因此,,毫無疑問,它們(coockie )只會產(chǎn)生網(wǎng)絡(luò)流量,。你應(yīng)該確保請求靜態(tài)組件時,,請求中不帶 cookie。創(chuàng)建一個域,,把你所有的靜態(tài)組件放在該子域,。 如果你的域名是 ww.example.org,那么你可以把靜態(tài)組件放在 static.example.org 上,。然而,,如果你已經(jīng)在頂級域 example.org 設(shè)置了 coockie,,而不是在 www.example.org 上,那么,,所有對 static.example.org 的請求都將包含 coockie,。在這種情況下,你可以購買一個新域名,,存放你的靜態(tài)組件,,并讓這個域名無 coockie。Yahoo! 使用的是 ymig.com,,YouTube 使用的是 ytimg.com,,Amazon 使用 images-anazon.com 等。 使用無 coockie 域名存放靜態(tài)組件的另外一個好處是,,一些代理(服務(wù)器)可能會拒絕緩存帶 coockie 請求的組件,。相關(guān)建議是,如果你想確定是用 example.org 作為你的主頁,,還是 www.example.org,,那么,你可以考慮 coockie 帶來的影響,。沒有 www 的會把 coockie 設(shè)置到 *.example.org 的所有域,,這樣你就別無選擇了。因此,,出于性能的考慮,,最好使用 www 子域名,并在它上設(shè)置 coockie,。
最小化 DOM 訪問類別:javascript 用 JavaScript 訪問 DOM 元素比較慢,,因此為了更好響應(yīng)頁面,你應(yīng)該:
有關(guān)更多信息,請查看 Julien Lecomte 的文章 "High Performance Ajax Applications",。
開發(fā)智能事件處理程序類別:javascript 有時,,頁面反應(yīng)遲鈍,這是因?yàn)?,太多綁定?DOM 樹元素的事件處理,,并且被頻繁執(zhí)行。這就是為什么使用事件托管(event delegation),。如果你在一個 div 中有 10 個按鈕,,那么你只需在 div 上綁定一個事件處理(利用委托),而不是為每個按鈕,。事件冒泡時,,你可以捕捉到該事件,,并判斷出是哪個事件發(fā)出的。 你也不用為了操作 DOM 樹而等待 onload 事件,。通常,,你所需要就是訪問DOM 樹中可用的元素。你也不必等待所有圖像都加載完畢,。不用 onload,,DOMContentLoaded 是可以考慮的事件,但在所有瀏覽器都支持它之前,,你可使用 YUI Event 工具,,它有一個 onAvailable 方法。 有關(guān)更多信息,,參看 Julien Lecomte 的文章 "High Performance Ajax Applications",。 批注換句話說,通過事件委托,,我們可以為 10 個按鈕只使用一個事件,,而不是 10 個按鈕搞 10 個事件處理。比如,,增刪改三個按鈕,,可以用一個事件來弄,事件觸發(fā)時,,可以知道當(dāng)前操作的是什么,。
用 <link> 代替 @import類別:css 前面的最佳實(shí)踐提到,CSS 應(yīng)該放在頁面頂部,,以便漸進(jìn)呈現(xiàn),。 在 IE 中,@import 的行為相當(dāng)于把 <link> 放在頁面頂部,,因此最好不要使用它,。
避免使用濾鏡類別:css IE 獨(dú)有的 AlphaImageLoader 濾鏡旨在修復(fù) 7.0 以下版本的半透明真彩色 PNG 圖像問題。該濾鏡的問題是,,當(dāng)圖像正被下載時,,它會阻塞呈現(xiàn),并凍結(jié)瀏覽器,。濾鏡也會增加內(nèi)存消耗,,并被應(yīng)用到每個元素,而不是每個圖像,,因此,,濾鏡的問題是多方面的。 最好的方法是避免完全使用 AlphaImageLoader,,而是使用 PNG8,,它能在 IE 中很好地工作,。如果你確實(shí)需要使用 AlphaImageLoader,那應(yīng)該使用 hack_filter,,不會影響到 IE7 以上版本的用戶,。
優(yōu)化圖像類別:images 設(shè)計(jì)人員為頁面創(chuàng)建圖像后,向 Web 服務(wù)器上傳圖像前,,你可以試著做以下幾件事:
identify -verbose image.gif 如果你發(fā)現(xiàn)圖像中只用了 4 種顏色,,而調(diào)色板中是 256 色,,那么這張圖片就改進(jìn)的空間。
convert image.gif image.png
pngcrush image.png -rem alla -reduce -brute result.png
jpegtran -copy none -optimize -perfect src.jpg dest.jpg
優(yōu)化 CSS Sprites類別:images
不要在 HTML 中縮放圖像類別:images 不要使用比你實(shí)際需要的大的圖像,。因?yàn)槟憧梢栽O(shè)置長寬,。如果你需要: <img width="100" height="100" src="mycat.jpg" alt="My Cat" /> 那么你的圖像(mycat.jpg)就應(yīng)該是 100x100 像素,而不是把一個 500x500 像素的圖片縮小來用,。 批注使用多大的圖像,,就做多大的圖像。你可能見過,,往往一個內(nèi)容,,會有不同像素大小的版本,比如工具欄按鈕圖標(biāo),,同時做 16×16 像素,,和 32×32 像素的。
favicon.ico 要小且可緩存類別:images favicon.ico 是一個放在你服務(wù)器根位置的圖像,。這是個必需的邪惡,,因?yàn)椋词鼓悴魂P(guān)心它,,瀏覽器仍然會請求它,,因此,最好不要用 404 響應(yīng),。此外,,由于位于同一個服務(wù)器,每次發(fā)送 Cookie 都會請求它,。這個圖像也會干擾下載隊(duì)列,,例如,在 IE 中,,當(dāng)你在 onload 請求一個額外的組件時,,favicon 將在這些額外組件前被下載。 因此,,為了減輕 favicon.ico 弊端,,應(yīng)確保:
ImageMagick 可以幫助你創(chuàng)建小的 favicons(網(wǎng)站圖例),。 批注千萬別忘了 favicon.ico,。這是瀏覽器默認(rèn)下載的資源,。
保持組件 25K 以下類別:mobile 這個限制與一個事實(shí)有關(guān),iPhone 不能緩存操作 25K 大小的組件,。注意,,這是未壓縮的大小。這個小是很重要的,,因?yàn)閱为?dú) gzip 完全不夠,。 有關(guān)更多信息,參考 Wayne Shea 和 Tenni Theurer 的文章 "Performance Research, Part 5: iPhone Cacheability - Making it Stick",。
把組件打包到一個 Multipart 文檔類別:mobile 把組件打包到一個 multipart 文檔很像一個帶附件的email,,它能使你在一個 HTTP 請求中獲取多個組件(切記:HTTP 請求很昂貴)。當(dāng)你使用這個技術(shù)時,,首先要確定用戶代理是否支持(iPhone 不支持),。
避免圖片 src 屬性為空類別:server img src 屬性為空的經(jīng)常發(fā)生。它有兩種形式:
<img src="">
var img = new Image(); img.src = "";
這兩種形式效果相同:瀏覽器會向服務(wù)器發(fā)出另一個請求,。
為什么這個行為很糟,?
這種行為的根本原因是在瀏覽器中完成 URI 解析的方式。這種行為定義在 RFC 3986 - Uniform Resource Identifiers,。當(dāng)遇到一個空字符串時就作為 URI,它被看作是一個相對的 URI,,并根據(jù) 5.2 節(jié)定義的算法解決,。在 5.4 節(jié) 列出了空字符串的例子。Firefox,、Safari 和 Chrome 都按規(guī)范正確解析字符串,,而 Internet Explorer 沒有,還遵循早期的規(guī)范 RFC 2396 - Uniform Resource Identifiers(已由 RFC 3986 代替),。因此,,技術(shù)上,瀏覽器做了它們被期望做的事,,來解析相對 URI,。空字符串顯然是個意外,。 HTML5 在 4.8.2 節(jié)添加一個關(guān)于標(biāo)記的 src 屬性的描述,,指示瀏覽器不要發(fā)出額外的請求: src 屬性必須存在,并且必須包含一個有效的 URL,,它引用一個非交互式的,、可選的、可有動畫的圖像源,,不能是頁面或腳本,。如果元素的基 URI 與文檔地址相同,那么 src 屬性必須不能為空,。 慶幸的是,,之后的瀏覽器不會存在這個問題。而不幸的是,,沒有對 <script src=""> 和 <link href=""> 的規(guī)定,。可能還是有時間調(diào)整以確保瀏覽器執(zhí)行此行為,。 該規(guī)則得到 Yahoo!'s JavaScript guru Nicolas C. Zakas 的支持,。有關(guān)更多信息,參考 "Empty image src can destroy your site",。
修改記錄
|
|
來自: 歆馨 > 《開發(fā)測試》