前端性能優(yōu)化

本文主要考慮客戶端性能、服務(wù)器端和網(wǎng)絡(luò)性能,內(nèi)容框架來自Yahoo Developer Network,包含 7 個(gè)類別共 35 條前端性能優(yōu)化最佳實(shí)踐,在此基礎(chǔ)上補(bǔ)充了一些相關(guān)或者更符合主流技術(shù)的內(nèi)容。

主流技術(shù)的內(nèi)容

前端性能的一個(gè)重要指標(biāo)是頁面加載時(shí)間,不僅事關(guān)用戶體驗(yàn),也是搜索引擎排名考慮的一個(gè)因素。

  • 來自Google的數(shù)據(jù)表明,一個(gè)有10條數(shù)據(jù)0.4秒能加載完的頁面,變成30條數(shù)據(jù)0.9秒加載完之后,流量和廣告收入下降90%。
  • Google Map 首頁文件大小從100KB減小到70-80KB后,流量在第一周漲了10%,接下來的三周漲了25%。
  • 亞馬遜的數(shù)據(jù)表明:加載時(shí)間增加100毫秒,銷量就下降1%。

以上數(shù)據(jù)更說明「加載時(shí)間就是金錢」,前端優(yōu)化主要圍繞提高加載速度進(jìn)行。

一、頁面內(nèi)容

1. 減少HTTP請(qǐng)求數(shù)
Web 前端 80% 的響應(yīng)時(shí)間花在圖片、樣式、腳本等資源下載上。最直接的方式是減少頁面所需資源,但并不現(xiàn)實(shí)。所以,減少HTTP請(qǐng)求數(shù)主要的途徑是:

  • 合并JS/CSS文件。服務(wù)器端(CDN)自動(dòng)合并,基于Node.js的文件合并工具,通過把所有腳本放在一個(gè)文件中的方式來減少請(qǐng)求數(shù)。
  • 使用CSS Sprite將背景圖片合并成一個(gè)文件,通過background-imagebackground-position 控制顯示
  • 行內(nèi)圖片(Base64編碼)。使用Data URI scheme將圖片嵌入HTML或者CSS中;或者將CSS、JS、圖片直接嵌入HTML中,會(huì)增加文件大小,也可能產(chǎn)生瀏覽器兼容及其他性能問題。

減少頁面的HTTP請(qǐng)求數(shù)是個(gè)起點(diǎn),這是提升站點(diǎn)首次訪問速度的重要指導(dǎo)原則。

2. 減少DNS查詢
用戶輸入U(xiǎn)RL以后,瀏覽器首先要查詢域名(hostname)對(duì)應(yīng)服務(wù)器的IP地址,一般需要耗費(fèi)20-120毫秒時(shí)間。DNS查詢完成之前,瀏覽器無法從服務(wù)器下載任何數(shù)據(jù)。

基于性能考慮,ISP、局域網(wǎng)、操作系統(tǒng)、瀏覽器都會(huì)有相應(yīng)的DNS緩存機(jī)制。

  • IE緩存30分鐘,可以通過注冊(cè)表中DnsCacheTimeout項(xiàng)設(shè)置;
  • Firefox緩存1分鐘,通過network.dnsCacheExpiration配置;

另外減少不同的主機(jī)名可減少DNS查找,減少不同主機(jī)名的數(shù)量同時(shí)也減少了頁面能夠并行下載的組件數(shù)量,避免DNS查找削減了響應(yīng)時(shí)間,而減少并行下載數(shù)量卻增加了響應(yīng)時(shí)間。原則是把組件分散在2到4個(gè)主機(jī)名下,這是同時(shí)減少DNS查找和允許高并發(fā)下載的折中方案。

3. 避免重定向
HTTP重定向通過301/302狀態(tài)碼實(shí)現(xiàn)。下面是一個(gè)有301狀態(tài)碼的HTTP頭

HTTP/1.1 301 Moved Permanently 
Location: http://example.com/newuri
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)碼,主要是為了讓返回按鈕能正常使用。

客戶端收到服務(wù)器的重定向響應(yīng)后,會(huì)根據(jù)響應(yīng)頭中Location的地址再次發(fā)送請(qǐng)求。重定向會(huì)影響用戶體驗(yàn),尤其是多次重定向時(shí),用戶在一段時(shí)間內(nèi)看不到任何內(nèi)容,只看到瀏覽器進(jìn)度條一直在刷新。

  • 最浪費(fèi)的重定向經(jīng)常發(fā)生、而且很容易被忽略:URL 末尾應(yīng)該添加/但未添加。比如,訪問http://astrology.yahoo.com/astrology將被301重定向到http://astrology.yahoo.com/astrology/(注意末尾的 /)。如果使用 Apache,可以通過Alias或mod_rewrite或DirectorySlash解決這個(gè)問題。
  • 網(wǎng)站域名變更:CNAME結(jié)合Alias或mod_rewrite或者其他服務(wù)器類似功能實(shí)現(xiàn)跳轉(zhuǎn)。

4. 緩存Ajax請(qǐng)求
最重要的的優(yōu)化方式是緩存響應(yīng)結(jié)果。有尚未過期的Expires或者Cache-Control HTTP頭,那么之前的資源就可以從緩存中讀出。必須通知瀏覽器,應(yīng)該繼續(xù)使用之前緩存的資源響應(yīng),還是去請(qǐng)求一個(gè)新的。可以通過給資源的Ajax URL里添加一個(gè)表明用戶資源最后修改時(shí)間的時(shí)間戳來實(shí)現(xiàn)。如果資源從上一次下載之后再?zèng)]有被修改過,時(shí)間戳不變,資源就將從瀏覽器緩存中直接讀出,從而避免一次額外的HTTP往返消耗。詳見服務(wù)器-添加Expires或Cache響應(yīng)頭

5. 延遲加載
頁面初始加載時(shí)哪些內(nèi)容是絕對(duì)必需的?不在答案之列的資源都可以延遲加載。比如:

  • 非首屏使用的數(shù)據(jù)、樣式、腳本、圖片等;
  • 用戶交互時(shí)才會(huì)顯示的內(nèi)容。

遵循「漸進(jìn)增強(qiáng)」理念開發(fā)的網(wǎng)站:JavaScript用于增強(qiáng)用用戶體驗(yàn),但沒有(不支持) JavaScript也能正常工作,完全可以延遲加載JavaScript。

將首屏以外的HTML放在不渲染的元素中,如隱藏的<textarea>,或者type屬性為非執(zhí)行腳本的<script>標(biāo)簽中,減少初始渲染的DOM元素?cái)?shù)量,提高速度。等首屏加載完成或者用戶操作時(shí),再去渲染剩余的頁面內(nèi)容。

6. 預(yù)加載
預(yù)先加載利用瀏覽器空閑時(shí)間請(qǐng)求將來要使用的資源,以便用戶訪問下一頁面時(shí)更快地響應(yīng)。

  • 無條件預(yù)先加載:頁面加載完成(load)后,馬上獲取其他資源。以 google.com 為例,首頁加載完成后會(huì)立即下載一個(gè) Sprite 圖片,此圖首頁不需要,但是搜索結(jié)果頁要用到。
  • 有條件預(yù)先加載:根據(jù)用戶行為預(yù)判用戶去向,預(yù)載相關(guān)資源。比如search.yahoo.com開始輸入時(shí)會(huì)有額外的資源加載。Chrome 等瀏覽器的地址欄也有類似的機(jī)制。
  • 有「陰謀」的預(yù)先加載:頁面即將上線新版前預(yù)先加載新版內(nèi)容。網(wǎng)站改版后由于緩存、使用習(xí)慣等原因,會(huì)有舊版的網(wǎng)站更快更流暢的反饋。為緩解這一問題,在新版上線之前,舊版可以利用空閑提前加載一些新版的資源緩存到客戶端,以便新版正式上線后更快的載入。

7. 減少DOM元素?cái)?shù)量
復(fù)雜的頁面不僅下載的字節(jié)更多,JavaScript DOM操作也更慢。例如,同是添加一個(gè)事件處理器,500個(gè)元素和5000個(gè)元素的頁面速度上會(huì)有很大區(qū)別。

從以下幾個(gè)角度考慮移除不必要的標(biāo)記:

  • 是否還在使用表格布局?
  • 塞進(jìn)去更多的<div>僅為了處理布局問題?也許有更好、更語義化的標(biāo)記。
  • 能通過偽元素實(shí)現(xiàn)的功能,就沒必要添加額外元素,如清除浮動(dòng)。

瀏覽器控制臺(tái)中輸入以下代碼可以計(jì)算出頁面中有多少 DOM 元素:

document.getElementsByTagName('*').length

為什么不使用表格布局?

  • 更多的標(biāo)簽,增加文件大小;
  • 不易維護(hù),無法適應(yīng)響應(yīng)式設(shè)計(jì);
  • 性能考量,默認(rèn)的表格布局算法會(huì)產(chǎn)生大量重繪

8. 劃分內(nèi)容到不同域名
瀏覽器一般會(huì)限制每個(gè)域的并行線程(一般為6個(gè),甚至更少),使用不同的域名可以最大化下載線程,但注意保持在2-4個(gè)域名內(nèi),以避免DNS查詢損耗。

例如,動(dòng)態(tài)內(nèi)容放在csspod.com上,靜態(tài)資源放在static.csspod.com上。這樣還可以禁用靜態(tài)資源域下的Cookie,減少數(shù)據(jù)傳輸,詳見Cookie 優(yōu)化

9. 盡量減少iframe的使用
用iframe可以把一個(gè)HTML文檔插入到父文檔里,重要的是明白iframe是如何工作的并高效地使用它。

<iframe>的優(yōu)點(diǎn):

  • 可以用來加載速度較慢的第三方資源,如廣告、徽章;
  • 可用作安全沙箱;
  • 可以并行下載腳本。

<iframe>的缺點(diǎn):

  • 加載代價(jià)昂貴,即使是空的頁面;
  • 阻塞頁面 load 事件觸發(fā);

Iframe 完全加載以后,父頁面才會(huì)觸發(fā) load 事件。 Safari、Chrome 中通過 JavaScript 動(dòng)態(tài)設(shè)置 iframe src 可以避免這個(gè)問題。

  • 缺乏語義。

10. 避免404錯(cuò)誤
HTTP請(qǐng)求很昂貴,返回?zé)o效的響應(yīng)(如404未找到)完全沒必要,降低用戶體驗(yàn)而且毫無益處。 一些網(wǎng)站設(shè)計(jì)很酷炫、有提示信息的404頁面,有助于提高用戶體驗(yàn),但還是浪費(fèi)服務(wù)器資源。尤其糟糕的是外部腳本返回404,不僅阻塞其他資源下載,瀏覽器還會(huì)嘗試把404頁面內(nèi)容當(dāng)作JavaScript解析,消耗更多資源。

二、服務(wù)器

1. 使用CDN
用戶與服務(wù)器的物理距離對(duì)響應(yīng)時(shí)間也有影響。把內(nèi)容部署在多個(gè)地理位置分散的服務(wù)器上能讓用戶更快地載入頁面。但具體要怎么做呢?

網(wǎng)站80-90%響應(yīng)時(shí)間消耗在資源下載上,減少資源下載時(shí)間是性能優(yōu)化的黃金法則。相比分布式架構(gòu)的復(fù)雜和巨大投入,靜態(tài)內(nèi)容分發(fā)網(wǎng)絡(luò)(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ù)器。

2. 添加Expires或Cache-Control響應(yīng)頭

  • 靜態(tài)內(nèi)容:將 Expires 響應(yīng)頭設(shè)置為將來很遠(yuǎn)的時(shí)間,實(shí)現(xiàn)「永不過期」策略;
  • 動(dòng)態(tài)內(nèi)容:設(shè)置合適的 Cache-Control 響應(yīng)頭,讓瀏覽器有條件地發(fā)起請(qǐng)求。

Cache-Control頭在HTTP/1.1規(guī)范中定義,取代了之前用來定義響應(yīng)緩存策略的頭(例如 Expires、Pragma)。當(dāng)前的所有瀏覽器都支持Cache-Control,因此,使用它就夠了。

3. 啟用Gzip
前端工程師可以想辦法明顯地縮短通過網(wǎng)絡(luò)傳輸HTTP請(qǐng)求和響應(yīng)的時(shí)間。毫無疑問,終端用戶的帶寬速度,網(wǎng)絡(luò)服務(wù)商,對(duì)等交換點(diǎn)的距離等等,都是開發(fā)團(tuán)隊(duì)所無法控制的。但還有別的能夠影響響應(yīng)時(shí)間的因素,壓縮可以通過減少HTTP響應(yīng)的大小來縮短響應(yīng)時(shí)間。

Gzip壓縮通常可以減少70%的響應(yīng)大小,對(duì)某些文件更可能高達(dá)90%,比Deflate更高效。主流 Web 服務(wù)器都有相應(yīng)模塊,而且絕大多數(shù)瀏覽器支持gzip解碼。所以,應(yīng)該對(duì)HTML、CSS、JS、XML、JSON等文本類型的內(nèi)容啟用壓縮。

注意!!! 圖片和 PDF 文件不要使用 gzip。它們本身已經(jīng)壓縮過,再使用 gzip 壓縮不僅浪費(fèi) CPU 資源,而且還可能增加文件體積。

從HTTP/1.1開始,web客戶端就有了支持壓縮的Accept-Encoding HTTP請(qǐng)求頭。

Accept-Encoding: gzip, deflate

如果web服務(wù)器看到這個(gè)請(qǐng)求頭,它就會(huì)用客戶端列出的一種方式來壓縮響應(yīng)。web服務(wù)器通過Content-Encoding響應(yīng)頭來通知客戶端。

Content-Encoding: gzip

4. 配置 Etag
實(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請(qǐng)求頭來把ETag傳回源服務(wù)器。如果ETags匹配成功,會(huì)返回一個(gè)304狀態(tài)碼,這樣就減少了12195個(gè)字節(jié)的響應(yīng)體。Etag 通過文件版本標(biāo)識(shí),方便服務(wù)器判斷請(qǐng)求的內(nèi)容是否有更新,如果沒有就響應(yīng) 304,避免重新下載。

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 

5. 盡早輸出(flush)緩沖
用戶請(qǐng)求頁面時(shí),服務(wù)器通常需要花費(fèi)200 ~ 500毫秒來組合 HTML 頁面。在此期間,瀏覽器處于空閑、等待數(shù)據(jù)狀態(tài)。使用PHP中的flush()函數(shù),可以發(fā)送部分已經(jīng)準(zhǔn)備好的 HTML到瀏覽器,以便服務(wù)器還在忙于處理剩余頁面時(shí),瀏覽器可以提前開始獲取資源。

可以考慮在</head>之后輸出一次緩沖,HTML head一般比較容易生成,先發(fā)送以便瀏覽器開始獲取<head>里引用的CSS等資源。

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

6. Ajax請(qǐng)求使用GET方法
瀏覽器執(zhí)行XMLHttpRequest POST請(qǐng)求時(shí)分成兩步,先發(fā)送Http Header,再發(fā)送data。而GET只使用一個(gè)TCP數(shù)據(jù)包(Http Header與data)發(fā)送數(shù)據(jù),所以首選GET方法。

根據(jù)HTTP規(guī)范,GET用于獲取數(shù)據(jù),POST則用于向服務(wù)器發(fā)送數(shù)據(jù),所以Ajax請(qǐng)求數(shù)據(jù)時(shí)使用GET更符合規(guī)范。

7. 避免圖片src為空
圖片src屬性值為空字符串可能以下面兩種形式出現(xiàn):

HTML:

<img src="" /> 

JavaScript:

var img = new Image(); 
img.src = ""; 

雖然src屬性為空字符串,但瀏覽器仍然會(huì)向服務(wù)器發(fā)起一個(gè)HTTP請(qǐng)求:

  • IE 向頁面所在的目錄發(fā)送請(qǐng)求;
  • Safari、Chrome、Firefox向頁面本身發(fā)送請(qǐng)求;
  • Opera不執(zhí)行任何操作。

空src產(chǎn)生請(qǐng)求的后果不容小覷:

  • 給服務(wù)器造成意外的流量負(fù)擔(dān),尤其時(shí)日 PV 較大時(shí);
  • 浪費(fèi)服務(wù)器計(jì)算資源;
  • 可能產(chǎn)生報(bào)錯(cuò)。

空的href屬性也存在類似問題。用戶點(diǎn)擊空鏈接時(shí),瀏覽器也會(huì)向服務(wù)器發(fā)送HTTP請(qǐng)求,可以通過JavaScript阻止空鏈接的默認(rèn)的行為。

三、Cookie

1. 減少 Cookie 大小
Cookie被用于身份認(rèn)證、個(gè)性化設(shè)置等諸多用途。Cookie通過HTTP頭在服務(wù)器和瀏覽器間來回傳送,減少Cookie大小可以降低其對(duì)響應(yīng)速度的影響。

  • 去除不必要的 Cookie;
  • 盡量壓縮 Cookie 大小;
  • 注意設(shè)置 Cookie 的 domain 級(jí)別,如無必要,不要影響到 sub-domain;
  • 設(shè)置合適的過期時(shí)間。

2. 靜態(tài)資源使用無Cookie域名
靜態(tài)資源一般無需使用Cookie,可以把它們放在使用二級(jí)域名或者專門域名的無Cookie服務(wù)器上,降低Cookie傳送的造成的流量浪費(fèi),提高響應(yīng)速度。

四、CSS

1. 把樣式表放在<head>中
把樣式表放在<head>中可以讓頁面漸進(jìn)渲染,盡早呈現(xiàn)視覺反饋,給用戶加載速度很快的感覺。

這對(duì)內(nèi)容比較多的頁面尤為重要,用戶可以先查看已經(jīng)下載渲染的內(nèi)容,而不是盯著白屏等待。

如果把樣式表放在頁面底部,一些瀏覽器為減少重繪,會(huì)在 CSS 加載完成以后才渲染頁面,用戶只能對(duì)著白屏干瞪眼,用戶體驗(yàn)極差。把樣式表放到文檔的HEAD部分能讓頁面看起來加載地更快。

2. 不要使用CSS表達(dá)式
CSS表達(dá)式可以在CSS里執(zhí)行JavaScript,僅IE5-IE7支持,IE8標(biāo)準(zhǔn)模式已經(jīng)廢棄。 CSS表達(dá)式超出預(yù)期的頻繁執(zhí)行,頁面滾動(dòng)、鼠標(biāo)移動(dòng)時(shí)都會(huì)不斷執(zhí)行,帶來很大的性能損耗。

3. 使用<link>替代@import
對(duì)于IE某些版本,@import的行為和放在頁面底部一樣。所以,不要用它。

4. 不要使用 filter
AlphaImageLoader為IE5.5-IE8專有的技術(shù),和CSS表達(dá)式一樣,放進(jìn)博物館吧。IE專有的AlphaImageLoader濾鏡可以用來修復(fù)IE7之前的版本中半透明PNG圖片的問題。在圖片加載過程中,這個(gè)濾鏡會(huì)阻塞渲染,卡住瀏覽器,還會(huì)增加內(nèi)存消耗而且是被應(yīng)用到每個(gè)元素的,而不是每個(gè)圖片,所以會(huì)存在一大堆問題。

注意!!!這里所說的不是 CSS3 Filter

五、Javasript

1. 把腳本放在頁面底部
瀏覽器下載腳本時(shí),會(huì)阻塞其他資源并行下載,即使是來自不同域名的資源。因此,最好將腳本放在底部,以提高頁面加載速度。

一些特殊場景無法將腳本放到頁面底部的,可以考慮<script>的以下屬性:

  • defer 屬性;
  • HTML5 新增的async屬性。

2. 使用外部JavaScript和CSS
外部JavaScript和CSS文件可以被瀏覽器緩存,在不同頁面間重用,也能降低頁面大小。

當(dāng)然,實(shí)際中也需要考慮代碼的重用程度。如果僅僅是某個(gè)頁面使用到的代碼,可以考慮內(nèi)嵌在頁面中,減少HTTP請(qǐng)求數(shù)。另外,可以在首頁加載完成以后,預(yù)先加載子頁面的資源。

3. 壓縮JavaScript和CSS
壓縮代碼可以移除非功能性的字符(注釋、空格、空行等),減少文件大小,提高載入速度。

得益于Node.js的流行,開源社區(qū)涌現(xiàn)出許多高效、易用的前端優(yōu)化工具,JavaScript 和CSS壓縮類的,不敢說多如牛毛,多入雞毛倒是一點(diǎn)不夸張,如[UglifyJS 2] (github.com/mishoo/Ugli…)、csso、cssnano 等。

對(duì)于內(nèi)嵌的CSS和JavaScript,也可以通過htmlmin等工具壓縮。

這些項(xiàng)目都有Gulp、Webpack等流行構(gòu)建工具的配套版本。

4. 移除重復(fù)腳本
重復(fù)的腳本不僅產(chǎn)生不必要的HTTP請(qǐng)求,而且重復(fù)解析執(zhí)行浪費(fèi)時(shí)間和計(jì)算資源。

5. 減少DOM操作
JavaScript 操作 DOM 很慢,尤其是 DOM 節(jié)點(diǎn)很多時(shí)。

使用時(shí)應(yīng)該注意:

  • 緩存已經(jīng)訪問過的元素;
  • 使用DocumentFragment暫存DOM,整理好以后再插入DOM樹;
  • 操作className,而不是多次讀寫style;
  • 避免使用JavaScript修復(fù)布局。

6. 使用高效的事件處理

  • 減少綁定事件監(jiān)聽的節(jié)點(diǎn),如通過事件委托;
  • 盡早處理事件,在DOMContentLoaded即可進(jìn)行,不用等到load以后。

六、圖片

1. 優(yōu)化圖片
嘗試把GIF格式轉(zhuǎn)換成PNG格式,看看是否節(jié)省空間。在所有的PNG圖片上運(yùn)行pngcrush(或者其它PNG優(yōu)化工具)。

YDN列出的相關(guān)工具缺乏易用性,建議參考以下工具

  • imagemin
  • imageoptim.com

TODO:

  • PNG 終極優(yōu)化;
  • Webp 相關(guān)內(nèi)容;
  • SVG 相關(guān)內(nèi)容。

PNG終極優(yōu)化

  • Most Effective Method to Reduce and Optimize PNG Images
  • Clever PNG Optimization Techniques

2. 優(yōu)化CSS Sprite

  • 水平排列Sprite中的圖片,垂直排列會(huì)增加圖片大小;
  • Spirite中把顏色較近的組合在一起可以降低顏色數(shù),理想狀況是低于256色以適用PNG8格式;
  • 不要在Spirite的圖像中間留有較大空隙。減少空隙雖然不太影響文件大小,但可以降低用戶代理把圖片解壓為像素圖的內(nèi)存消耗,對(duì)移動(dòng)設(shè)備更友好。

3. 不要在HTML中縮放圖片
不要使用<img>的width、height縮放圖片,如果用到小圖片,就使用相應(yīng)大小的圖片。如果需要

<img width="100" height="100" src="mycat.jpg" alt="My Cat" /> 

那么圖片本身(mycat.jpg)應(yīng)該是100x100px的,而不是去縮小500x500px的圖片。

很多 CMS 和 CDN 都提供圖片裁切功能。

補(bǔ)充:設(shè)置圖片的寬和高,以免瀏覽器按照「猜」的寬高給圖片保留的區(qū)域和實(shí)際寬高差異,產(chǎn)生重繪。

4. 使用體積小、可緩存的favicon.ico
Favicon.ico一般存放在網(wǎng)站根目錄下,無論是否在頁面中設(shè)置,瀏覽器都會(huì)嘗試請(qǐng)求這個(gè)文件。

所以確保這個(gè)圖標(biāo):

  • 存在(避免 404);
  • 盡量小,最好小于 1K;
  • 設(shè)置較長的過期時(shí)間。

對(duì)于較新的瀏覽器,可以使用PNG格式的favicon。

七、移動(dòng)端

1. 保證所有組件都小于25K
這個(gè)限制是因?yàn)閕Phone不能緩存大于25K的組件,注意這里指的是未壓縮的大小。這就是為什么縮減內(nèi)容本身也很重要,因?yàn)閱渭兊膅zip可能不夠。

2. 打包內(nèi)容為分段(multipart)文檔
把各個(gè)組件打包成一個(gè)像有附件的電子郵件一樣的復(fù)合文檔里,可以用一個(gè)HTTP請(qǐng)求獲取多個(gè)組件(記住一點(diǎn):HTTP請(qǐng)求是代價(jià)高昂的)。用這種方式的時(shí)候,要先檢查用戶代理是否支持(iPhone就不支持)。

總結(jié)

寫到這里,雅虎的35條軍規(guī)算是介紹完了。條目雖然很多,但經(jīng)過分類,可以發(fā)現(xiàn),性能優(yōu)化主要切入點(diǎn)可以從以下幾個(gè)方面去考慮:

  • 資源本身大小的壓縮優(yōu)化(想辦法減少資源的體積)
  • 網(wǎng)絡(luò)請(qǐng)求的全過程(從url地址欄輸入發(fā)送請(qǐng)求開始到返回響應(yīng)包的每個(gè)環(huán)節(jié))
  • 瀏覽器渲染的全過程(拿到資源后瀏覽器渲染的每個(gè)環(huán)節(jié))
    因此,要徹底掌握優(yōu)化的方法,必須對(duì)http請(qǐng)求的全過程以及瀏覽器的渲染全過程都有深入的理解。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容