Web開發(fā)中圖片優(yōu)化的完全教程手冊

2015-02-16 06:44:13來源:wizcabbit作者:

圖片優(yōu)化既是一門藝術,也是一門科學,圖片優(yōu)化是一門藝術,是因為單個圖片的壓縮不存在最好的特定性方案,而圖片優(yōu)化之所以是一門科學,是因為許多開發(fā)得很出色的方法和算法可以明顯減小圖片的大小。

HTTP Archieve有個統(tǒng)計,圖片內容已經(jīng)占到了互聯(lián)網(wǎng)內容總量的62%,也就是說超過一半的流量和時間都用來下載圖片。從性能優(yōu)化的角度看,圖片也絕對是優(yōu)化的熱點和重點之一,Google PageSpeed或者Yahoo的14條性能優(yōu)化規(guī)則無不把圖片優(yōu)化作為重要的優(yōu)化手段,本文覆蓋了Web圖片優(yōu)化的方方面面,從基本的圖片格式選擇、到尚未被廣泛支持的響應式圖片均有所提及。

Google Web Fundamentals的說法我很喜歡:

圖片優(yōu)化既是一門藝術,也是一門科學,圖片優(yōu)化是一門藝術,是因為單個圖片的壓縮不存在最好的特定性方案,而圖片優(yōu)化之所以是一門科學,是因為許多開發(fā)得很出色的方法和算法可以明顯減小圖片的大小。要找到圖片的最優(yōu)設置,需要按照許多維度進行認真分析:格式能力、編碼數(shù)據(jù)內容、像素尺寸等。

傳送門:跳過理論直達自動優(yōu)化圖片 點這里

真的要用圖片嗎?

要實現(xiàn)需要的效果,真的需要圖片嗎?這是首先要問自己的問題。瀏覽器和Web標準的發(fā)展速度極快,記得數(shù)年前我在用微軟Silverlight 1.0寫視頻播放器的時候,中文還不能使用自定義字體顯示,所以那時候寫了很多糟糕的代碼把需要的文字在服務器上生成圖片并緩存起來。用戶下載起來很慢,搜索引擎也完全無法檢索這些文字。

但是現(xiàn)在不一樣了,很多特效(漸變、陰影、圓角等等)都可以用純粹的HTML、CSS、SVG等加以實現(xiàn),實現(xiàn)這些效果少則寥寥數(shù)行代碼,多則加載額外的庫(一張普通的照片比非常強大的效果庫也大了許多)。這些效果不但需要的空間很小,而且在多設備、多分辨率下都能很好的工作,在低級瀏覽器上也可以實現(xiàn)較好的功能降級。因此在存在備選技術的情況下,應該首先選擇這些技術,只有在不得不使用圖片的時候才加入真正的圖片。

備選技術

  • CSS效果、CSS動畫。提供與分辨率無關的效果,在任何分辨率和縮放級別都可以顯示得非常清晰,占用的空間也很小。
  • 網(wǎng)絡字體,F(xiàn)在連很多圖標庫都是用字體方式提供,保持文字的可搜索性同時擴展顯示的樣式。

前端工程師最好能和設計師、產(chǎn)品經(jīng)理保持溝通,幫助他們了解到什么樣的效果比較“簡潔、高效、可維護”,畢竟對于CSS來說改變圓角矩形的Radius可以實時看到效果,用圖片的話至少要重新生成圖片、切圖并替換資源。Retina、高分辨率屏幕、多尺寸的設備,這些都加快了非圖片特效的發(fā)展,想想在高分辨率屏幕下Windows 7的慘不忍睹,就知道原生的圖片資源絕對不是多多益善。

圖片格式的選擇

如果效果真的需要圖片來表現(xiàn),那么選擇圖片格式是優(yōu)化的第一步。我們經(jīng)常聽到的詞語包括矢量圖、標量圖、SVG、有損壓縮、無損壓縮等等,我們首先說明各種圖片格式的特點

圖片格式 壓縮方式 透明度 動畫 瀏覽器兼容 適應場景
JPEG 有損壓縮 不支持 不支持 所有 復雜顏色及形狀、尤其是照片
GIF 無損壓縮 支持 支持 所有 簡單顏色,動畫
PNG 無損壓縮 支持 不支持 所有 需要透明時
APNG 無損壓縮 支持 支持 Firefox
Safari
iOS Safari
需要半透明效果的動畫
WebP 有損壓縮 支持 支持 Chrome
Opera
Android Chrome
Android Browser
復雜顏色及形狀
瀏覽器平臺可預知
SVG 無損壓縮 支持 支持 所有(IE8以上) 簡單圖形,需要良好的放縮體驗
需要動態(tài)控制圖片特效

其中APNG和WebP格式出現(xiàn)的較晚,尚未被Web標準所采納,只有在特定平臺或瀏覽器環(huán)境可以預知的情況下加以采用,雖然均可以在不支持的環(huán)境中較好的功能降級,但本節(jié)暫不討論這兩種格式。圖片格式選擇過程如下:

image optim

顏色豐富的照片,JPG是通用的選擇

  • 人眼的結構很適合查看JPG壓縮后的照片,可以充分的忽略并在腦中補齊細節(jié)
  • JPG在壓縮率不高時保留的細節(jié)還是不錯的
  • WebP能夠比JPG減少30%的體積,但目前兼容性較差

如果需要較通用的動畫,GIF是唯一可用的選擇

  • GIF支持的顏色范圍為256色,而且僅支持完全透明/完全不透明
  • GIF在顯示顏色豐富的動畫時可能出現(xiàn)顏色不全、邊緣鋸齒等問題

如果圖片由標準的幾何圖形組成,或需要使用程序動態(tài)控制其顯示特效,可以考慮SVG格式

  • SVG是使用XML定義的矢量圖形,生成的圖片在各種分辨率下均可自由放縮
  • SVG中可以通過JavaScript等接口自由變換圖片特效,可以完成其中部分元素的自由旋轉、移動、變換顏色等

如果需要清晰的顯示顏色豐富的圖片,PNG比較好

  • PNG-8能夠顯示256種顏色,但能夠同時支持256階透明,因此顏色數(shù)較少但需要半透明的情景(如微信動畫大表情)可以考慮PNG-8
  • PNG-24可以顯示真彩色,但不支持透明,顏色豐富的圖片推薦使用(如屏幕截圖、界面設計圖)
  • PNG-32可以顯示真彩色,同時支持256階透明,效果最好但尺寸也最大

圖片尺寸的選擇

尺寸,曾經(jīng)是最不需要討論的話題,但自從Retina出現(xiàn)之后世界就變得復雜多了。關于移動設備上的像素和尺寸,展開說足夠寫一篇論文,我建議想詳細了解的同學參考下面的文章:

淺談移動Web開發(fā)(上):深入概念

這里只說我們關心的部分和結論,我們需要分清不同類型的像素:CSS像素和設備像素。一個 CSS像素可能包含多個設備像素。對于圖片來說,在高DPI的屏幕上需要使用分辨率更高的圖片,如果我們討論的是Retina,那么就需要2倍分辨率(幾乎4倍尺寸)的圖片。這幾乎沒有取巧的空間,屏幕就是那么大,需要的圖片也就是那么大。(鴿子為什么那么大?^_^)

kraken

我們能夠控制的地方是“恰好”顯示所需尺寸的圖片。例如在屏幕中通過CSS或者標簽的wihth/height屬性,將一副200x200的圖片調整為100x100大小,那么這其中就有(200x200)-(100x100)=30000個像素是浪費的,這占到了圖片尺寸的75%!

之所以有這么大的浪費,是因為圖片的尺寸與面積基本成正比,與寬高的平方成正比。因此良好的計算客戶端實際顯示的圖片尺寸,能夠大大減小圖片的大小。即使只有長和寬都只有10px被浪費,但是當圖片足夠大時,這部分也將產(chǎn)生很大影響。

響應式圖片

上面提到“恰好”顯示客戶端所需大小的圖片,聽上去很容易不是嗎?但當響應式布局出現(xiàn)后,這就變得極其困難。我們要支持上至1920寬度,下至320寬度的無數(shù)種設備,如果使用1920寬度的圖片,那么在小型設備(這類設備往往對網(wǎng)速和流量更加敏感)上每個用戶都要付出額外的帶寬和等待時間,如果使用320寬度的圖片,那么在1920的屏幕上就像是在高清屏上使用DOS那么讓人難以接受。

很自然的,我們需要圖片也能“響應式”加載,根據(jù)所在設備的不同,加載不同尺寸的圖片。響應式圖片尚沒有寫入Web標準,實現(xiàn)起來也有諸多不便和兼容性限制。我建議參考百度EFE團隊的這篇文章:

實戰(zhàn)響應式圖片

響應式圖片雖然尚未成為標準,但這是Web圖片優(yōu)化的一柄利器,一旦被廣泛支持,再沒有比縮小圖片尺寸更有效的優(yōu)化方法了。

優(yōu)化JPG和PNG

選擇了正確的圖片格式,按照正確的大小生成了圖片后,我們還需要對圖片進行進一步優(yōu)化,這種優(yōu)化一般分兩步進行:

  1. 有損優(yōu)化,刪除沒有出現(xiàn)或極少出現(xiàn)過的顏色,合并相鄰的相近顏色。這一步并不必須,如PNG格式就直接進入下一步
  2. 無損優(yōu)化,壓縮數(shù)據(jù),刪除不必要的信息

JPG和PNG格式的圖片生成后,一般還有進一步優(yōu)化的空間,例如JPG格式的照片中,可能攜帶有相機的Exif信息,PNG格式的圖片中可能帶有Fireworks等軟件的圖層信息等。去除這些額外信息后,還可以通過減小圖片的調色板,去除沒有出現(xiàn)過的顏色,以及合并相鄰的相同顏色等手段來進行優(yōu)化。原理性的內容這里不再贅述,僅介紹工程中可用的優(yōu)化工具。

不同格式的圖片有一系列工具,這些工具有有更多種參數(shù)調節(jié)方案,常見的幾種調節(jié)工具有:

工具 用途
jpegtran 優(yōu)化JPG圖片
OptiPNG 無損PNG優(yōu)化
AdvPNG 無損PNG優(yōu)化
PNGQuant 有損PNG優(yōu)化

如果你真的需要追求各種圖片的極限壓縮,可以參閱這些工具的文檔,但是對于一般的Web應用,面對的圖片種類多樣,幾乎不可能在工程中實現(xiàn)對每種工具的獨立配置,因此推薦使用以下工具來進行優(yōu)化。這些工具往往使用了上表中的一種或幾種優(yōu)化工具。

ImageOptim (Mac)

主頁:https://imageoptim.com/

Mac平臺下非常贊的圖片優(yōu)化工具,只需要把需要優(yōu)化的圖片拖拽進ImageOptim,就能夠完成對圖片的優(yōu)化。設置選擇的也很豐富,目前支持JPG和PNG的優(yōu)化。這是我在寫文章時最常用到的工具,把網(wǎng)站用到的圖片拖進去,優(yōu)化就完成了~

image optim

Kraken (Web)

主頁:https://kraken.io/

在免費模式下可以上傳圖片,優(yōu)化后打包下載,很多國外企業(yè)也選擇了它的收費服務。親自測試Kraken的圖片優(yōu)化結果比ImageOptim一般要小3%左右,效果不錯,當然價格也不錯。適合偶爾有圖片優(yōu)化需求,或者不在開發(fā)機上沒有優(yōu)化軟件可以使用的情況。

kraken

智圖 (Web)

主頁:http://zhitu.tencent.com/

騰訊ISUX團隊有篇文章介紹智圖:http://isux.tencent.com/zhitu.html

國貨當自強,騰訊的智圖工具推出不久,但實測效果很好,而且提供了Gulp的自動化支持,這部分會在后面自動優(yōu)化章節(jié)介紹。只想建議一句,Kraken的首頁比智圖美好幾百倍…… 而且把壓縮前的PNG和壓縮后的JPG放在一起對比大小,真的沒關系么~

kraken

優(yōu)化SVG

所有較新的瀏覽器都支持可縮放矢量圖(SVG),SVG是基于XML的圖片格式,適用于二維圖片。可以將SVG標記直接嵌入網(wǎng)頁,也可以作為外部資源嵌入?梢酝ㄟ^大多數(shù)基于矢量的繪圖軟件創(chuàng)建SVG文件。這是一段簡單的SVG圖形:

kraken

這個圓形輪廓為黑色,背景為紅色,從Adobe Illustrator直接導出。可以從中看到大量元數(shù)據(jù),例如圖層信息、注釋和XML名稱空間等等,在瀏覽器中呈現(xiàn)資源時,通常不需要這些數(shù)據(jù)。因此我們需要使用一些工具去除這些不必要的元數(shù)據(jù),僅保留必須的標記。

SVGO工具可以縮減SVG文件的體積,在這個的例子中,SVGO能夠將Illustrator生成的SVG文件大小減小58%,從470字節(jié)縮減到199字節(jié)。

由于SVG是基于XML的格式,本質上是純文本,所以,還可以采用GZIP壓縮來減小傳輸大小,當然這需要一些服務器配置,例如在apache服務器中設置:

AddType image/svg+xml .svg
AddOutputFilterByType DEFLATE image/svg+xml

來對SVG文件啟用GZip壓縮(當然你還需要先加載deflate模塊并進行適當配置,GZip的配置超出了本文的范疇,這部分內容請自行Google)

優(yōu)化GIF和APNG

GIF有很多好處,在顏色數(shù)較低的時候能夠大幅減小圖片體積,而且他也是唯一能夠較為通用的展示動畫的圖片格式。關于GIF格式的優(yōu)化原理我并不熟悉,只是在工程中直接使用成型的壓縮工具,在后文自動優(yōu)化章節(jié)的Grunt中,會介紹通過Grunt Task進行自動優(yōu)化的方法。

關于APNG,目前瀏覽器對他的支持還不夠好,不過在支持HTML5的場景中,有成熟的開源工具apng-canvas可以用于支持APNG。

kraken

騰訊ISUX團隊有篇文章介紹iSparta工具:http://isux.tencent.com/introduction-of-apng.html。這是目前幾乎唯一能夠批量處理APNG文件的工具,感興趣的同學可以在那篇文章里得到更多地了解。

自動優(yōu)化

前面說了太多關于如何優(yōu)化各種不同格式圖片的方法和工具,優(yōu)化圖片需要大量重復性的勞動,作為工程師顯然不會忍受這一點,因此也產(chǎn)生出了很多工具對圖片進行自動優(yōu)化,這里主要介紹CDN、Grunt/Gulp、Google PageSpeed三種方式。

自動優(yōu)化:CDN

使用CDN對圖片自動進行優(yōu)化,我在國外的CDN提供商處很少見到這類服務,倒是國內的兩大新秀CDN七牛又拍在這方面都做了大量工作。其工作方式為,向CDN請求圖片的URL參數(shù)中包含了圖片處理的參數(shù)(格式、寬高等),CDN服務器根據(jù)請求生成所需的圖片,發(fā)送到用戶瀏覽器。

七牛云存儲的圖片處理接口極其豐富,覆蓋了圖片的大部分基本操作,例如:

  • 圖片裁剪,支持多種裁剪方式(如按長邊、短邊、填充、拉伸等)
  • 圖片格式轉換,支持JPG, GIF, PNG, WebP等,支持不同的圖片壓縮率
  • 圖片處理,支持圖片水印、高斯模糊、重心處理等

七牛云存儲的圖片處理接口使用并不復雜,例如下面這張原圖:

\

我們通過如下URL請求,裁剪正中部分,等比縮小生成200x200縮略圖:

http://qiniuphotos.qiniudn.com/gogopher.jpg?imageView2/1/w/200/h/200

\

自動優(yōu)化:Grunt/Gulp

這里介紹用于圖片優(yōu)化的Grunt組件:grunt-image。前端工程師的重復性工作,例如合并靜態(tài)資源、壓縮JS和CSS文件、編譯SASS等都可以使用Grunt等自動化工具批量完成,圖片優(yōu)化也是如此。

grunt-image非常強大,按照作者的介紹,其內部加載的圖片優(yōu)化工具包括了pngquant, optipng, advpng, zopflipng, pngcrush, pngout, mozjpeg, jpegRecompress, jpegoptim, gifsicle和svgo。支持批量自動優(yōu)化PNG, JPG, SVG和GIF,速度也不錯,配置方式支持單圖片優(yōu)化和全目錄優(yōu)化:

module.exports = function (grunt) {
  grunt.initConfig({
    image: {
      // 指定單獨的圖片優(yōu)化
      static: {
        options: {
          pngquant: true,
          optipng: true,
          advpng: true,
          zopflipng: true,
          pngcrush: true,
          pngout: true,
          mozjpeg: true,
          jpegRecompress: true,
          jpegoptim: true,
          gifsicle: true,
          svgo: true
        },
        files: {
          'dist/img.png': 'src/img.png',
          'dist/img.jpg': 'src/img.jpg',
          'dist/img.gif': 'src/img.gif',
          'dist/img.svg': 'src/img.svg'
        }
      },
      // 指定圖片目錄進行優(yōu)化
      dynamic: {
        files: [{
          expand: true,
          cwd: 'src/',
          src: ['**/*.{png,jpg,gif,svg}'],
          dest: 'dist/'
        }]
      }
    }
  });

  grunt.loadNpmTasks('grunt-image');
};

web image optimization

自動優(yōu)化:Google PageSpeed

Google做事風格比較徹底,看見哪個軟件不好用就拿來直接fork出新版本或者干脆重寫,對于Web優(yōu)化,Google發(fā)布了了Google PageSpeed這個服務器模塊,可以在apache或ngnix中加載,通過在服務器配置文件中進行設置來進行自動化的優(yōu)化。對于圖片格式轉換、圖片優(yōu)化甚至圖片LazyLoad都有相關選項。這部分展開會非常長,請感興趣的同學參考Google的手冊。

參考鏈接

題圖來自:http://www.curata.com/blog/optimizing-your-content-marketing-with-secrets-exposed-in-recent-google-patent/