網(wǎng)站前端性能優(yōu)化方案

  • 發(fā)布時(shí)間:2019-01-21 11:23:35
  • 作者:資深網(wǎng)
  • 瀏覽:3230
  • 網(wǎng)站前端性能優(yōu)化方案,網(wǎng)站優(yōu)化離不開前后端的互相協(xié)作,但是對(duì)于前端工程師來說,在保證后端技術(shù)方案不變時(shí),能不能只利用前端技術(shù)來優(yōu)化網(wǎng)站呢?答案是肯定。雅虎的郵件團(tuán)隊(duì)總結(jié)了常用的35條網(wǎng)站優(yōu)化最佳實(shí)踐,其中就有很多實(shí)踐,只要我們前端人員在日常開發(fā)過程中遵循這些實(shí)踐,就可以在一定程度優(yōu)化網(wǎng)站加載速度。

    1.最小化HTTP請(qǐng)求

    2.使用內(nèi)容分發(fā)網(wǎng)絡(luò)(CDN)

    3.增加Expires或者Cache-Control頭

    4.Gzip壓縮內(nèi)容

    5.把CSS文件放到頂部

    6.把Js文件放到底部

    7.避免CSS表達(dá)式

    8.保持Js和CSS外部引用

    9.減少DNS查詢路徑

    10.壓縮js和css

    11.避免重定向

    12.刪除重復(fù)Scripts

    13.配置Etags

    14.使Ajax請(qǐng)求可緩存

    15.盡早刷新緩存

    16.使用GET方式的Ajax請(qǐng)求

    17.延遲加載內(nèi)容

    18.預(yù)加載組

    19.減少DOM元素?cái)?shù)量

    20.跨域分離內(nèi)容

    21.減少iframe

    22.不要404

    23.減少Cookie大小

    24.內(nèi)容使用沒有cookie的域

    25.減少DOM訪問次數(shù)

    26.優(yōu)化事件處理

    27.選擇<link>而不是@import

    28.避免Filter

    29.優(yōu)化Images

    30.優(yōu)化CSS Sprites

    31.不要在HTML中使用過大的Images

    32.favicon.ico最小化以及可緩存

    33.內(nèi)容保持在25K以下

    34.把內(nèi)容打包成一個(gè)復(fù)合文檔

    35.避免空的Image src



    網(wǎng)站前端性能優(yōu)化

    下面就是這些實(shí)踐的詳細(xì)說明。

    1.最小化HTTP請(qǐng)求

    80%的終端響應(yīng)時(shí)間花費(fèi)在前端,這其中的大部分時(shí)間又浪費(fèi)在下載頁面內(nèi)容上,頁面內(nèi)容包括圖片,樣式表,腳本,flash等等。減少頁面內(nèi)容的數(shù)量,轉(zhuǎn)而就減少了渲染頁面需要的HTTP請(qǐng)求數(shù)量。這是優(yōu)化頁面的關(guān)鍵。

    減少頁面內(nèi)容的一種方法是簡化頁面設(shè)計(jì)。但是是否存在其它方法既可以用豐富的內(nèi)容來構(gòu)建頁面,又可以獲取快速的相應(yīng)時(shí)間呢?下面的幾種技術(shù)即可以減少HTTP請(qǐng)求數(shù)量,又可以支持豐富的頁面設(shè)計(jì)。

    合并文件是一種減少HTTP請(qǐng)求的方式,通過合并多個(gè)Js文件到一個(gè)Js文件,合并多個(gè)CSS文件到一個(gè)CSS文件的方式。文件合并是非常有挑戰(zhàn)性的,因?yàn)槊總€(gè)頁面的Script和CSS都不一樣,但是如果在你的發(fā)布過程中有這個(gè)步驟確實(shí)可以響應(yīng)時(shí)間。

    CSS Sprites是減少圖片請(qǐng)求首選的方法。把你的背景圖片合并到一張圖片中,使用CSS的background-image和background-position屬性來展示期望的圖片部分。

    Image maps 合并多個(gè)圖片到一個(gè)圖片中。圖片總大小是一樣的,但是減少了一定數(shù)量的HTTP請(qǐng)求,加快了頁面展示速度。只有當(dāng)頁面中的圖片是連續(xù)的,Image maps才有用,例如導(dǎo)航欄。定義Image maps的坐標(biāo)可能非常乏味并且也容易出錯(cuò),為導(dǎo)航使用Image maps也不是很方便,所以不推薦這種方式。

    Inline images 使用data:URL scheme把圖片數(shù)據(jù)內(nèi)嵌到當(dāng)前頁面中。這種方式會(huì)增加HTML文檔的大小。把Inline images寫到(緩存的)樣式文件中是減少HTTP請(qǐng)求的同時(shí)避免增加頁面大小的一種方法。Inline images還沒有被所有的主流瀏覽器支持。

    2.使用內(nèi)容分發(fā)網(wǎng)絡(luò)(Content Delivery Network,CDN)

    用戶跟Web服務(wù)器的距離對(duì)相應(yīng)時(shí)間是有影響的。從用戶的角度來說,把你的內(nèi)容部署在多個(gè)地理位置分散的服務(wù)器上有利于頁面加載的更快。

    實(shí)施內(nèi)容分發(fā),首先不要嘗試把Web應(yīng)用重構(gòu)成分布式架構(gòu)。根據(jù)不同的應(yīng)用,改變架構(gòu)可能會(huì)有艱巨的任務(wù),比如在不同的服務(wù)器之前同步session狀態(tài),復(fù)制數(shù)據(jù)庫事務(wù)。這樣的話應(yīng)用架構(gòu)這一步可能就會(huì)導(dǎo)致這種嘗試延遲。

    記住80%到90%的終端響應(yīng)時(shí)間花費(fèi)在下載頁面內(nèi)容上面:iamges,css,js,flash等等,這是性能的黃金法則。而不是以重構(gòu)web應(yīng)用架構(gòu)的艱巨任務(wù)開始,最好首先分散靜態(tài)內(nèi)容。這樣不僅最大化的減少響應(yīng)時(shí)間,而且利用內(nèi)容分發(fā)網(wǎng)絡(luò)可以變得更簡單。

    內(nèi)容分發(fā)網(wǎng)絡(luò)(CDN)是分布在多個(gè)地點(diǎn)的web服務(wù)器的集合,可以有效的為用戶分發(fā)內(nèi)容。給用戶分發(fā)內(nèi)容的服務(wù)器是根據(jù)網(wǎng)絡(luò)距離選擇的,例如,選擇擁有最少網(wǎng)絡(luò)跳轉(zhuǎn)或者最快相應(yīng)速度的服務(wù)器。

    3.增加Expires或者Cache-Control頭

    這個(gè)規(guī)則有兩個(gè)方面:

    對(duì)于靜態(tài)資源:實(shí)行"永不過期"策略,通過在header中把Expires設(shè)置盡量長點(diǎn)

    對(duì)于動(dòng)態(tài)資源:使用一個(gè)適當(dāng)?shù)腃ache-Control header幫助瀏覽器響應(yīng)條件請(qǐng)求

    頁面設(shè)計(jì)的越來越豐富,這就意味著頁面中有更多的js,css,images,falsh等。首次訪問頁面的用戶可能會(huì)有幾個(gè)HTTP請(qǐng)求,但是通過使用Expires header你可以使這些內(nèi)容緩存。這樣在后續(xù)頁面訪問時(shí)可以避免不必要的HTTP請(qǐng)求次數(shù)。Expires header經(jīng)常和圖片一起用,但是js,css,flash都可以使用。

    瀏覽器(和代理)使用緩存減少HTTP請(qǐng)求數(shù)量和大小,加快頁面加載速度。web服務(wù)器在HTTP響應(yīng)中使用Expires header告訴客戶端內(nèi)容可以被緩存多長時(shí)間。 下面就是一個(gè)Expires header例子,告訴瀏覽器這個(gè)響應(yīng)在2010-4-15之前不會(huì)過期Expires: Thu, 15 Apr 2010 20:00:00 GMT

    如果是Apache服務(wù)器,使用ExpiresDefault指令相對(duì)當(dāng)前日期設(shè)置過期時(shí)間。下面就是設(shè)置請(qǐng)求10年過期的例子:ExpiresDefault "access plus 10 years"

    謹(jǐn)記,如果你使用了Expires header,那么當(dāng)你的文件內(nèi)容有改變時(shí),內(nèi)容的文件名必須改變。這樣內(nèi)容才會(huì)更新。可以再文件名中加版本后,這樣每次發(fā)布時(shí)文件名都會(huì)改變。

    使用Expire header只會(huì)影響已經(jīng)訪問過你站點(diǎn)的用戶。如果用戶第一次訪問站點(diǎn)或者瀏覽器還沒有緩存,它不會(huì)減少HTTP請(qǐng)求次數(shù)。因此這種性能改善的影響依賴于用戶是不是經(jīng)常訪問帶緩存的頁面。通過使用Expires header你可以讓瀏覽器增加緩存內(nèi)容數(shù)量,在后續(xù)頁面訪問時(shí)重用這些內(nèi)容而不用在通過網(wǎng)絡(luò)請(qǐng)求獲取。

    4.Gzip壓縮內(nèi)容

    前端工程師做出的某些決定可以顯著的減少HTTP請(qǐng)求以及響應(yīng)的網(wǎng)絡(luò)傳輸時(shí)間。終端用戶的帶寬速度,網(wǎng)絡(luò)服務(wù)提供商,距網(wǎng)絡(luò)交換節(jié)點(diǎn)的距離這些因素都不受開發(fā)團(tuán)隊(duì)的控制。但是仍有其它的因素會(huì)影響響應(yīng)時(shí)間。比如,通過壓縮HTTP響應(yīng)來減少響應(yīng)時(shí)間。

    HTTP/1.1開始,web客戶端就開始支持HTTP請(qǐng)求的 Accept-Encoding header。Accept-Encoding: gzip, deflate

    如果web服務(wù)器在請(qǐng)求中看到這種header,它就會(huì)用客戶端列出來的方法來壓縮響應(yīng)內(nèi)容。web服務(wù)器通過響應(yīng)中的Content-Encoding header通知web客戶端。Content-Encoding: gzip

    Gzip是目前最流行以及最有效的壓縮方法。其它你有可能看到的壓縮格式是deflate,但是它不是很流行以及很有效。

    Gzip通常可以把響應(yīng)內(nèi)容大小減少70%。目前瀏覽器當(dāng)中接近90%的網(wǎng)絡(luò)流量支持gzip。

    對(duì)于瀏覽器以及代理來說還有一個(gè)已知問題就是瀏覽器期望的內(nèi)容和它獲取的壓縮內(nèi)容可能不匹配。幸運(yùn)的是,這種情況隨著舊版瀏覽器的使用率越來越低會(huì)越來越少。Apache模塊通過添加適當(dāng)?shù)牟煌憫?yīng)頭來解決這個(gè)問題。

    服務(wù)端選擇用Gzip壓縮內(nèi)容主要依賴于文件類型,但是通常也受限于要決定壓縮的內(nèi)容。大部分web站點(diǎn)用gzip壓縮html文檔。當(dāng)然也值的壓縮腳本以及樣式文件,但是很多網(wǎng)站都沒有選擇這么做。事實(shí)上,可以用gzip壓縮任何文本響應(yīng)內(nèi)容,包括XML和JSON。Image和PDF不建議gzip壓縮,因?yàn)樗鼈兌际潜粔嚎s過的。試圖壓縮它們不僅浪費(fèi)CPU也有可能會(huì)增加文件大小。

    gzip壓縮盡可能多的文件類型是減少頁面大小提升用戶體驗(yàn)的一種簡單方法。

    5.把CSS文件放到頂部

    CSS文件移到文檔的HEAD中看起來好像可以加快頁面載入速度,其實(shí)這是因?yàn)榘袰SS文件放到HEAD中,可以讓頁面逐步渲染。

    前端工程師可能只關(guān)注性能,希望頁面可以逐步加載,但是對(duì)于用戶來說,不管頁面有多少內(nèi)容,希望瀏覽器可以盡快的展示頁面。對(duì)于頁面內(nèi)容很多以及用戶網(wǎng)絡(luò)環(huán)境不好的情況,這一點(diǎn)非常重要。給用戶視覺反饋(例如進(jìn)度提示)的重要性不言而喻,有很多類似的研究。當(dāng)瀏覽器加載頁面時(shí)逐步加載頭部,導(dǎo)航欄,以及頂部logo等的過程,HTML頁面就相當(dāng)于進(jìn)度提示,這樣就給等待頁面加載的用戶一個(gè)視覺反饋。提高整體的用戶體驗(yàn)。

    如果把CSS文件放到頁面底部,在很多瀏覽器中可能會(huì)影響逐步渲染過程,包括IE瀏覽器。因?yàn)檫@些瀏覽器會(huì)阻塞渲染過程以防頁面元素樣式改變時(shí)重繪元素。用戶就會(huì)看到一個(gè)空白頁。

    HTML的規(guī)范中明確聲明了CSS是包含在頁面的HEAD中的。

    6.把Js文件放到底部****

    腳本文件會(huì)導(dǎo)致的一個(gè)問題就是它們會(huì)阻塞并行下載。HTTP/1.1規(guī)范建議不要在一個(gè)主機(jī)上并行下載不超過兩個(gè)腳本文件。如果把圖片托管到多臺(tái)主機(jī)上面,那就可以并行下載多個(gè)圖片文件。但是當(dāng)一個(gè)腳本文件正在下載時(shí),瀏覽器不會(huì)下載其他的腳本文件,即便這個(gè)腳本文件在其它主機(jī)上面。

    在有些情況下想要把腳本文件移動(dòng)文檔底部并不容易。例如如果腳本使用document.write插入頁面內(nèi)容,它就不能移到頁面底部。這可能會(huì)引起作用域問題。在很多情況下,還有其它的途徑解決類似的這種問題。

    一個(gè)常用的建議就是使用延時(shí)腳本。script的DEFER屬性表明腳本不包含document.write,告訴瀏覽器可以繼續(xù)渲染。但是也不是所有的瀏覽器都支持。Firefox不支持DEFER屬性,IE對(duì)DEFER的支持也不盡如意。

    如果腳本可以延遲加載,它就可以放到頁面底部,這樣就會(huì)加快頁面的載入速度。

    7.避免CSS表達(dá)式

    CSS表達(dá)式是動(dòng)態(tài)設(shè)置CSS屬性的一種強(qiáng)大并且危險(xiǎn)的方法。IE從5開始支持CSS表達(dá)式,但是從IE8開始棄用這種方式。下面的例子就是,背景顏色可以根據(jù)時(shí)間動(dòng)態(tài)設(shè)置:
    background-color: expression( (new Date()).getHours()%2 ? "#B8D4FF" : "#F08A00" );

    如上面展示的,expression方法接受一個(gè)js表達(dá)式參數(shù),CSS的屬性是根據(jù)js表達(dá)式的計(jì)算結(jié)果設(shè)置的。其它瀏覽器不支持expression方法,所以它只適用于IE瀏覽器。

    CSS表達(dá)式的問題是計(jì)算太頻繁了,不僅頁面渲染縮放時(shí),需要計(jì)算,頁面滾動(dòng)甚至鼠標(biāo)滑過頁面時(shí)都需要重新計(jì)算。如果在CSS表達(dá)式里面加個(gè)計(jì)數(shù)器來追蹤C(jī)SS表達(dá)式的計(jì)算頻率,把鼠標(biāo)滑過頁面就會(huì)發(fā)現(xiàn)計(jì)算次數(shù)會(huì)輕易的超過10000次。

    減少CSS表達(dá)式計(jì)算次數(shù)的方法是使用一次性表達(dá)式,表達(dá)式第一次計(jì)算時(shí)會(huì)給樣式屬性設(shè)置一個(gè)顯示值來代替表達(dá)式。如果樣式屬性必須根據(jù)頁面活動(dòng)動(dòng)態(tài)設(shè)置,用事件綁定代替CSS表達(dá)式是一個(gè)好的選擇。

    8.保持Js和CSS外部引用

    有很多性能規(guī)則來處理外部組件管理。然而,在考慮這些因素之前,有一個(gè)更基本的問題需要考慮:js和css應(yīng)該包含在外部文件中,還是內(nèi)聯(lián)在頁面里面?

    使用外部文件通常會(huì)加快頁面速度,因?yàn)檫@樣js,css文件可以被瀏覽器緩存。如果js,css內(nèi)聯(lián)在頁面中,每次請(qǐng)求頁面的時(shí)候都會(huì)重新加載。這樣雖然減少了http請(qǐng)求數(shù)量,但是增加了html的大小。從另一方面來說,如果js,css在外部文件中并且被瀏覽器緩存,那么后續(xù)請(qǐng)求不會(huì)增加html文檔大小,也不會(huì)增加http請(qǐng)求數(shù)量(外部文件從瀏覽器緩存中取,不經(jīng)過http請(qǐng)求了)。

    關(guān)鍵是html文檔使用緩存的js,css文件的頻率。這個(gè)因素盡管難以量化,但是也可以通過其它維度衡量。如果一個(gè)站點(diǎn)用戶每個(gè)session周期需要訪問多個(gè)頁面,并且這多個(gè)頁面有共同的腳本和樣式文件,那么使用緩存的文件就有潛在的好處。

    一般情況下都是把js,css寫到外部文件中,但是也有例外,內(nèi)聯(lián)適合應(yīng)用在首頁。首頁的每個(gè)session的訪問次數(shù)少,內(nèi)聯(lián)js,css可以加快終端的響應(yīng)時(shí)間。

    內(nèi)聯(lián)可以降低http請(qǐng)求,使用外部文件緩存也有好處。通常的處理是首頁內(nèi)聯(lián)js,css,當(dāng)也加載完成之后再動(dòng)態(tài)下載外部文件,這樣后續(xù)頁面就可以從瀏覽器緩存中獲取這些文件。

    9.減少DNS查詢路徑

    域名系統(tǒng)(DNS)是把域名映射到IP地址上,就像手機(jī)通訊錄把人名映射到手機(jī)號(hào)上一樣。當(dāng)你在瀏覽器輸入www.yahoo.com的時(shí)候,DNS解析服務(wù)連接到瀏覽器然后返回服務(wù)器的IP地址。DNS是有開銷的,一般會(huì)花費(fèi)20-120ms為主機(jī)查詢IP地址。瀏覽器不能通過主機(jī)名下載任何東西,除非DNS解析已完成。

    為了性能考慮DNS查詢都會(huì)緩存。這個(gè)緩存可能發(fā)生在某一臺(tái)緩存服務(wù)器上面,這個(gè)緩存服務(wù)器有用戶的ISP或者局域網(wǎng)維護(hù),也有可能緩存到個(gè)別用戶電腦上。DNS信息保存在操作系統(tǒng)的DNS緩存中(windows上面的DNS client service)。大部分瀏覽器都是自己的DNS緩存以區(qū)分于操作系統(tǒng)的緩存。一旦瀏覽器在自己的緩存中保存了DNS記錄,它就不會(huì)從操作系統(tǒng)里面查這條記錄了。

    IE默認(rèn)緩存DNS查詢30分鐘,可以在注冊(cè)表DnsCacheTimeout中指定。Firefox默認(rèn)緩存DNS查詢1分鐘,可以通過network.dnsCacheExpiration配置項(xiàng)設(shè)置。

    當(dāng)客戶端的DNS緩存都是空時(shí)(瀏覽器和操作系統(tǒng)的),DNS的查詢次數(shù)就和頁面中主機(jī)的DNS查詢次數(shù)一樣。包括頁面url,圖片,腳本樣式文件,flash對(duì)象里面的主機(jī)名。減少獨(dú)立主機(jī)名,就可以減少DNS查詢次數(shù)。
    減少獨(dú)立主機(jī)名對(duì)頁面中需要并行下載的地方有潛在的影響。避免DNS查詢雖然可以減少響應(yīng)時(shí)間,但是減少并行下載也會(huì)增加響應(yīng)時(shí)間。這兩者是相互矛盾的,作者的建議是保持2到4個(gè)單獨(dú)主機(jī),這樣DNS查詢不至于過多,也有一定的并行下載。

    和中的代碼塊也應(yīng)該壓縮。盡管你用gzip壓縮了你的腳本和樣式文件,再次壓縮它們?nèi)匀豢梢詼p少5%或者更多的體積。隨著使用的js和css越來越多,壓縮代碼可以消減成本。

    10.壓縮js和css

    壓縮的做法就是移除代碼中不必要的字符減少文件大小進(jìn)而提升加載速度。代碼一旦被壓縮,所有的注釋,不需要的空白字符(空格,換行,tab)都會(huì)被移除。對(duì)于Js來說,這會(huì)提高響應(yīng)時(shí)間性能,因?yàn)橐螺d的文件大小減少了。常用的壓縮js代碼的工具是JSMin,YUI Compressor。YUICompressor也可以壓縮css。和中的代碼塊也應(yīng)該壓縮。盡管你用gzip壓縮了你的腳本和樣式文件,再次壓縮它們?nèi)匀豢梢詼p少5%或者更多的體積。隨著使用的js和css越來越多,壓縮代碼可以消減成本。

    代碼混淆是處理源代碼的另一種選擇,它比代碼壓縮更復(fù)雜,因此在混淆過程中也更容易產(chǎn)生問題。有調(diào)查指出代碼壓縮可以減少21%的大小,代碼混淆可以減少25%的大小。盡快代碼混淆有更高的壓縮率,但是代碼壓縮風(fēng)險(xiǎn)更低。

    除了外部的腳本樣式需要壓縮,內(nèi)聯(lián)在<script><style>中的代碼塊也應(yīng)該壓縮。盡管你用gzip壓縮了你的腳本和樣式文件,再次壓縮它們?nèi)匀豢梢詼p少5%或者更多的體積。隨著使用的js和css越來越多,壓縮代碼可以消減成本。

    11.避免重定向

    重定向是使用301,302狀態(tài)碼來完成的。下面就是一個(gè)使用301響應(yīng)的HTTP header:

    HTTP/1.1 301 Moved Permanently

    Location: http://example.com/newuri

    Content-Type: text/html

    瀏覽器自動(dòng)的把用戶帶到Location字段制定的url中。重定向所有有用額信息都在header里面。響應(yīng)內(nèi)容通常是空的。

    12.刪除重復(fù)Scripts

    一個(gè)頁面中有兩個(gè)一樣的js文件會(huì)影響性能。這可能不像你想的那樣不同尋常。當(dāng)團(tuán)隊(duì)人數(shù)及腳本數(shù)量增加時(shí),很有可能一個(gè)頁面就會(huì)引入相同的腳本文件。這種情況發(fā)生時(shí),重復(fù)的腳本會(huì)創(chuàng)建不需要HTTP連接而且多次執(zhí)行進(jìn)而會(huì)影響性能。不需要的HTTP請(qǐng)求發(fā)生在IE瀏覽器中,F(xiàn)irefox不會(huì)有這種現(xiàn)象。在IE中,如果一個(gè)外部js被引入了兩次并且沒被緩存,它就會(huì)在頁面加載時(shí)產(chǎn)生兩個(gè)HTTP請(qǐng)求。甚至當(dāng)js被緩存時(shí),當(dāng)用戶刷新頁面后,額外的HTTP請(qǐng)求也會(huì)發(fā)生。除了產(chǎn)生浪費(fèi)的HTTP請(qǐng)求,腳本多次也會(huì)浪費(fèi)時(shí)間。這種情況在Firefox以及IE中都會(huì)發(fā)生,不管js文件有沒有被緩存。

    有一種方法可以避免多次引入相同的腳本,那就是在模板系統(tǒng)里面實(shí)現(xiàn)一個(gè)腳本管理模塊。這樣的話,在HTML頁面中就可以利用script標(biāo)簽引入腳本管理文件。<script type="text/javascript" src="menu_1.0.17.js"></script>這種方式不僅可以避免相同的腳本插入多次,還可以處理腳本相關(guān)的其它情況,比如,依賴檢查,把版本號(hào)加到腳本文件名后面就可以實(shí)現(xiàn)緩存腳本更新。

    13.配置Etags

    ETags(Entity tags)是Web服務(wù)器和瀏覽器使用的一種機(jī)制,來決定瀏覽器中緩存的組件是否匹配源服務(wù)器上的組件。(entity和component一樣,代指:圖片,腳本,樣式等)ETags提供了一種可以驗(yàn)證entities是否修改的機(jī)制。一個(gè)ETag是一個(gè)字符串可以唯一標(biāo)示一個(gè)指定版本的組件。唯一的格式要求就是這個(gè)字符串必須加引號(hà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匹配,會(huì)返回一個(gè)304狀態(tài)碼,這樣可以減少12195字節(jié)的響應(yīng)。

    GET /i/yahoo.gif HTTP/1.1

    Host: us.yimg.comIf-Modified-Since: Tue, 12 Dec 2006 03:03:59 GMTIf-None-Match: "10c24bc-4ab-457e1c1f"HTTP/1.1 304 Not Modified

    ETags的問題在于它們通常用屬性來構(gòu)建,這些屬性使它們對(duì)于特定的網(wǎng)站服務(wù)器是獨(dú)有的。當(dāng)瀏覽器從服務(wù)器獲取源組件,然后嘗試在不同的服務(wù)器上驗(yàn)證這個(gè)組件時(shí),ETags不會(huì)匹配的。這種情況在使用集群服務(wù)器處理請(qǐng)求時(shí)很常見。默認(rèn)情況下,Apache和IIS在ETag中嵌入數(shù)據(jù),這樣大大降低了在有多個(gè)服務(wù)器的站點(diǎn)上進(jìn)行有效性測(cè)試成功的幾率。

    Apache 1.3和2.x版本的ETag格式是inode-size-timestamp。盡管一個(gè)指定的文件在不同的服務(wù)器中保存在相同的目錄,有著相同的大小,權(quán)限,時(shí)間戳等等,但是不同服務(wù)器的inode是不一樣的。

    IIS 5.0和6.0版本也有ETags問題。IIS的Etags格式是Filetimestamp:ChangeNumber
    ChangeNumber是一個(gè)追蹤IIS配置更改的計(jì)數(shù)器。一個(gè)站點(diǎn)的所有的IIS服務(wù)器的ChangeNumber不可能一樣。Apache和IIS的ETags問題導(dǎo)致的結(jié)果就是,對(duì)于相同的組件在各個(gè)服務(wù)器之間不會(huì)匹配。如果ETags沒有匹配,用戶就不會(huì)收到小的,快速的304響應(yīng);反而會(huì)收到一個(gè)正常的200響應(yīng)和組件內(nèi)容一起。如果web站點(diǎn)只部署在一臺(tái)機(jī)器上,就不會(huì)有這個(gè)問題。但是如果有多臺(tái)服務(wù)器,而且又使用了Apache或者IIS的默認(rèn)ETag配置,用戶獲取頁面的速度就不會(huì)那么快,服務(wù)器有更高的負(fù)載,消耗更多的帶寬,代理也不會(huì)緩存有效的內(nèi)容。即使組件有一個(gè)很大的過期時(shí)間,但是每當(dāng)用戶點(diǎn)擊重載或刷新時(shí),都會(huì)創(chuàng)建一個(gè)條件GET請(qǐng)求。

    如果你沒有利用ETags提供的靈活驗(yàn)證模型,最好移除ETag。Last-Modified頭驗(yàn)證基于組件的時(shí)間戳。移除ETag可以減小響應(yīng)和后續(xù)請(qǐng)求的HTTP頭的大小。在Apache中可以通過修改配置文件來實(shí)現(xiàn):FileETag none。

    14.使Ajax請(qǐng)求可緩存

    使用Ajax的一個(gè)好處就是它能給用戶提供及時(shí)的響應(yīng),因?yàn)樗鼜暮蠖水惒降墨@取數(shù)據(jù)。然而使用Ajax并不能保證用戶可以立馬得到返回的異步j(luò)s和xml響應(yīng)。在許多應(yīng)用中,用戶是否繼續(xù)等待,取決于Ajax如果如何使用。例如在內(nèi)嵌頁面的郵件客戶端中用戶為了獲取符合搜索條件的郵件消息,會(huì)繼續(xù)等待Ajax的請(qǐng)求結(jié)果。重要的是要記住一點(diǎn),“異步”并不代表“及時(shí)”。

    為了提高性能,優(yōu)化Ajax響應(yīng)也很重要。提高Ajax性能最重要的方式是緩存響應(yīng)內(nèi)容。來看一個(gè)例子,一個(gè)Web2.0的郵箱客戶端可能使用Ajax來自動(dòng)下載用戶地址列表。如果用戶從上次使用郵箱web app之后沒有修改過地址列表,那么之前地址列表響應(yīng)可以從緩存中讀取,如果Ajax響應(yīng)用Expires或者Cache-Control頭做了緩存。瀏覽器必須知道何時(shí)使用緩存地址列表對(duì)于一個(gè)新請(qǐng)求。可以通過添加一個(gè)時(shí)間戳到地址列表Ajax url后面,表明用戶修改地址列表的最新時(shí)間,例如,&t=1190241612。如果地址列表自從上次下載都沒有被修改,時(shí)間戳應(yīng)該不變,然后就會(huì)從瀏覽器緩存中去地址列表,這樣就消除了一個(gè)多余的HTTP請(qǐng)求。如果用戶修改了地址列表,時(shí)間戳就確保了新的url不會(huì)匹配到緩存中的響應(yīng),瀏覽器會(huì)請(qǐng)求更新的地址列表。

    盡管Ajax響應(yīng)是動(dòng)態(tài)創(chuàng)建的,也可能只適用于單個(gè)用戶,也應(yīng)該被緩存。這樣做可以使你的Web2.0 apps更快。

    15.盡早刷新緩存

    當(dāng)用戶請(qǐng)求一個(gè)頁面時(shí),后端可能會(huì)消耗200或者500ms來整合HTML頁面。在這段時(shí)間內(nèi),瀏覽器處在等待服務(wù)器返回?cái)?shù)據(jù)的空閑狀態(tài)。在PHP中,可以使用flush()函數(shù)。它可以讓服務(wù)器發(fā)送部分準(zhǔn)備好的html響應(yīng)給瀏覽器,然后當(dāng)后端正在處理html頁面的其余部分時(shí),瀏覽器可以開始獲取內(nèi)容。

    刷新緩存的最佳位置是在HEAD標(biāo)簽之后,因?yàn)镠TML頁面的head通常更容易產(chǎn)生,而且它可以引入任何CSS和JS文件,這樣當(dāng)后端還在處理時(shí),瀏覽器也可以開始并行的下載引用文件。

    ... <!-- css, js --></head><?php flush(); ?><body>

    ... <!-- content -->

    16.使用GET方式的Ajax請(qǐng)求

    雅虎郵件團(tuán)隊(duì)發(fā)現(xiàn)當(dāng)使用XMLHttpRequest時(shí),瀏覽器器實(shí)施POST請(qǐng)求有兩步,第一步發(fā)送headers,然后發(fā)送數(shù)據(jù)。所以最好使用GET請(qǐng)求,它只發(fā)一個(gè)TCP包(除非cookie數(shù)量很多)。在IE中url的最大長度是2K,如果數(shù)據(jù)超過2K,不能使用GET請(qǐng)求。

    如果POST請(qǐng)求沒有發(fā)送數(shù)據(jù),那么它的行為就像POST一樣。基于HTTP協(xié)議,GET請(qǐng)求是用來獲取信息的,所以當(dāng)你僅僅是獲取數(shù)據(jù)而不是向服務(wù)端發(fā)送數(shù)據(jù)時(shí),最好使用GET請(qǐng)求。

    17.延遲加載組件

    看一眼頁面,然后思考下:“那些是一定需要在初始化渲染頁面時(shí)?”。其余的內(nèi)容和組件都可以延遲獲取。

    js文件是一個(gè)理想的備選項(xiàng)。例如如果js代碼或者庫是用來實(shí)現(xiàn)拖拽,動(dòng)畫效果的,那么就可以等待加載,因?yàn)轫撁嬷械耐献г卦诔跏蓟秩局蟮摹?紤]可以延遲加載組件時(shí)也包括隱藏內(nèi)容(在用戶某個(gè)行為之后的才出現(xiàn)的內(nèi)容)和圖片的修飾。

    當(dāng)性能目標(biāo)存在于其他web開發(fā)最佳實(shí)踐中是非常好的。在這種情況下,漸進(jìn)增強(qiáng)告訴我們js可以提升用戶體驗(yàn),但是必須確保頁面沒有js時(shí)也可以正常工作。因此當(dāng)你確定頁面正常后,你可以用一些延時(shí)加載js來增強(qiáng)頁面效果。

    18.預(yù)加載組件

    預(yù)加載看起來和延遲加載相反,但是它有不同的目的。通過預(yù)加載組件,你可以充分利用瀏覽器空閑時(shí)間獲取需要的組件(圖片,樣式文件,腳本文件)。這樣當(dāng)用戶訪問下個(gè)頁面時(shí),你可能已經(jīng)把大部分組件緩存到瀏覽器緩存,然后頁面加載時(shí)就會(huì)更快。有下面幾種類型的預(yù)加載:

    無條件預(yù)加載:一旦開始加載,你就開始獲取一些額外的組件。拿google.com作為例子,看下一張sprite圖片時(shí)如何請(qǐng)求加載的。這張sprite圖片google首頁并不需要,但是在搜索結(jié)果頁面需要。
    有條件預(yù)加載:基于用戶行為,你做了一個(gè)猜測(cè)用戶下一步要去那個(gè)頁面,然后預(yù)加載響應(yīng)的東西。在search.yahoo.com站點(diǎn)你會(huì)發(fā)現(xiàn)當(dāng)你開始在輸入框輸入時(shí),一些額外的組件時(shí)如何被請(qǐng)求的。
    預(yù)期預(yù)加載:發(fā)新版本時(shí)提前加載。發(fā)布新版后,可能會(huì)有這樣的抱怨“新本很酷,但是速度比之前慢”。

    一部分原因可能是用戶訪問之前版本時(shí)有了充分的緩存,但是新版本剛開始沒有緩存。你可以消除這方面的影響通過預(yù)加載一些組件,在你發(fā)新版之前。舊站點(diǎn)可以利用瀏覽器的空閑時(shí)間加載新版要使用的圖片和腳本。

    19.減少DOM元素?cái)?shù)量

    一個(gè)復(fù)雜的頁面意味著要下載更多的字節(jié),js中更慢的DOM訪問速度。例如當(dāng)你遍歷500個(gè)或者5000個(gè)dom元素添加時(shí)間處理時(shí)是不同的。

    大量的dom元素可能意味著有些頁面標(biāo)記需要被改進(jìn)而不一定需要?jiǎng)h除一些內(nèi)容。你是否有過嵌套表格達(dá)到布局目的?使用很多<div>僅僅是修復(fù)布局問題?也許對(duì)標(biāo)記來說有更好的語義正確的方式。

    dom元素的數(shù)量很好測(cè)試,在Firebug控制臺(tái)輸入:document.getElementsByTagName("*").length

    但是多少dom元素算多呢?可以參考下有良好標(biāo)記的類似頁面。

    20.跨域分離組件

    分離組件可以最大化的并行下載。考慮到DNS查考消耗,確保使用不超過2到4個(gè)域。例如你可以托管HMTL和動(dòng)態(tài)內(nèi)容在www.example.org,將靜態(tài)組件放在static1.example.orgstatic2.example.org上面。

    21.減少iframe

    iframe允許把html文檔內(nèi)嵌到父文檔中。理解iframe的工作原理有助于更有效的使用iframe。

    iframe優(yōu)點(diǎn):有助于緩沖第三方內(nèi)容,像廣告;安全沙箱;并行下載js;
    iframe缺點(diǎn):即使是空白標(biāo)簽也有消耗;阻塞頁面加載;非語義;

    22.不要404

    HTTP請(qǐng)求是費(fèi)時(shí)操作,所以發(fā)HTTP請(qǐng)求但是獲取一個(gè)無用響應(yīng)(例如404)是完全沒必要的,也會(huì)降低用戶體驗(yàn)而么有任何好處。

    有些站點(diǎn)有一些有用的404內(nèi)容,這有助于提高用戶體驗(yàn),但是仍然會(huì)浪費(fèi)服務(wù)端的資源(像數(shù)據(jù)庫等)。當(dāng)引入的一個(gè)外部js文件是有問題的而且找不到的時(shí)候,這種情況是很糟糕的。首先這次下載會(huì)阻塞并行下載,然后瀏覽器可能會(huì)把404響應(yīng)內(nèi)容當(dāng)成js代碼解析,找出一些有用的東西。

    23.減少Cookie大小

    之所以會(huì)使用HTTP cookies是有多種理由的,例如權(quán)限,個(gè)性化。cookies的信息在瀏覽器和服務(wù)端通過HTTP頭交換。盡量減少cookies大小有助于減少用戶響應(yīng)時(shí)間。

    24.組件使用沒有cookie的域

    當(dāng)瀏覽器請(qǐng)求一個(gè)靜態(tài)圖片時(shí),會(huì)隨請(qǐng)求發(fā)送cookies到服務(wù)器,但是這些cookies在服務(wù)端又沒什么用。只會(huì)增加網(wǎng)絡(luò)流量。應(yīng)該確保靜態(tài)組件響應(yīng)沒有cookie請(qǐng)求。可以創(chuàng)建一子域?qū)iT托管靜態(tài)組件。

    假設(shè)你的域名是www.www88889999.com,你可以把靜態(tài)組件托管在static.zishenwang.com。如果你已經(jīng)在頂級(jí)域名zishenwang.com上面設(shè)置了cookie而不是在www.www88889999.com上面設(shè)置,那么所有的經(jīng)過static.zishenwang.com的請(qǐng)求都會(huì)攜帶cookie。這種情況你可以買一個(gè)新域名,把靜態(tài)組件托管到新域名上,并保持這個(gè)域名沒有cookie。

    把靜態(tài)文件托管在無cookie的域,還有一個(gè)好處就是,有些代理可能不會(huì)緩存那些請(qǐng)求中帶cookie的靜態(tài)組件。如果你想知道你是應(yīng)該用zishenwang.com或者static.zishenwang.com作為主頁,考慮下cookie的影響。如果忽略www,會(huì)把cookie寫到*.zishenwang.com中,所以為了性能考慮最好使用帶www的子域并且把cookie寫到子域。

    25.減少DOM訪問次數(shù)

    js訪問DOM元素也是耗時(shí)操作,為了更好的頁面響應(yīng),你最好做到下面幾點(diǎn):

    緩存訪問到的元素引用
    更新"離線"節(jié)點(diǎn)添加到DOM樹中避免用js操作布局

    26.優(yōu)化事件處理

    有時(shí)頁面可能會(huì)響應(yīng)延時(shí),因?yàn)?/span>DOM樹中不同元素上綁定了太多的事件,然后這些事件執(zhí)行的太頻繁了。這就是為什么事件委托是一個(gè)好的方法。如果在一個(gè)div里面有10個(gè)button,可以給div綁定一個(gè)事件而不是給每一個(gè)button綁定事件。因?yàn)橛惺录芭荩阅憧梢圆东@到這個(gè)事件,并且可以定位出來自于那個(gè)button。

    如果你想開始對(duì)DOM樹做點(diǎn)什么,你并不需要等待onload事件。通常你需要確定是你要獲取的標(biāo)簽在DOM樹中已經(jīng)可用。你也沒必要等待所有的圖片都被下載。等到所有瀏覽器都支持DOMContentLoad事件,你可以用DOMContentLoad事件代替onload事件。

    27.選擇<link>而不是@import

    前面的最佳實(shí)踐有一點(diǎn)就是把CSS放到頂部,這樣可以漸進(jìn)渲染。在IE中@import的行為和在頁面底部使用<link>的效果一樣,所以最好不要使用它。

    28.避免Filter

    IE有個(gè)屬性AlphaImageLoader filter,這個(gè)屬性主要為了實(shí)現(xiàn)真彩色的PNG圖片在IE7以下中的半透明效果。當(dāng)瀏覽器正在下載圖片時(shí),使用這個(gè)filter會(huì)阻塞渲染讓瀏覽器停止響應(yīng)。它也會(huì)增加內(nèi)存開銷,會(huì)作用于每個(gè)元素而不是每個(gè)圖片。

    最好的方式是完全避免使用AlphaImageLoader,使用PNG8代替,PNG8對(duì)IE友好。如果必須要使用AlphaImageLoader,使用下劃線hack _filter以防對(duì)使用IE7+的用戶不利。

    29.優(yōu)化Images

    設(shè)計(jì)師為網(wǎng)頁設(shè)計(jì)好圖片之后,在傳到服務(wù)器上面之前還有很多事情要做。

    你可以檢查下GIFs,看看他們使用的調(diào)色板大小是佛對(duì)應(yīng)圖片顏色數(shù)。使用imagemagick工具,非常容易檢查,使用命令 -verbose image.gif。當(dāng)你看到一個(gè)圖片使用了4種顏色,一個(gè)256顏色“槽”在調(diào)色板中,這說明還是有提升空間的。

    嘗試把GIFs轉(zhuǎn)成PNGs,看下大小是否減少了。通常是有所減小的。開發(fā)者經(jīng)常在使用PNG時(shí)猶豫,擔(dān)心瀏覽器支持限制,但是現(xiàn)在這種事不會(huì)發(fā)生了。現(xiàn)在唯一要擔(dān)心的是真彩色PNG的透明度通道,GIF不是真彩色,不支持透明度變化。因此GIF可以做的,PNG也可以做(動(dòng)畫除外)。在imagemagick工具中使用下面命令可以安全的使用PNG:convert image.gif image.pngpngcrush工具(PNG優(yōu)化工具)中處理所有的PNG。在jpegtran工具中處理所有的JPEG。這個(gè)工具無損JPEG操作,可以用來優(yōu)化移除圖片中的注解以及無用信息(例如EXIF信息)。

    30.優(yōu)化CSS Sprites

    sprite中水平排列圖片比垂直排列圖片更剩空間。

    sprite中組合同類色可以降低顏色數(shù)量。理想情況下小于256色,這樣更適應(yīng)PNG8。保持移動(dòng)友好性,sprite中的圖片之間不要留大的空白。這樣雖然對(duì)文件大小沒多少影響,但是用戶代理可以更少的內(nèi)存把圖片解壓成像素地圖。100X100的圖片有一萬個(gè)像素,1000X1000就有一百萬個(gè)像素。

    31.不要在HTML中使用過大的Images

    不要使用超過你需要的大圖片,因?yàn)槟憧梢栽?/span>HTML中設(shè)置寬高。如果你需要<img width="100" height="100" src="mycat.jpg" alt="My Cat" />,那么你的圖片(mycat.jpg)應(yīng)該是100X100,而不是500X500。

    32.favicon.ico最小化以及可緩存

    favicon.ico存在服務(wù)端根目錄。即使你不關(guān)注它,但是瀏覽器仍然需要請(qǐng)求它,因此最好不要用404響應(yīng)。因?yàn)樵谕慌_(tái)服務(wù)器上面,瀏覽器每次請(qǐng)求它時(shí)也會(huì)帶著cookie。這個(gè)圖片也會(huì)干擾下載序列,例如在IE瀏覽器中當(dāng)你請(qǐng)求額外的組件,favicon會(huì)在這些組件之前下載。所以為了減少favicon的缺點(diǎn),需要做到下面幾點(diǎn):
    使用小的favicon,最好1K一下。設(shè)置一個(gè)你認(rèn)為合適的Expires header。你可以設(shè)置Expires header為幾個(gè)月。為了做明智的決定,你可以檢查favicon.icon的上次修改時(shí)間。

    33.內(nèi)容保持在25K以下

    這個(gè)限制是基于這樣一個(gè)事實(shí),iphone不會(huì)緩存超過25K的內(nèi)容。注意這是未壓縮大小。這也說明了壓縮的重要性,但是僅僅gzip壓縮是不夠的。

    34.把內(nèi)容打包成一個(gè)復(fù)合文檔

    把內(nèi)容打包成一個(gè)復(fù)合文檔相當(dāng)于帶附件的郵件,可以讓你通過一個(gè)HTTP請(qǐng)求獲取多個(gè)內(nèi)容。使用這項(xiàng)技術(shù)之前,先確認(rèn)下用戶代理是否支持這種技術(shù)。

    35.避免空的Image src

    src屬性的Image經(jīng)常會(huì)出現(xiàn)。主要有兩種形式:

    HTML形式:<img src="">
    js形式:var img = new Image(); img.src = "";

    這兩種形式都有同樣的影響:瀏覽器給服務(wù)端發(fā)送另外的請(qǐng)求。

    IE對(duì)當(dāng)前頁所在目錄發(fā)請(qǐng)求。Safari和Chrome對(duì)當(dāng)前頁面本身發(fā)請(qǐng)求。Firefox3和之前的版本行為和Safari和Chrome一樣,但是3.5以上版本不會(huì)發(fā)請(qǐng)求。Opera碰到這種情況也不會(huì)發(fā)請(qǐng)求。

    本文原作者:留七七 原文鏈接鏈接:https://www.jianshu.com/p/d75555313845,本文鏈接:http://www.www88889999.com/zyh/16。

    本文由資深網(wǎng)整理發(fā)布,如有侵權(quán)請(qǐng)聯(lián)系刪除。

    熱門標(biāo)簽
    營銷型網(wǎng)站建設(shè) 怎么做網(wǎng)站 營銷型網(wǎng)站與展示型網(wǎng)站的區(qū)別 網(wǎng)站優(yōu)化原理 網(wǎng)站收錄 網(wǎng)站文章優(yōu)化 本地化網(wǎng)站優(yōu)化 網(wǎng)站建設(shè)合同 網(wǎng)站優(yōu)化合同 網(wǎng)站優(yōu)化排名 網(wǎng)站創(chuàng)意怎么做 網(wǎng)站有點(diǎn)擊無咨詢 有排名無點(diǎn)擊 網(wǎng)站定位 網(wǎng)站怎么做推廣 自己怎么做網(wǎng)站 網(wǎng)站怎么做 網(wǎng)站建設(shè)多少錢 網(wǎng)站建設(shè)價(jià)格 網(wǎng)站建設(shè)素材
    山東淄博市高新區(qū)齊魯電商谷C3-802
    843897106
    www.www88889999.com
    18615152101 0533-3910025
    Copyright 717 淄博資深網(wǎng)站建設(shè)公司 All rights reseved 魯ICP備17013190號(hào)-1
    日韩高清在线日韩大片观看网址| 手机看片日韩福利| 久青草久青草视频在线观看 | 樱桃视频高清免费观看在线播放| 成人羞羞视频国产| 亚洲午夜无码久久久久小说| 李丽莎1分37钞视频最大尺度| 亚洲人成人77777网站| 日韩欧美国产电影| 久久综合狠狠综合久久97色| 日日摸日日碰夜夜爽亚洲| 久久久久久久人妻无码中文字幕爆| 成人男女网18免费视频| 东北壮汉gayxxxvideo| 天天插天天操天天射| h小视频在线观看| 国产精品高清一区二区三区 | 永久在线免费观看| 亚洲精品无码久久毛片波多野吉衣| 欧美无人区码卡二卡3卡4免费| 亚洲成a人v欧美综合天| 最近2018免费中文字幕视频| 五月天婷五月天综合网站| 日出水了特别黄的视频| 丰满人妻熟妇乱又仑精品| 好日子在线观看视频大全免费| silk131中字在线观看| 国产老妇伦国产熟女老妇高清| 69视频在线观看| 国产成人性色视频| 美女邪恶色动图gig27报| 厨房掀起馊子裙子挺进去视频| 爆乳少妇在办公室在线观看| 亚洲熟妇av一区二区三区宅男| 最近中文字幕电影大全免费版| 久久精品国产福利电影网| 成人在线免费视频| yellow字幕网在线| 国产精品熟女视频一区二区| 青青草偷拍视频| 国产r67194吃奶视频|