對于yahoo軍規(guī)的詳細(xì)說明
發(fā)表時(shí)間:2024-05-15 來源:明輝站整理相關(guān)軟件相關(guān)文章人氣:
[摘要]yahoo軍規(guī)一共分7類共35條: 1.盡量減少HTTP請求數(shù) 分類: 內(nèi)容 80%的終端用戶響應(yīng)時(shí)間都花在了前端上,其中大部分時(shí)間都在下載頁面上的各種組件:圖片,樣式表,腳本,F(xiàn)lash等等。減少組件數(shù)必然能夠減少頁面提交的HTTP請求數(shù)。這是讓頁面更快的關(guān)鍵。 減少頁面組件數(shù)的一種方式是簡化頁...
yahoo
軍規(guī)一共分7類共35條:
1.盡量減少HTTP請求數(shù)
分類: 內(nèi)容
80%的終端用戶響應(yīng)時(shí)間都花在了前端上,其中大部分時(shí)間都在下載頁面上的各種組件:圖片,樣式表,腳本,Flash等等。減少組件數(shù)必然能夠減少頁面提交的HTTP請求數(shù)。這是讓頁面更快的關(guān)鍵。
減少頁面組件數(shù)的一種方式是簡化頁面設(shè)計(jì)。但有沒有一種方法可以在構(gòu)建復(fù)雜的頁面同時(shí)加快響應(yīng)時(shí)間呢?嗯,確實(shí)有魚和熊掌兼得的辦法。
合并文件是通過把所有腳本放在一個(gè)文件中的方式來減少請求數(shù)的,當(dāng)然,也可以合并所有的CSS。如果各個(gè)頁面的腳本和樣式不一樣的話,合并文件就是一項(xiàng)比較麻煩的工作了,但把這個(gè)作為站點(diǎn)發(fā)布過程的一部分確實(shí)可以提高響應(yīng)時(shí)間。
CSS Sprites 是減少圖片請求數(shù)量的首選方式。把背景圖片都整合到一張圖片中,然后用CSS的 background-image 和 background-position 屬性來定位要顯示的部分。
圖像映射 可以把多張圖片合并成單張圖片,總大小是一樣的,但減少了請求數(shù)并加速了頁面加載。圖片地圖只有在圖像在頁面中連續(xù)的時(shí)候才有用,比如導(dǎo)航條。給image map設(shè)置坐標(biāo)的過程既無聊又容易出錯(cuò),用image map來做導(dǎo)航也不容易,所以不推薦用這種方式。
行內(nèi)圖片(Base64編碼)用 data: URL模式 來把圖片嵌入頁面。這樣會(huì)增加HTML文件的大小,把行內(nèi)圖片放在(緩存的)樣式表中是個(gè)好辦法,而且成功避免了頁面變“重”。但目前主流瀏覽器并不能很好地支持行內(nèi)圖片。
減少頁面的HTTP請求數(shù)是個(gè)起點(diǎn),這是提升站點(diǎn)首次訪問速度的重要指導(dǎo)原則。就像Tenni Theurer的博客 Browser Cache Usage – Exposed! 里寫到的,40%到60%的訪客在訪問你的站點(diǎn)時(shí),緩存都是空的。所以,加快頁面首次訪問速度對提高用戶體驗(yàn)是極其重要的。
2.使用CDN(Content Delivery Network)
分類: 服務(wù)器
用戶與服務(wù)器的物理距離對響應(yīng)時(shí)間也有影響。把內(nèi)容部署在多個(gè)地理位置分散的服務(wù)器上能讓用戶更快地載入頁面。但具體要怎么做呢?
實(shí)現(xiàn)內(nèi)容在地理位置上分散的第一步是:不要嘗試去重新設(shè)計(jì)你的web應(yīng)用程序來適應(yīng)分布式結(jié)構(gòu)。這取決于應(yīng)用程序,改變結(jié)構(gòu)可能包括一些讓人望而生畏的任務(wù),比如同步會(huì)話狀態(tài)和跨服務(wù)器復(fù)制數(shù)據(jù)庫事務(wù)(翻譯可能不準(zhǔn)確)?s短用戶和內(nèi)容之間距離的提議可能被推遲,或者根本不可能通過,就是因?yàn)檫@個(gè)難題。
記住終端用戶80%到90%的響應(yīng)時(shí)間都花在下載頁面組件上了:圖片,樣式,腳本,Flash等等,這是 業(yè)績黃金法則 。最好先分散靜態(tài)內(nèi)容,而不是一開始就重新設(shè)計(jì)應(yīng)用程序結(jié)構(gòu)。這不僅能夠大大減少響應(yīng)時(shí)間,還更容易表現(xiàn)出CDN的功勞。
內(nèi)容分發(fā)網(wǎng)絡(luò)(CDN)是一組分散在不同地理位置的web服務(wù)器,用來給用戶更高效地發(fā)送內(nèi)容。典型地,選擇用來發(fā)送內(nèi)容的服務(wù)器是基于網(wǎng)絡(luò)距離的衡量標(biāo)準(zhǔn)的。例如:選跳數(shù)(hop)最少的或者響應(yīng)時(shí)間最快的服務(wù)器。
一些互聯(lián)網(wǎng)公司巨頭擁有他們自己的CDN,但用一個(gè)CDN服務(wù)提供者是比較劃算的,比如 Akamai Technologies , EdgeCast ,或者 level3 。對剛剛起步的公司和個(gè)人網(wǎng)站來說,CDN服務(wù)的成本是很高的,但如果你的用戶群卻越來越大,越來越全球化,那么用CDN來換取更快的響應(yīng)時(shí)間還是很有必要的。在Yahoo!,把靜態(tài)內(nèi)容從應(yīng)用程序的web服務(wù)器搬到CDN(包括上面提到的3rd party和Yahoo自己的 CDN )能夠提高終端用戶20%甚至更多的響應(yīng)時(shí)間。換到CDN是一個(gè)相當(dāng)簡單的代碼變更,但這將急劇提升站點(diǎn)的響應(yīng)速度。
3.添上Expires或者Cache-Control HTTP頭
分類: 服務(wù)器
這條規(guī)則有兩個(gè)方面:
對于靜態(tài)組件:通過設(shè)置一個(gè)遙遠(yuǎn)的將來時(shí)間作為 Expires 來實(shí)現(xiàn)永不失效
多余動(dòng)態(tài)組件:用合適的 Cache-Control HTTP頭來讓瀏覽器進(jìn)行條件性的請求
網(wǎng)頁設(shè)計(jì)越來越豐富,這意味著頁面里有更多的腳本,圖片和Flash。站點(diǎn)的新訪客可能還是不得不提交幾個(gè)HTTP請求,但通過使用有效期能讓組件變得可緩存,這避免了在接下來的瀏覽過程中不必要的HTTP請求。有效期HTTP頭通常被用在圖片上,但它們應(yīng)該用在 所有 組件上,包括腳本、樣式和Flash組件。
瀏覽器(和代理)用緩存來減少HTTP請求的數(shù)目和大小,讓頁面能夠更快加載。web服務(wù)器通過有效期HTTP響應(yīng)頭來告訴客戶端,頁面的各個(gè)組件應(yīng)該被緩存多久。用一個(gè)遙遠(yuǎn)的將來時(shí)間做有效期,告訴瀏覽器這個(gè)響應(yīng)在2010年4月15日前不會(huì)改變。
Expires: Thu, 15 Apr 2010 20:00:00 GMT
如果你用的是Apache服務(wù)器,用ExpiresDefault指令來設(shè)置相對于當(dāng)前日期的有效期。下面的例子設(shè)置了從請求時(shí)間起10年的有效期:
ExpiresDefault "access plus 10 years"
記住,如果你用一個(gè)遙遠(yuǎn)的未來時(shí)間做有效期,就不得不在組件發(fā)生變化后及時(shí)修改組件的文件名。在Yahoo!,我們經(jīng)常把這一步作為構(gòu)建過程的一部分:把版本號(hào)內(nèi)嵌在組件的文件名里,例如:yahoo_2.0.6.js
用一個(gè)遙遠(yuǎn)的未來時(shí)間做有效期HTTP頭,只有在用戶已經(jīng)訪問過站點(diǎn)之后才會(huì)影響頁面視圖。如果是新訪客或者瀏覽器的緩存被清空時(shí),對HTTP請求的數(shù)量并沒有影響。因此這種性能提升取決于已緩存各個(gè)組件的用戶訪問站點(diǎn)的頻率。我們 在Yahoo!測量了這個(gè)數(shù)據(jù) ,發(fā)現(xiàn)已緩存各個(gè)組件的頁面訪問量(PV)占75%到85%。通過把一個(gè)遙遠(yuǎn)的未來時(shí)間作為有效期HTTP頭,增加了被瀏覽器緩存的組件數(shù)量,在后續(xù)頁面訪問量中不需要用Internet連接多發(fā)送哪怕一個(gè)字節(jié)。
4.Gzip組件
分類: 服務(wù)器
前端工程師可以想辦法明顯地縮短通過網(wǎng)絡(luò)傳輸HTTP請求和響應(yīng)的時(shí)間。毫無疑問,終端用戶的帶寬速度,網(wǎng)絡(luò)服務(wù)商,對等交換點(diǎn)的距離等等,都是開發(fā)團(tuán)隊(duì)所無法控制的。但還有別的能夠影響響應(yīng)時(shí)間的因素,壓縮可以通過減少HTTP響應(yīng)的大小來縮短響應(yīng)時(shí)間。
從HTTP/1.1開始,web客戶端就有了支持壓縮的Accept-Encoding HTTP請求頭。
Accept-Encoding: gzip, deflate
如果web服務(wù)器看到這個(gè)請求頭,它就會(huì)用客戶端列出的一種方式來壓縮響應(yīng)。web服務(wù)器通過Content-Encoding相應(yīng)頭來通知客戶端。
Content-Encoding: gzip
Gzip是目前最常見的高效壓縮方法,由GNU項(xiàng)目開發(fā)并被 RFC 1952 標(biāo)準(zhǔn)化。唯一一個(gè)你可能會(huì)看到的其它壓縮格式是deflate,但它效率不高而且并不常見。
Gzipping一般能夠把響應(yīng)壓縮到70%左右,目前大約90%的通過瀏覽器的網(wǎng)絡(luò)傳輸都支持gzip。如果是Apache服務(wù)器,配置gzip的模塊取決于版本:Apache 1.3用 mod_gzip 而Apache 2.x是 mod_deflate 模塊。
瀏覽器和代理的某些因素可能會(huì)引起瀏覽器所期望的和它收到的壓縮內(nèi)容不匹配。幸運(yùn)的是,隨著老舊瀏覽器的淘汰,這些極少遇到的情況正在逐漸減少,而且Apache模塊可以通過自動(dòng)添加合適的Vary響應(yīng)頭來幫你搞定。
服務(wù)器會(huì)根據(jù)文件類型來決定要不要用gzip壓縮,但這非常有限。大多數(shù)網(wǎng)站都用gzip壓縮HTML文件,其實(shí)壓縮腳本,樣式表也是不錯(cuò)的選擇,但很多網(wǎng)站卻錯(cuò)失了這個(gè)機(jī)會(huì)。其實(shí),可以壓縮任何文本內(nèi)容,包括XML和JSON,而圖片和PDF不用壓縮,因?yàn)樗鼈円呀?jīng)被壓縮過了,再用gzip壓縮不僅浪費(fèi)CPU還可能會(huì)越壓越大。
盡可能多地用gzip壓縮能夠給頁面減肥,這也是提升用戶體驗(yàn)最簡單的方法。
5.把樣式表放在頂部
分類: css
在Yahoo!研究性能的時(shí)候,我們發(fā)現(xiàn)把樣式表放到文檔的HEAD部分能讓頁面 看起來 加載地更快。這是因?yàn)榘褬邮奖矸旁?/span>head里能讓頁面逐步渲染。
關(guān)注性能的前端工程師想讓頁面逐步渲染。也就是說,我們想讓瀏覽器盡快顯示已有內(nèi)容,這在頁面上有一大堆內(nèi)容或者用戶網(wǎng)速很慢時(shí)顯得尤為重要。給用戶顯示反饋(比如進(jìn)度指標(biāo))的重要性已經(jīng)被廣泛研究過,并且被 記錄 下來了。在我們的例子中,HTML頁面就是進(jìn)度指標(biāo)!當(dāng)瀏覽器逐漸加載頁面頭部,導(dǎo)航條,頂部logo等等內(nèi)容的時(shí)候,這些都被正在等待頁面加載的用戶當(dāng)作反饋,能夠提高整體用戶體驗(yàn)。
在很多瀏覽器(包括IE)中,把樣式表放在HTML文檔底部都會(huì)阻止頁面逐漸渲染。這些瀏覽器阻塞渲染過程,以避免因?yàn)闃邮阶儎?dòng)而重繪頁面元素,用戶這時(shí)就只能盯著空白頁面。
HTML官方文檔 清楚地描述了樣式表應(yīng)該放在頁面的HEAD里面:”Unlike A, [LINK] may only appear in the HEAD section of a document, although it may appear any number of times.”(不像a標(biāo)簽,link標(biāo)簽可能只出現(xiàn)在HEAD部分,雖然它能可以出現(xiàn)任意多次)。空白屏幕或者沒有樣式的falsh內(nèi)容都是不可取的。理想方案就是遵循HTML官方文檔,把樣式表放在HTML文檔的HEAD部分。
6.把腳本放在底部
分類: javascript
腳本會(huì)阻塞并行下載, HTTP/1.1官方文檔 建議瀏覽器每個(gè)主機(jī)名下并行下載的組件數(shù)不要超過兩個(gè),如果圖片來自多個(gè)主機(jī)名,并行下載的數(shù)量就可以超過兩個(gè)。如果腳本正在下載,瀏覽器就不開始任何其它下載任務(wù),即使是在不同主機(jī)名下的。
有時(shí)候,并不容易把腳本移動(dòng)到底部。舉個(gè)例子,如果腳本是用 document.write 插入到頁面內(nèi)容中的,就沒辦法再往下移了。還可能存在作用域問題,在多數(shù)情況下,這些問題都是可以解決的。
一個(gè)常見的建議是用推遲(deferred)腳本,有 DEFER 屬性的腳本意味著不能含有document.write,并且提示瀏覽器告訴他們可以繼續(xù)渲染。不幸的是,Firefox不支持 DEFER 屬性。在IE中,腳本可能被推遲,但不盡如人意。如果腳本可以推遲,我們就可以把它放到頁面底部,頁面就可以更快地載入。
7.避免使用CSS表達(dá)式
分類: css
用CSS表達(dá)式動(dòng)態(tài)設(shè)置CSS屬性,是一種強(qiáng)大又危險(xiǎn)的方式。從IE5開始支持,但 從IE8起就不推薦使用了 。例如,可以用CSS表達(dá)式把背景顏色設(shè)置成按小時(shí)交替的:
上面的代碼中, expression 方法可以接受一個(gè)JavaScript表達(dá)式。CSS屬性會(huì)被設(shè)置成表達(dá)式的計(jì)算結(jié)果。 expression 方法會(huì)被其它瀏覽器忽略,所以只有想辦法實(shí)現(xiàn)跨瀏覽器的與IE一致的用戶體驗(yàn)才有用。
表達(dá)式最大的問題是它們經(jīng)常被重復(fù)計(jì)算,比我們想象的次數(shù)還要多。不僅僅是頁面渲染和調(diào)整大小的時(shí)候,在頁面被滾動(dòng),甚至用戶在頁面上移動(dòng)鼠標(biāo)時(shí)都會(huì)重新計(jì)算表達(dá)式。給CSS表達(dá)式添加一個(gè)計(jì)數(shù)器就可以追蹤它重新計(jì)算的時(shí)間和頻率,而在頁面上動(dòng)動(dòng)鼠標(biāo)就可以引發(fā)10000多次重新計(jì)算。
減少CSS表達(dá)式重新計(jì)算的一種方式就是用一次性表達(dá)式,即在表達(dá)式第一次計(jì)算后就把樣式屬性設(shè)置成一個(gè)明確的值,換掉表達(dá)式。如果必須要在頁面的整個(gè)生命周期中動(dòng)態(tài)設(shè)置樣式屬性,可以用事件處理器來代替CSS表達(dá)式。如果必須使用CSS表達(dá)式,要記得它們可能會(huì)被重復(fù)計(jì)算上千次,從而影響整個(gè)頁面的性能。
8.把JavaScript和CSS放到外面
分類: javascript, css
很多性能原則都是關(guān)于如何管理外部組件的,然而,在這些顧慮出現(xiàn)之前你應(yīng)該問一個(gè)更基礎(chǔ)的問題:應(yīng)該把JavaScript和CSS放到外部文件中還是直接寫在頁面里?
實(shí)際上,用外部文件可以讓頁面更快,因?yàn)?/span>JavaScript和CSS文件會(huì)被緩存在瀏覽器。HTML文檔中的行內(nèi)JavaScript和CSS在每次請求該HTML文檔的時(shí)候都會(huì)重新下載。這樣做減少了所需的HTTP請求數(shù),但增加了HTML文檔的大小。另一方面,如果JavaScript和CSS在外部文件中,并且已經(jīng)被瀏覽器緩存起來了,那么我們就成功地把HTML文檔變小了,而且還沒有增加HTTP請求數(shù)。
關(guān)鍵因素是,外部文件被緩存的頻率和頁面被請求數(shù)量之間的關(guān)系。盡管這個(gè)因素很難量化,但我們還是可以用各種各樣的指標(biāo)來衡量。如果用戶的每個(gè)會(huì)話中都有多次頁面訪問,那么相同的腳本和樣式表就可以被多個(gè)頁面復(fù)用,緩存的外部文件就會(huì)帶來巨大的好處。
很多站點(diǎn)在度量中都處于中等水平,對這些站點(diǎn)來說,一般最好的解決方案就是把JavaScript和CSS部署為外部文件。唯一的例外是主頁上行內(nèi)方式優(yōu)先,例如 Yahoo!的首頁 和 My Yahoo! 。在每個(gè)會(huì)話中訪問量比較少的主頁會(huì)發(fā)現(xiàn)行內(nèi)JavaScript和CSS能讓終端用戶的響應(yīng)時(shí)間更快。
對典型的站點(diǎn)來說,首頁是眾多訪問量的開始,有很多技術(shù)可以對減少HTTP請求起到杠桿作用,就像用外部文件緩存的好處一樣。這樣的一種技術(shù)就是在首頁用行內(nèi)JavaScript和CSS,但在頁面載入完成之后動(dòng)態(tài)加載外部文件,這樣后續(xù)的頁面所需的外部文件就已經(jīng)被放到瀏覽器的緩存里了。
9.減少DNS查找
分類: 內(nèi)容
域名系統(tǒng)建立了主機(jī)名和IP地址間的映射,就像電話簿上人名和號(hào)碼的映射一樣。當(dāng)你在瀏覽器輸入www.yahoo.com的時(shí)候,瀏覽器就會(huì)聯(lián)系DNS解析器返回服務(wù)器的IP地址。DNS是有成本的,它需要20到120毫秒去查找給定主機(jī)名的IP地址。在DNS查找完成之前,瀏覽器無法從主機(jī)名下載任何東西。
DNS查找被緩存起來更高效,由用戶的ISP(網(wǎng)絡(luò)服務(wù)提供商)或者本地網(wǎng)絡(luò)存在一個(gè)特殊的緩存服務(wù)器上,但還可以緩存在個(gè)人用戶的計(jì)算機(jī)上。DNS信息被保存在操作系統(tǒng)的DNS cache(微軟Windows上的”DNS客戶端服務(wù)”)里。大多數(shù)瀏覽器有獨(dú)立于操作系統(tǒng)的自己的cache。只要瀏覽器在自己的cache里還保留著這條記錄,它就不會(huì)向操作系統(tǒng)查詢DNS。
IE默認(rèn)緩存DNS查找30分鐘,寫在 DnsCacheTimeout 注冊表設(shè)置中。Firefox緩存1分鐘,可以用 network.dnsCacheExpiration 配置項(xiàng)設(shè)置。(Fasterfox把緩存時(shí)間改成了1小時(shí) P.S. Fasterfox是FF的一個(gè)提速插件)
如果客戶端的DNS cache是空的(包括瀏覽器的和操作系統(tǒng)的),DNS查找數(shù)等于頁面上不同的主機(jī)名數(shù),包括頁面URL,圖片,腳本文件,樣式表,Flash對象等等組件中的主機(jī)名,減少不同的主機(jī)名就可以減少DNS查找。
減少不同主機(jī)名的數(shù)量同時(shí)也減少了頁面能夠并行下載的組件數(shù)量,避免DNS查找削減了響應(yīng)時(shí)間,而減少并行下載數(shù)量卻增加了響應(yīng)時(shí)間。我的原則是把組件分散在2到4個(gè)主機(jī)名下,這是同時(shí)減少DNS查找和允許高并發(fā)下載的折中方案。
10.壓縮JavaScript和CSS
分類: javascript, css
壓縮具體來說就是從代碼中去除不必要的字符以減少大小,從而提升加載速度。代碼最小化就是去掉所有注釋和不必要的空白字符(空格,換行和tab)。在JavaScript中這樣做能夠提高響應(yīng)性能,因?yàn)橐螺d的文件變小了。兩個(gè)最常用的JavaScript代碼壓縮工具是 JSMin 和 YUI Compressor ,YUI compressor還可以壓縮CSS。
混淆是一種可選的源碼優(yōu)化措施,要比壓縮更復(fù)雜,所以混淆過程也更容易產(chǎn)生bug。在對美國前十的網(wǎng)站調(diào)查中,壓縮可以縮小21%,而混淆能縮小25%。雖然混淆的縮小程度更高,但比壓縮風(fēng)險(xiǎn)更大。
除了壓縮外部腳本和樣式,行內(nèi)的 <script> 和 <style> 塊也可以壓縮。即使啟用了gzip模塊,先進(jìn)行壓縮也能夠縮小5%或者更多的大小。JavaScript和CSS的用處越來越多,所以壓縮代碼會(huì)有不錯(cuò)的效果。
11.避免重定向
分類: 內(nèi)容
重定向用301和302狀態(tài)碼,下面是一個(gè)有301狀態(tài)碼的HTTP頭:
HTTP/1.1 301 Moved Permanently
Location:
Content-Type: text/html
瀏覽器會(huì)自動(dòng)跳轉(zhuǎn)到 Location 域指明的URL。重定向需要的所有信息都在HTTP頭部,而響應(yīng)體一般是空的。其實(shí)額外的HTTP頭,比如 Expires 和 Cache-Control 也表示重定向。除此之外還有別的跳轉(zhuǎn)方式:refresh元標(biāo)簽和JavaScript,但如果你必須得做重定向,最好用標(biāo)準(zhǔn)的3xxHTTP狀態(tài)碼,主要是為了讓返回按鈕能正常使用。
牢記重定向會(huì)拖慢用戶體驗(yàn),在用戶和HTML文檔之間插入重定向會(huì)延遲頁面上的所有東西,頁面無法渲染,組件也無法開始下載,直到HTML文檔被送達(dá)瀏覽器。
有一種常見的極其浪費(fèi)資源的重定向,而且web開發(fā)人員一般都意識(shí)不到這一點(diǎn),就是URL尾部缺少一個(gè)斜線的時(shí)候。例如,跳轉(zhuǎn)到 會(huì)返回一個(gè)重定向到 的301響應(yīng)(注意添在尾部的斜線)。在Apache中可以用 Alias , mod_rewrite 或者 DirectorySlash 指令來取消不必要的重定向。
重定向最常見的用途是把舊站點(diǎn)連接到新的站點(diǎn),還可以連接同一站點(diǎn)的不同部分,針對用戶的不同情況(瀏覽器類型,用戶帳號(hào)類型等等)做一些處理。用重定向來連接兩個(gè)網(wǎng)站是最簡單的,只需要少量的額外代碼。雖然在這些時(shí)候使用重定向減少了開發(fā)人員的開發(fā)復(fù)雜度,但降低了用戶體驗(yàn)。一種替代方案是用 Alias 和 mod_rewrite ,前提是兩個(gè)代碼路徑都在相同的服務(wù)器上。如果是因?yàn)橛蛎兓褂昧酥囟ㄏ颍涂梢詣?chuàng)建一條CNAME(創(chuàng)建一個(gè)指向另一個(gè)域名的DNS記錄作為別名)結(jié)合 Alias 或者 mod_rewrite 指令。
12.去除重復(fù)腳本
分類: javascript
頁面含有重復(fù)的腳本文件會(huì)影響性能,這可能和你想象的不一樣。在對美國前10大web站點(diǎn)的評(píng)審中,發(fā)現(xiàn)只有2個(gè)站點(diǎn)含有重復(fù)腳本。兩個(gè)主要原因增加了在單一頁面中出現(xiàn)重復(fù)腳本的幾率:團(tuán)隊(duì)大小和腳本數(shù)量。在這種情況下,重復(fù)腳本會(huì)創(chuàng)建不必要的HTTP請求,執(zhí)行無用的JavaScript代碼,而影響頁面性能。
IE會(huì)產(chǎn)生不必要的HTTP請求,而Firefox不會(huì)。在IE中,如果一個(gè)不可緩存的外部腳本被頁面引入了兩次,它會(huì)在頁面加載時(shí)產(chǎn)生兩個(gè)HTTP請求。即使腳本是可緩存的,在用戶重新加載頁面時(shí)也會(huì)產(chǎn)生額外的HTTP請求。
除了產(chǎn)生沒有意義的HTTP請求之外,多次對腳本求值也會(huì)浪費(fèi)時(shí)間。因?yàn)闊o論腳本是否可緩存,在Firefox和IE中都會(huì)執(zhí)行冗余的JavaScript代碼。
避免不小心把相同腳本引入兩次的一種方法就是在模版系統(tǒng)中實(shí)現(xiàn)腳本管理模塊。典型的腳本引入方法就是在HTML頁面中用SCRIPT標(biāo)簽:
<script type="text/javascript" src="menu_1.0.17.js?1.1.11"></script>
PHP中一個(gè)可選方案是創(chuàng)建一個(gè)叫 insertScript 的函數(shù):
<?php insertScript("menu.js?1.1.11") ?>
除了防止相同腳本被多次引入,這個(gè)函數(shù)還可以解決腳本相關(guān)的其它問題,比如依賴性檢查和給腳本文件名添加版本號(hào)來支持“永久”有效期HTTP頭。
13.配置ETags
分類: 服務(wù)器
實(shí)體標(biāo)簽(ETags),是服務(wù)器和瀏覽器用來決定瀏覽器緩存中組件與源服務(wù)器中的組件是否匹配的一種機(jī)制(“實(shí)體”也就是組件:圖片,腳本,樣式表等等)。添加ETags可以提供一種實(shí)體驗(yàn)證機(jī)制,比最后修改日期更加靈活。一個(gè)ETag是一個(gè)字符串,作為一個(gè)組件某一具體版本的唯一標(biāo)識(shí)符。唯一的格式約束是字符串必須用引號(hào)括起來,源服務(wù)器用相應(yīng)頭中的 ETag 來指定組件的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)證一個(gè)組件,它用 If-None-Match 請求頭來把ETag傳回源服務(wù)器。如果ETags匹配成功,會(huì)返回一個(gè)304狀態(tài)碼,這樣就減少了12195個(gè)字節(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ù)器構(gòu)造的,所以如果瀏覽器從一個(gè)服務(wù)器獲取最初的組件,然后想驗(yàn)證另一個(gè)服務(wù)器上的相同組件,ETags是無法匹配成功的,而用一群服務(wù)器處理請求在web站點(diǎn)中又非常普遍。默認(rèn)情況下,Apache和IIS會(huì)在ETag中嵌入數(shù)據(jù),以大大降低在多服務(wù)器站點(diǎn)上有效性測試成功的幾率。
Apache 1.3和2.x中ETag的格式是 inode-size-timestamp 。就算給定的文件可能在多個(gè)服務(wù)器的相同目錄下,而且文件大小、訪問權(quán)限、時(shí)間戳等等全部相同,它的i節(jié)點(diǎn)(P.S. inode,UNIX中的索引文件)在不同服務(wù)器中也不一樣。
IIS5.0和6.0也都存在類似的問題。IIS中ETags的格式是 Filetimestamp:ChangeNumber , ChangeNumber 是一個(gè)用來追蹤IIS配置變更的計(jì)數(shù)器。 一個(gè)站點(diǎn)在不同的IIS服務(wù)器上的 ChangeNumber 是不可能相同的。
最終結(jié)果是Apache和IIS為完全相同的組件生成的ETags無法跨瀏覽器匹配,如果ETags不匹配,用戶就無法收到為又小又快的304響應(yīng)設(shè)計(jì)的ETags。反而,他們將收到一個(gè)攜帶著組件所有數(shù)據(jù)的200正常響應(yīng)。如果站點(diǎn)部署在單一服務(wù)器上,就根本不存在這個(gè)問題。但如果站點(diǎn)部署在多個(gè)服務(wù)器上,而且打算用Apache或者IIS的默認(rèn)ETags配置,用戶將看到緩慢的頁面,服務(wù)器負(fù)載更高,還會(huì)消耗更大的帶寬,并且代理也無法有效緩存頁面內(nèi)容。即使組件有“永久” Expires HTTP頭,用戶點(diǎn)擊重新加載或者刷新的時(shí)候,仍然會(huì)發(fā)出條件GET請求。
如果不想用ETags提供的靈活的驗(yàn)證模型,最好把所有的Etag全都去掉,可以用基于組件的時(shí)間戳的 Last-Modified HTTP頭驗(yàn)證,而且去掉ETag可以減少HTTP響應(yīng)頭以及后續(xù)請求的大小。 Microsoft Support article 里寫了怎樣移除ETags。在Apache中,可以簡單地通過在Apache配置文件中添上如下代碼來實(shí)現(xiàn):
FileETag none
14.讓Ajax可緩存
分類: 內(nèi)容
Ajax的一個(gè)好處是可以給用戶提供即時(shí)反饋,因?yàn)樗軌驈暮笈_(tái)服務(wù)器異步請求信息。然而,用了Ajax就無法保證用戶在等待異步JavaScript和XML響應(yīng)返回期間不會(huì)非常無聊。在很多應(yīng)用程序中,用戶能夠一直等待取決于如何使用Ajax。例如,在基于web的電子郵件客戶端中,用戶為了尋找符合他們搜索標(biāo)準(zhǔn)的郵件消息,將會(huì)保持對Ajax請求返回結(jié)果的關(guān)注。重要的是,要記得“異步”并不意味著“即時(shí)”。
要提高性能,優(yōu)化這些Ajax響應(yīng)至關(guān)重要。最重要的提高Ajax性能的方法就是讓響應(yīng)變得可緩存,就像在 添上Expires或者Cache-Control HTTP頭 中討論的一樣。下面適用于Ajax的其它規(guī)則:
Gzip組件
減少DNS查找
壓縮JavaScript
避免重定向
配置ETags
我們一起看看例子,一個(gè)Web 2.0的電子郵件客戶端用了Ajax來下載用戶的通訊錄,以便實(shí)現(xiàn)自動(dòng)完成功能。如果用戶從上一次使用之后再?zèng)]有修改過她的通訊錄,而且Ajax響應(yīng)是可緩存的,有尚未過期的Expires或者Cache-Control HTTP頭,那么之前的通訊錄就可以從緩存中讀出。必須通知瀏覽器,應(yīng)該繼續(xù)使用之前緩存的通訊錄響應(yīng),還是去請求一個(gè)新的?梢酝ㄟ^給通訊錄的Ajax URL里添加一個(gè)表明用戶通訊錄最后修改時(shí)間的時(shí)間戳來實(shí)現(xiàn),例如 &t=1190241612 。如果通訊錄從上一次下載之后再?zèng)]有被修改過,時(shí)間戳不變,通訊錄就將從瀏覽器緩存中直接讀出,從而避免一次額外的HTTP往返消耗。如果用戶已經(jīng)修改了通訊錄,時(shí)間戳也可以確保新的URL不會(huì)匹配緩存的響應(yīng),瀏覽器將請求新的通訊錄條目。
即使Ajax響應(yīng)是動(dòng)態(tài)創(chuàng)建的,而且可能只適用于單用戶,它們也可以被緩存,而這樣會(huì)讓你的Web 2.0應(yīng)用更快。
15.盡早清空緩沖區(qū)
分類: 服務(wù)器
當(dāng)用戶請求一個(gè)頁面時(shí),服務(wù)器需要用大約200到500毫秒來組裝HTML頁面,在這期間,瀏覽器閑等著數(shù)據(jù)到達(dá)。PHP中有一個(gè) flush() 函數(shù),允許給瀏覽器發(fā)送一部分已經(jīng)準(zhǔn)備完畢的HTML響應(yīng),以便瀏覽器可以在后臺(tái)準(zhǔn)備剩余部分的同時(shí)開始獲取組件,好處主要體現(xiàn)在很忙的后臺(tái)或者很“輕”的前端頁面上(P.S. 也就是說,響應(yīng)時(shí)耗主要在后臺(tái)方面時(shí)最能體現(xiàn)優(yōu)勢)。
比較理想的清空緩沖區(qū)的位置是HEAD后面,因?yàn)?/span>HTML的HEAD部分通常更容易生成,并且允許引入任何CSS和JavaScript文件,這樣就可以讓瀏覽器在后臺(tái)還在處理的時(shí)候就開始并行獲取組件。
例如:
... <!-- css, js -->
</head>
<?php flush(); ?>
<body>
... <!-- content -->
Yahoo!搜索 開創(chuàng)了這項(xiàng)技術(shù),而且真實(shí)用戶測試研究也證明了使用這種技術(shù)的諸多好處。
16.對Ajax用GET請求
分類: 服務(wù)器
Yahoo!郵箱 團(tuán)隊(duì)發(fā)現(xiàn)使用 XMLHttpRequest 時(shí),瀏覽器的POST請求是通過一個(gè)兩步的過程來實(shí)現(xiàn)的:先發(fā)送HTTP頭,在發(fā)送數(shù)據(jù)。所以最好用GET請求,它只需要發(fā)送一個(gè)TCP報(bào)文(除非cookie特別多)。IE的URL長度最大值是2K,所以如果要發(fā)送的數(shù)據(jù)超過2K就無法使用GET了。
POST請求的一個(gè)有趣的副作用是實(shí)際上沒有發(fā)送任何數(shù)據(jù),就像GET請求一樣。正如 HTTP說明文檔 中描述的,GET請求是用來檢索信息的。所以它的語義只是用GET請求來請求數(shù)據(jù),而不是用來發(fā)送需要存儲(chǔ)到服務(wù)器的數(shù)據(jù)。
17.延遲加載組件
分類: 內(nèi)容
可以湊近看看頁面并問自己:什么才是一開始渲染頁面所必須的?其余內(nèi)容都可以等會(huì)兒。
JavaScript是分隔onload事件之前和之后的一個(gè)理想選擇。例如,如果有JavaScript代碼和支持拖放以及動(dòng)畫的庫,這些都可以先等會(huì)兒,因?yàn)橥戏旁厥窃陧撁孀畛蹁秩局蟮。其它可以延遲加載的部分包括隱藏內(nèi)容(在某個(gè)交互動(dòng)作之后才出現(xiàn)的內(nèi)容)和折疊的圖片。
工具可幫你減輕工作量: YUI Image Loader 可以延遲加載折疊的圖片,還有 YUI Get utility 是一種引入JS和CSS的簡單方法。 Yahoo!主頁 就是一個(gè)例子,可以打開Firebug的網(wǎng)絡(luò)面板仔細(xì)看看。
最好讓性能目標(biāo)符合其它web開發(fā)最佳實(shí)踐,比如“漸進(jìn)增強(qiáng)”。如果客戶端支持JavaScript,可以提高用戶體驗(yàn),但必須確保頁面在不支持JavaScript時(shí)也能正常工作。所以,在確定頁面運(yùn)行正常之后,可以用一些延遲加載腳本增強(qiáng)它,以支持一些拖放和動(dòng)畫之類的華麗效果。
18.預(yù)加載組件
分類: 內(nèi)容
預(yù)加載可能看起來和延遲加載是相反的,但它其實(shí)有不同的目標(biāo)。通過預(yù)加載組件可以充分利用瀏覽器空閑的時(shí)間來請求將來會(huì)用到的組件(圖片,樣式和腳本)。用戶訪問下一頁的時(shí)候,大部分組件都已經(jīng)在緩存里了,所以在用戶看來頁面會(huì)加載得更快。
實(shí)際應(yīng)用中有以下幾種預(yù)加載的類型:
無條件 預(yù)加載——盡快開始加載,獲取一些額外的組件。google.com就是一個(gè)sprite圖片預(yù)加載的好例子,這個(gè)sprite圖片并不是google.com主頁需要的,而是搜索結(jié)果頁面上的內(nèi)容。
條件性 預(yù)加載——根據(jù)用戶操作猜測用戶將要跳轉(zhuǎn)到哪里并據(jù)此預(yù)加載。在 search.yahoo.com 的輸入框里鍵入內(nèi)容后,可以看到那些額外組件是怎樣請求加載的。
提前 預(yù)加載——在推出新設(shè)計(jì)之前預(yù)加載。經(jīng)常在重新設(shè)計(jì)之后會(huì)聽到:“這個(gè)新網(wǎng)站不錯(cuò),但比以前更慢了”,一部分原因是用戶訪問先前的頁面都是有舊緩存的,但新的卻是一種空緩存狀態(tài)下的體驗(yàn)?梢酝ㄟ^在將要推出新設(shè)計(jì)之前預(yù)加載一些組件來減輕這種負(fù)面影響,老站可以利用瀏覽器空閑的時(shí)間來請求那些新站需要的圖片和腳本。
19.減少DOM元素的數(shù)量
分類: 內(nèi)容
一個(gè)復(fù)雜的頁面意味著要下載更多的字節(jié),而且用JavaScript訪問DOM也會(huì)更慢。舉個(gè)例子,想要添加一個(gè)事件處理器的時(shí)候,循環(huán)遍歷頁面上的500個(gè)DOM元素和5000個(gè)DOM元素是有區(qū)別的。
大量的DOM元素是一種征兆——頁面上有些內(nèi)容無關(guān)的標(biāo)記需要清理。正在用嵌套表格來布局嗎?還是為了修復(fù)布局問題而添了一堆的 <div> s?或許應(yīng)該用更好的語義化標(biāo)記。
YUI CSS utilities 對布局有很大幫助:grids.css針對整體布局,fonts.css和reset.css可以用來去除瀏覽器的默認(rèn)格式。這是個(gè)開始清理和思考標(biāo)記的好機(jī)會(huì),例如只在語義上有意義的時(shí)候使用 <div> ,而不是因?yàn)樗軌蜾秩疽粋(gè)新行。
DOM元素的數(shù)量很容易測試,只需要在Firebug的控制臺(tái)里輸入:
document.getElementsByTagName('*').length
那么多少DOM元素才算是太多呢?可以參考其它類似的標(biāo)記良好的頁面,例如 Yahoo!主頁 是一個(gè)相當(dāng)繁忙的頁面,但只有不到700個(gè)元素(HTML標(biāo)簽)。
20.跨域分離組件
分類: 內(nèi)容
分離組件可以最大化并行下載,但要確保只用不超過2-4個(gè)域,因?yàn)榇嬖?/span>DNS查找的代價(jià)。例如,可以把HTML和動(dòng)態(tài)內(nèi)容部署在 www.example.org ,而把靜態(tài)組件分離到 static1.example.org 和 static2.example.org 。
更多信息請查看Tenni Theurer和Patty Chi的文章: Maximizing Parallel Downloads in the Carpool Lane
21.盡量少用iframe
分類: 內(nèi)容
用iframe可以把一個(gè)HTML文檔插入到父文檔里,重要的是明白iframe是如何工作的并高效地使用它。
<iframe> 的優(yōu)點(diǎn):
引入緩慢的第三方內(nèi)容,比如標(biāo)志和廣告
安全沙箱
并行下載腳本
<iframe> 的缺點(diǎn):
代價(jià)高昂,即使是空白的iframe
阻塞頁面加載
非語義
22.杜絕404
分類: 內(nèi)容
HTTP請求代價(jià)高昂,完全沒有必要用一個(gè)HTTP請求去獲取一個(gè)無用的響應(yīng)(比如404 Not Found),只會(huì)拖慢用戶體驗(yàn)而沒有任何好處。
有些站點(diǎn)用的是有幫助的404——“你的意思是xxx?”,這樣做有利于用戶體驗(yàn),,但也浪費(fèi)了服務(wù)器資源(比如數(shù)據(jù)庫等等)。最糟糕的是鏈接到的外部JavaScript有錯(cuò)誤而且結(jié)果是404。首先,這種下載將阻塞并行下載。其次,瀏覽器會(huì)試圖解析404響應(yīng)體,因?yàn)樗?/span>JavaScript代碼,需要找出其中可用的部分。
23.給Cookie減肥
分類: cookie
使用cookie的原因有很多,比如授權(quán)和個(gè)性化。HTTP頭中cookie信息在web服務(wù)器和瀏覽器之間交換。重要的是保證cookie盡可能的小,以最小化對用戶響應(yīng)時(shí)間的影響。
更多信息請查看Tenni Theurer和Patty Chi的文章: When the Cookie Crumbles 。相關(guān)經(jīng)驗(yàn)原則可以總結(jié)如下:
清除不必要的cookie
保證cookie盡可能小,以最小化對用戶響應(yīng)時(shí)間的影響
注意給cookie設(shè)置合適的域級(jí)別,以免影響其它子域
設(shè)置合適的有效期,更早的有效期或者none可以更快的刪除cookie,提高用戶響應(yīng)時(shí)間
24.把組件放在不含cookie的域下
分類: cookie
當(dāng)瀏覽器發(fā)送對靜態(tài)圖像的請求時(shí),cookie也會(huì)一起發(fā)送,而服務(wù)器根本不需要這些cookie。所以它們只會(huì)造成沒有意義的網(wǎng)絡(luò)通信量,應(yīng)該確保對靜態(tài)組件的請求不含cookie。可以創(chuàng)建一個(gè)子域,把所有的靜態(tài)組件都部署在那兒。
如果域名是 www.example.org ,可以把靜態(tài)組件部署到 static.example.org 。然而,如果已經(jīng)在頂級(jí)域 example.org 或者 www.example.org 設(shè)置了cookie,那么所有對 static.example.org 的請求都會(huì)含有這些cookie。這時(shí)候可以再買一個(gè)新域名,把所有的靜態(tài)組件部署上去,并保持這個(gè)新域名不含cookie。Yahoo!用的是 yimg.com ,YouTube是 ytimg.com ,Amazon是 images-amazon.com 等等。
把靜態(tài)組件部署在不含cookie的域下還有一個(gè)好處是有些代理可能會(huì)拒絕緩存帶cookie的組件。有一點(diǎn)需要注意:如果不知道應(yīng)該用example.org還是www.example.org作為主頁,可以考慮一下cookie的影響。省略www的話,就只能把cookie寫到 *.example.org ,所以因?yàn)樾阅茉蜃詈糜?/span>www子域,并且把cookie寫到這個(gè)子域下。
25.盡量減少DOM訪問
分類: javascript
用JavaScript訪問DOM元素是很慢的,所以,為了讓頁面反應(yīng)更迅速,應(yīng)該:
緩存已訪問過的元素的索引
先“離線”更新節(jié)點(diǎn),再把它們添到DOM樹上
避免用JavaScript修復(fù)布局問題
更多信息請查看YUI影院里Julien Lecomte的文章: High Performance Ajax Applications
26.用智能的事件處理器
分類: javascript
有時(shí)候感覺頁面反映不夠靈敏,是因?yàn)橛刑囝l繁執(zhí)行的事件處理器被添加到了DOM樹的不同元素上,這就是推薦使用 事件委托 的原因。如果一個(gè) div 里面有10個(gè)按鈕,應(yīng)該只給div容器添加一個(gè)事件處理器,而不是給每個(gè)按鈕都添加一個(gè)。事件能夠冒泡,所以可以捕獲事件并得知哪個(gè)按鈕是事件源。
不需要為了處理DOM樹而等待onload事件,通常只要目標(biāo)元素在DOM樹中可訪問即可,而不必等待所有的圖片下載完成。可以考慮用 DOMContentLoaded 來代替onload事件,但為了讓它在所有瀏覽器中都可用,可以用 YUI Event 工具,它有一個(gè) onAvailable 方法。
更多信息請查看YUI影院里Julien Lecomte的文章: High Performance Ajax Applications
27.選擇<link>舍棄@import
分類: css
前面提到了一個(gè)最佳實(shí)踐:為了實(shí)現(xiàn)逐步渲染,CSS應(yīng)該放在頂部。
在IE中用 @import 與在底部用 <link> 效果一樣,所以最好不要用它。
28.避免使用濾鏡
分類: css
IE專有的 AlphaImageLoader 濾鏡可以用來修復(fù)IE7之前的版本中半透明PNG圖片的問題。在圖片加載過程中,這個(gè)濾鏡會(huì)阻塞渲染,卡住瀏覽器,還會(huì)增加內(nèi)存消耗而且是被應(yīng)用到每個(gè)元素的,而不是每個(gè)圖片,所以會(huì)存在一大堆問題。
最好的方法是干脆不要用 AlphaImageLoader ,而優(yōu)雅地降級(jí)到用在IE中支持性很好的PNG8圖片來代替。如果非要用 AlphaImageLoader ,應(yīng)該用下劃線hack: _filter 來避免影響IE7及更高版本的用戶。
29.優(yōu)化圖片
分類: 圖片
設(shè)計(jì)師做好圖片后,在把這些圖片通過FTP上傳到web服務(wù)器之前,我們還可以做一些事情。
檢查GIF圖片,看看圖片中是不是用了調(diào)色板大小對應(yīng)的顏色數(shù),用 imagemagick 可以簡單地檢查:
identify -verbose image.gif
如果4色圖片用了調(diào)色板中256色的“槽”,那就還有改進(jìn)的余地
試著把GIF圖片轉(zhuǎn)換成PNG,看能不能縮減大小,往往可以。開發(fā)者通常不愿意用PNG圖片,因?yàn)闉g覽器支持有限,但這都是過去的事情了。真正的問題是PNG圖片完全支持alpha透明度,而GIF圖片卻不支持透明度漸變,所以GIF能做的任何事情,PNG都可以(除了動(dòng)畫)。下面這個(gè)簡單的命令就能讓PNG圖片可以安全使用:
convert image.gif image.png
“我們強(qiáng)調(diào)的是:給PNG一個(gè)機(jī)會(huì)。”
用 pngcrush (或者其它的PNG優(yōu)化工具)處理所有的PNG圖片,例如:
pngcrush image.png -rem alla -reduce -brute result.png
用jpegtran處理所有JPEG圖片,這個(gè)工具支持對JPEG圖片的無損操作比如旋轉(zhuǎn),還可以用來去除注釋和其它無用信息(比如EXIF信息 P.S. 數(shù)碼照片信息,焦距光圈之類的):
jpegtran -copy none -optimize -perfect src.jpg dest.jpg
30.優(yōu)化CSS Sprite
分類: 圖片
在Sprite圖片中橫向排列一般都比縱向排列的最終文件小
組合Sprite圖片中的相似顏色可以保持低色數(shù),最理想的是256色以下PNG8格式
“對移動(dòng)端友好”,不要在Sprite圖片中留下太大的空隙。雖然不會(huì)在很大程度上影響圖片文件的大小,但這樣做可以節(jié)省用戶代理把圖片解壓成像素映射時(shí)消耗的內(nèi)存。100×100的圖片是1萬個(gè)像素,而1000×1000的圖片就是100萬個(gè)像素了。
31.不要用HTML縮放圖片
分類: 圖片
不要因?yàn)樵?/span>HTML中可以設(shè)置寬高而使用本不需要的大圖。如果需要
<img width="100" height="100" src="mycat.jpg" alt="My Cat" />
那么圖片本身(mycat.jpg)應(yīng)該是100x100px的,而不是去縮小500x500px的圖片。
32.用小的可緩存的favicon.ico(P.S. 收藏夾圖標(biāo))
分類: 圖片
favicon.ico是放在服務(wù)器根目錄的圖片,它會(huì)帶來一堆麻煩,因?yàn)榧幢隳悴还芩,瀏覽器也會(huì)自動(dòng)請求它,所以最好不要給一個(gè) 404 Not Found 響應(yīng)。而且只要在同一個(gè)服務(wù)器上,每次請求它時(shí)都會(huì)發(fā)送cookie,此外這個(gè)圖片還會(huì)干擾下載順序,例如在IE中,當(dāng)你在onload中請求額外組件時(shí),將會(huì)先下載favicon。
所以為了緩解favicon.ico的缺點(diǎn),應(yīng)該確保:
足夠小,最好在1K以下
設(shè)置合適的有效期HTTP頭(以后如果想換的話就不能重命名了),把有效期設(shè)置為幾個(gè)月后一般比較安全,可以通過檢查當(dāng)前favicon.ico的最后修改日期來確保變更能讓瀏覽器知道。
Imagemagick 可以用來處理小收藏夾圖標(biāo)
33.保證所有組件都小于25K
分類: 移動(dòng)
這個(gè)限制是因?yàn)?/span>iPhone不能緩存大于25K的組件,注意這里指的是 未壓縮的 大小。這就是為什么縮減內(nèi)容本身也很重要,因?yàn)閱渭兊?/span>gzip可能不夠。
更多信息請查看Wayne Shea和Tenni Theurer的文章: Performance Research, Part 5: iPhone Cacheability – Making it Stick
34.把組件打包到一個(gè)復(fù)合文檔里
分類: 移動(dòng)
把各個(gè)組件打包成一個(gè)像有附件的電子郵件一樣的復(fù)合文檔里,可以用一個(gè)HTTP請求獲取多個(gè)組件(記住一點(diǎn):HTTP請求是代價(jià)高昂的)。用這種方式的時(shí)候,要先檢查用戶代理是否支持(iPhone就不支持)。
35.避免圖片src屬性為空
分類: 服務(wù)器
Image with empty string src 屬性是空字符串的圖片很常見,主要以兩種形式出現(xiàn):
straight HTML
<img src=””>
JavaScript
var img = new Image();img.src =
“”
;
這兩種形式都會(huì)引起相同的問題:瀏覽器會(huì)向服務(wù)器發(fā)送另一個(gè)請求。
IE 向頁面所在目錄發(fā)起一個(gè)請求
Safari和Chrome 想當(dāng)前頁面本身發(fā)送一個(gè)請求
Firefox 3及更早版本與Safari和Chrome處理方式一樣,但3.5解決了這個(gè)問題 [bug 444931] ,不會(huì)再發(fā)送請求了
Opera 遇到有空src屬性的圖片不做任何處理
為什么圖片src屬性為空不好?
意外發(fā)送大量的通信量對服務(wù)器來說是很傷的,尤其是在每天有幾百萬訪問量頁面的時(shí)候。
浪費(fèi)服務(wù)器資源去生成一個(gè)根本不可能被看到的頁面
可能會(huì)污染用戶數(shù)據(jù),如果追蹤請求狀態(tài),要么通過cookie要么是其它方式,可能會(huì)破壞用戶數(shù)據(jù)。即使圖片請求并沒有返回圖片,整個(gè)HTTP頭部也會(huì)被瀏覽器接受并讀取,包括所有的cookie。雖然其余部分會(huì)被丟棄,但這可能已經(jīng)造成破壞了。
問題的根本原因是各個(gè)瀏覽器在處理URI時(shí)的分歧,這在RFC 3986 – Uniform Resource Identifiers文檔中有明確定義。如果URI是一個(gè)空串,會(huì)被看作一個(gè)相對URI,并按照5.2節(jié)定義的算法處理。實(shí)際情況是,Firefox、Safari和Chrome都是根據(jù)文檔中5.4節(jié)列出的規(guī)范來處理空串,而IE并沒有正確處理。據(jù)說在舊版本規(guī)范文檔RFC 2396 – Uniform Resource Identifiers(被RFC 3986廢棄了)中,所以從嚴(yán)格意義上來說瀏覽器處理相對URI的做法都是對的。問題是,在這種情形下,空串顯然是無心的(P.S. 而不是什么相對URI)。
HTML5的4.8.2節(jié)有關(guān)于<img>標(biāo)簽src屬性的描述,規(guī)定瀏覽器不再發(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.(P.S. “src屬性必須存在,而且必須有一個(gè)合法的URL引用非交互式的動(dòng)畫或者圖像資源,不能分頁也不能含有腳本。如果元素的基URI和文檔地址相同,那么src屬性的值就不能是空串!保
以上就是關(guān)于yahoo軍規(guī)的詳細(xì)介紹的詳細(xì)內(nèi)容,更多請關(guān)注php中文網(wǎng)其它相關(guān)文章!
網(wǎng)站建設(shè)是一個(gè)廣義的術(shù)語,涵蓋了許多不同的技能和學(xué)科中所使用的生產(chǎn)和維護(hù)的網(wǎng)站。