爲你從新系統梳理下, Web 體驗優化中和圖有關的那些事(萬字長文)

本文首發於政採雲前端團隊博客 : 爲你從新系統梳理下, Web 體驗優化中和圖有關的那些事(萬字長文)

Web 頁面性能優化,解決了圖片相關,問題就解決了大半。本文從 Web 常見的圖片格式入手,引出與圖片優化相關的有效方案,指望對你們能有一點幫助。javascript

先來點背景知識

注:以下說明整理於網絡公開信息。

◎ 名詞解釋

  • 有損壓縮:藉由將次要的信息數據捨棄,犧牲一些質量來減小數據量、提升壓縮比。這個過程是不可逆的。圖片常見的有損壓縮手段是合併相近的像素點。
  • 無損壓縮:數據通過壓縮後,信息不受損失,還能夠徹底恢復到壓縮前的樣子。無損壓縮技術通常是經過兩個步驟來完成:css

    • 產生輸入數據的統計模型。
    • 利用這個統計模型將較常出現的數據用較短的比特序列表示,較不常出現的數據用較長的比特序列表示。
  • 索引色(Indexed Color):一個字節 2^8 表示一個顏色,也就是最多支持 256 種顏色。
  • 直接色(Direct Color):4 個數字表示一個顏色,分別表示紅、黃、藍以及透明度,因此最多能夠表達 2^32 種顏色。
  • 位圖(Bitmap):又叫柵格圖、點陣圖,使用像素陣列來表示圖像。位圖就是由象素陣列的排列來實現其顯示效果的,每一個象素有本身的顏色信息,在對位圖圖像進行編輯操做的時候,可操做的對象是每一個象素,咱們能夠改變圖像的色相、飽和度、明度,從而改變圖像的顯示效果。位圖根據位深度,有 一、四、八、1六、2四、32 位圖像等。位圖放大會失真變模糊。
  • 矢量圖:計算機圖形學中用點、直線或者多邊形等基於數學方程的幾何圖元表示圖像。相比較位圖,矢量圖保存最少的信息,體積更小,縮放不會失真。
  • 通道:RGB 三種顏色信息稱爲紅通道、綠通道、藍通道,透明度是 Alpha 通道。

◎ Web 中經常使用圖格式說明

  • JPEG/JPG:使用 JPEG 格式壓縮的圖片文件,是目前應用最普遍的圖片格式之一。最廣泛被使用的擴展名格式爲.jpg,其餘經常使用的擴展名還包括 .jpeg、.jpe、.jfif 以及 .jif。聯合圖像專家小組(Joint Photographic Experts Group)1992 年發佈 JPEG 壓縮標準,1994 年得到 ISO10918-1 認證。其特色是有損壓縮,直接色,位圖,體積最小,經常使用於顏色較豐富、無透明要求的圖片。
  • PNG:PNG 是一種無損壓縮的位圖圖形格式,支持索引、灰度、RGB 三種顏色方案以及 Alpha 通道等特性。PNG 的開發目標是改善並取代 GIF 做爲適合網絡傳輸的格式而不需專利許可。名稱由來一個是 Portable Network Graphics(便攜式網絡圖形),還有一個非正式的由來是 "Png is Not Gif"。使用場景是帶有透明、半透明背景的圖片,須要在網絡傳輸中顯示預覽效果後展現全貌。上古時期的 IE6 不支持 PNG 半透明,須要用 hack 方法解決。PNG 體積比較大,非必須可用 JPG 替代。PNG 有 png八、png2四、png32 之分。html

    • png8: 最多支持 256 色的 PNG,無損、索引色的位圖。非動圖能夠替代 GIF,體積更小,透明度支持也更好。
    • png24: 最多支持 2^24 色的 PNG,不支持透明,無損、直接色的位圖。目標是替換 JPG,但通常來講,相同顯示效果,PNG 圖片是 JPG 體積的數倍。
    • png32: 加上 8 位 Alpha 通道的 png24。(注:PS 中導出圖片時選擇 png24,勾選透明度,導出的是png32)。
  • GIF:圖像互換格式(Graphics Interchange Format)是一種位圖圖形文件格式,無損壓縮、索引色。原始版本爲 87a,1989 年發佈 89a 版本,支持多幀動畫和透明色。1995 年 Netscape Navigator 2.0 發佈,定義了動畫循環多少次或是否無限次播放,如今聊天的動圖都是基於該版本的 GIF。GIF 的特性以下:前端

    • 優秀的 LZW 算法在保證質量的同時將體積變的更小。
    • 可插入多幀實現動畫效果。
    • 可實現透明效果。
    • 最多支持 256 色,故不適用於真彩色圖片。
  • WebP:Google 2010 年發佈的同時支持有損和無損壓縮的圖片文件格式。有損用來替換 JPG,無損用來替換PNG,動態用來替換 GIF。根據 Google 較早的測試,WebP 的無損壓縮比網絡上找到的 PNG 檔少了 45% 的文件大小,即便這些 PNG 檔在使用 PngcrushPNGOUT 處理過,WebP 仍是能夠減小近 30% 的文件體積。WebP 目前還不能全平臺兼容,相關兼容性可點此連接查看。
  • SVG:可縮放矢量圖形(Scalable Vector Graphics)是一種基於可擴展編輯語言(XML),用於描述二維矢量圖形的圖形格式。SVG 由 W3C 制定,是一個開放標準。SVG 的優勢是文件可讀,易於修改編輯。支持多種濾鏡和特殊效果,在不改變圖像內容的前提下能夠實現位圖中相似文字陰影的效果,還能夠生成動態圖形。

圖優化之請求優化

◎ 擁抱 HTTP2

更快、更簡單、更穩定是咱們每個前端工程師的追求,HTTP/2 的出現讓這些美好的詞彙都匯聚在一塊兒。首先來一個 demo 感覺一下牛逼哄哄的 HTTP/2,HTTP/1.1 vs HTTP/2vue

二進制分幀層

HTTP/2 全部性能加強的核心在於新的二進制分幀層,它定義瞭如何封裝 HTTP 消息並在客戶端與服務器之間傳輸。java

HTTP/2 二進制分幀層

從這張圖比較清晰地看出 HTTP/1.x 和 HTTP/2的區別。HTTP/1.x 協議以換行符做爲純文本的分隔符,而 HTTP/2 將全部傳輸的信息分割爲更小的消息和幀,並採用二進制格式對它們編碼。react

服務器端推送

通常狀況下,客戶端須要啥東西會告訴服務端,而後服務端返回對應的資源到客戶端。HTTP/2 新增的另外一個強大的新功能是,服務器能夠對一個客戶端請求發送多個響應。換句話說,服務端能夠先於客戶端檢測到將要請求的資源,提早推送到客戶端,不發送全部資源的實體,只發送資源的 URL。客戶端接到後會進行驗證緩存,若是發現須要這些資源,則正式發起請求。webpack

標頭壓縮

每一個 HTTP 傳輸都承載一組標頭,這些標頭說明了傳輸的資源及其屬性。在 HTTP/1.x 中,這些元數據始終以純文本形式,一般會給每一個傳輸增長 500–800 字節的開銷。若是使用 HTTP Cookie,增長的開銷有時會達到上千字節。 爲了減小此開銷和提高性能,HTTP/2 使用 HPACK 壓縮格式壓縮請求和響應標頭元數據,這種格式採用兩種簡單可是強大的技術:ios

  • 支持經過靜態霍夫曼代碼對傳輸的標頭字段進行編碼,從而減少了各個傳輸的大小。
  • 客戶端和服務端之間同時維護和更新一個包含以前見過的標頭字段的索引列表(換句話說,它能夠創建一個共享的壓縮上下文),對相同請求而言不須要再次發送和相應,好比 User-Agent。

在 HTTP/2 中,請求和響應標頭字段的定義保持不變,僅有一些微小的差別:全部標頭字段名稱均爲小寫,請求行如今拆分紅各個 :method:scheme:authority:path 僞標頭字段。git

HPACK:HTTP/2 的標頭壓縮

◎ 多路複用

每一個 TCP 鏈接只能發送一個請求, HTTP/1.x 在前面的請求沒有完成前,後面的請求將會阻塞。

其實在 HTTP/2 以前,咱們在寫代碼的時候也用過相似的思想,好比

  • 合併 CSS 和 JS 代碼
  • 雪碧圖
  • Iconfont

HTTP/2 Multiplexing

HTTP/2 的出現又可讓咱們省掉很多麻煩。多路複用容許同時經過單一的HTTP請求多個響應。

◎ 少不了的懶加載

什麼是懶加載?

只加載可視區的內容,當頁面向下滾動時,再繼續加載後面的內容。

圖片懶加載的原理其實很是簡單,咱們先不設置圖片的 src 屬性,將圖片的真實路徑放到一個瀏覽器不認識的屬性中(好比 data-src),而後咱們去監聽 scroll 事件。當頁面的 scrollTop 與瀏覽器的高度之和大於圖片距頁面頂端的 Y (注意是整個頁面不是瀏覽器窗口)時,說明圖片已經進入可視區域,這是把 data-src 的值放到 src 中便可。 

爲何要使用懶加載?

  • 對於大多數用戶,特別是移動端和網速比較的用戶,若是首屏加載過多的圖片,頁面將會加載得很慢並且浪費用戶的流量。
  • Javascript 腳步一般要等到 DOM 加載完後纔會執行,若是加載的資源過多,可能會影響網頁的正常使用。
  • 可以節省流量和減輕服務器壓力,更近一步就是可以爲公司省成本。

怎麼實現?

關於如何實現本文不作過多闡述,成熟的方案社區比比皆是。這邊推薦幾個比較好用的輪子。

安裝

npm install --save lozad

使用

<img class="lozad" data-src="image.png" />
const observer = lozad(); // 默認會去找 .lozad 這個class
observer.observe();

安裝

npm i vue-lazyload -S

使用

Vue.use(VueLazyload)

用高階組件去包裹

安裝

npm install --save react-lazyload

使用

import React from 'react';
import ReactDOM from 'react-dom';
import LazyLoad from 'react-lazyload';
import MyComponent from './MyComponent';

const App = () => {
  return (
    <div className="list">
      <LazyLoad height={200}>
        <img src="tiger.jpg" />
      </LazyLoad>
      <LazyLoad>
        <MyComponent />
      </LazyLoad>
    </div>
  );
};

ReactDOM.render(<App />, document.body);

◎ 正確使用緩存

緩存是一種保存資源副本並在下次請求時直接使用該副本的技術,所以使用HTTP緩存是WEB性能優化中必不可少的,也是每位前端開發工程師的必修課。

HTTP 請求

瀏覽器和服務器之間使用的緩存策略能夠分爲強緩存、協商緩存兩種:

  • 強緩存:在緩存數據未失效的狀況下,不須要再和服務器發生交互
  • 協商緩存:須要與服務端校驗是否使用緩存

ETag

有這樣一種場景,瀏覽器檢查本地緩存找到以前響應的文件發現已通過期,只能去服務端請求,可是服務器的資源沒有發生變化,能夠說是浪費了一次請求。

Etag的出現很好地解決了這個問題,其爲一個哈希值,瀏覽器甚至不用去關係這個值是怎麼來的,在第一次請求時,瀏覽器生成Etag併發送到服務端。瀏覽器下一次請求時發現這個值未變,就跳過請求。

HTTP Cache-Control 示例

瀏覽器自動在 If-None-Match HTTP 請求頭內提供 ETag。 服務器根據當前資源覈對令牌,若是它未發生變化,服務器將返回 304 Not Modified 響應。這樣一個來回避免了瀏覽器再次去請求資源,即省錢又省時間。

Cache-Control

Cache-Control是強緩存的一種,每一個資源均可經過 Cache-Control 定義其緩存策略,Cache-Control來控制誰能夠緩存、緩存多久。

無需和服務端通訊的請求是最佳的,經過本地副本消除全部網絡延遲、節省流量。

Cache-Control 是在 HTTP/1.1 規範中定義的,取代了以前用來定義響應緩存策略的頭部(例如 Expires)。 全部現代瀏覽器都支持 Cache-Control,所以,用他就足夠了。

HTTP Cache-Control 示例

指令 說明
max-age 指令指定從請求的時間開始,容許提取的響應被重用的最長時間(單位:秒
private 只爲單個用戶緩存,不容許任何中間緩存對其進行緩存
no-cache 先與服務器確認返回的響應是否發生了變化,走協商緩存
no-store 禁止瀏覽器以及全部中間緩存存儲任何版本的返回響應

緩存 CheckList

實際開發中每每不存在什麼固定的最優解,咱們須要根據不一樣的業務場景制定相應的策略。

  • 變與不變 一些不變的部分,如第三方庫的代碼,能夠考慮和業務代碼分離,這樣一來能夠減小下載資源的大小
  • 最佳的緩存週期 不一樣的資源可能有不一樣的更新要求,設置合適的max-age
  • Etag 當服務器上的資源未發生變更時不須要請求

◎ 雪碧圖

雪碧圖,CSS Sprites,國內也叫 CSS 精靈,是一種 CSS 圖像合成技術,主要用於小圖片顯示。

使用場景

在網頁中,爲了更好的展示效果,常常會採用一些小圖標來替代文字。經常使用的方式包括 Icon Fonts、SVG Icons、小圖片,其中 Icon Fonts 只支持單色,SVG Icons 需 IE9+。

注:如不考慮低版本瀏覽器兼容性,推薦使用 SVG Icons,有興趣能夠閱讀 張鑫旭-SVG Sprites技術介紹

若是採用小圖片,須要考慮一個問題:每張小圖片獨立請求,加載時都會產生一個 HTTP 請求,而小圖片體積(1 ~ 2 kb)就比較小,對比上 HTTP 請求鏈接、請求頭內容、響應等的開銷,就顯得很是不必了,那有沒有可能將多張小圖片合併成一張圖?

實現原理

將小圖標合併成一張圖片,利用 backround-position 屬性值來肯定圖片呈現的位置便可。以下圖所示不一樣尺寸、位置:

圖片

經過 CSS 定位,能夠展示對應的圖標。

.icon-alipay {
  background-image: url(sprite.png);
  background-position: 0px -131px;
  width: 81px;
  height: 73px;
}
.icon-taobao {
  background-image: url(sprite.png);
  background-position: -177px 0px;
  width: 114px;
  height: 114px;
}
.icon-wechat {
  background-image: url(sprite.png);
  background-position: 0px 0px;
  width: 177px;
  height: 131px;
}
.icon-xinlang {
  background-image: url(sprite.png);
  background-position: -81px -131px;
  width: 72px;
  height: 72px;
}

自動生成

每次修改或者新增圖片時,都須要對雪碧圖進行修改,若是依靠人工維護,成本過高,可否自動生成雪碧圖和樣式呢?可使用 spritesmith,該工具可自動合併圖片,並獲得圖片在合併以後的相對位置。簡單使用示例代碼以下:

const fs = require('fs')
const path = require('path');
const Spritesmith = require('spritesmith');

const baseDir = './images';
const files = fs.readdirSync(baseDir)
const sprites = files.map(file => path.join(baseDir, file))

Spritesmith.run({src: sprites}, (err, result) => {
  if (err) {
    console.error(err)
  } else {
    console.info(result);
  }
})

運行的輸出結果以下:

{
  coordinates: {
    'images/alipay.png': { x: 0, y: 131, width: 81, height: 73 },
    'images/taobao.png': { x: 177, y: 0, width: 114, height: 114 },
    'images/wechat.png': { x: 0, y: 0, width: 177, height: 131 },
    'images/xinlang.png': { x: 81, y: 131, width: 72, height: 72 }
  },
  properties: { width: 291, height: 204 },
  image: <Buffer 89 50 4e 47 0d 0a 1a 0a 00 00 00 0d 49 48 44 52 00 00 01 23 00 00 00 cc 08 06 00 00 00 38 45 c5 ce 00 00 40 06 49 44 41 54 78 01 ec c1 0b 98 e6 05 61 ... 22705 more bytes>
}

其中

  • coordinates:每張圖片對應的尺寸和位置
  • properties:生成的圖片尺寸
  • image:文件的Buffer,可用於生成圖片

對於現有的經常使用的構建工具,已有現成的插件可直接使用:

  1. webpack-spritesmith
  2. gulp.spritesmith
  3. grunt-spritesmith

如下爲 gulp 配合 gulp.spritesmith 的示例代碼:

const gulp = require('gulp');
const spritesmith = require('gulp.spritesmith');

// gulp任務定義
gulp.task('sprite', () => {
  return gulp.src('images/*.png')
    .pipe(spritesmith({
        imgName: 'sprite.png',
        cssName: 'sprite.css'
      })
    ).pipe(gulp.dest('./'));
});

運行後會獲得sprite.pngsprite.css 兩個文件,最後打包的時候將文件對應打包進去便可。

注意事項

  1. 若是要適配高清屏,須要配置高清屏的圖片,而且經過設置background-size屬性來使得最終顯示正常,可參考以上插件的retina相關配置參數;
  2. 因爲 HTTP/2 的支持多路複用特性,使得單個圖片的請求的開銷很小,不推薦使用雪碧圖了,但爲了兼容 HTTP1.1,現階段多版本HTTP 協議並存期間仍是建議保留;
  3. 雪碧圖好用,可不要濫用。

◎ 使用 iconfont

iconfont 譯爲字體圖標,即經過字體的方式展現圖標,多用於渲染圖標、簡單圖形、特殊字體等。

使用 iconfont 時,因爲只須要引入對應的字體文件,針對加載圖片張數較多的狀況,可有效減小 HTTP 請求次數,並且通常字體體積較小,因此請求傳輸數據量較少。與直接引入圖片不一樣,iconfont 能夠像使用字體同樣,設置大小和顏色,還能夠經過 CSS 設置特殊樣式,且由於其是矢量圖,不存在失真的狀況。

那麼,怎麼使用 iconfont 呢?請參照如下 demo:

根據開發需求,按需引入不一樣格式的字體文件(eot / ttf / woff / svg)
<style>
  @font-face {
    font-family: "iconfont";
    src: url('iconfont.eot'); /* IE9*/
    src: url('iconfont.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
         url('iconfont.woff') format('woff'),
         url('iconfont.ttf') format('truetype'), /* chrome, firefox, opera, Safari,  Android, iOS 4.2+*/
         url('iconfont.svg?#iconfont') format('svg'); /* iOS 4.1- */
  }

  .iconfont {
    font-family: "iconfont";
  }
</style>

<body>
  // &#xe609 是一個字符的 unicode 碼,在該 iconfont 字體文件中對應某個圖標
  <i class="iconfont">&#xe609</i> 
</body>

關於 @font-face 的說明可參考 mozilla 官方文檔

在平時開發工做中,可以使用如下經常使用圖標字體庫:

◎ 使用 Base64

Base64 是網絡上最多見的用於傳輸 8Bit 字節碼的編碼方式之一,可將圖片編碼爲特定的字符串,由 52 個大小字母和 10 個數字,以及 +、/、= 三個字符組成,詳見 wiki.

使用 Base64 編碼渲染圖片有如下優勢:

  • 有效減小 HTTP 請求次數
  • 可對數據進行簡單加密,沒法肉眼獲取信息
  • 沒有跨域問題,無需考慮圖片緩存

凡事皆有利弊,使用 Base64 編碼同時也會帶來一些問題:

  • 編碼後文件體積增大,僅適用於小體積圖片編碼
  • 增長了編碼和解碼的工做量
  • 不支持 IE 8.0 如下版本

如需將圖片轉換爲 Base64 編碼,可使用 JavaScript API FileReader.readAsDataURL ,詳細可參考文檔

圖優化之體積優化

圖片體積壓縮就是在圖片保持在可接受的清晰度範圍內同時減小文件大小,圖片體積壓縮能夠藉助工具實現。

◎ 在線工具

  • TinyPNG:免費,TinyPng 使用智能有損壓縮技術減少 PNG 文件的文件大小,原理是將圖片中類似的顏色組合起來(量化),經過減小顏色的數量,能夠將 24 位 PNG 文件轉爲更小的 8 位索引圖片,同時全部沒必要要的元數據被剝離。
  • PP鴨:¥69.9,很好用,根據圖片的特色,選擇比較兼顧大小和質量的壓縮方案。
  • 智圖:免費,能夠選擇壓縮質量,生成 Webp。
  • Iloveimg:免費,支持壓縮 JPG,PNG, GIF, 能保持最佳文件質量和壓縮程度, 而且 Iloveimg 不只僅是一款圖片壓縮工具,還支持圖片的裁剪、圖片的格式轉換以及大小調整等功能。

◎ 客戶端工具

  • PhotoShop:只適用 JPG,導出時選擇 JPG,選擇壓縮質量。
  • Sketch:只適用 JPG,導出時選擇 JPG,選擇壓縮質量。

◎ 阿里雲 OSS

阿里雲 OSS 能夠經過配置參數形式對圖片進行處理,支持縮放、裁剪、旋轉、效果、格式轉換、水印等操做,詳細信息點此 文檔 查看。

示例:將圖強制縮略成寬度爲 100,高度爲 100。

http://image-demo.oss-cn-hangzhou.aliyuncs.com/example.jpg?x-oss-process=image/resize,m_fixed,h_100,w_100

本文做者之一@明明 亦作過一個小工具,經過配置縮放參數、壓縮質量、格式等屬性後自動生成 OSS 後綴地址,具體如何使用參考文檔

◎ 七牛雲

七牛雲的圖片處理服務和阿里雲 OSS 功能相似,也能夠對圖片進行縮放、裁剪、旋轉、縮略等操做,詳細文檔

示例:將圖強制縮略成寬度爲 100,高度爲 100。

https://odum9helk.qnssl.com/resource/Ship.jpg?imageView2/2/w/100/h/100

圖優化之格式、尺寸優化

◎ 圖片格式

Web 開發中常見的圖片包括 JPG,PNG,GIF,webP,選擇合適的格式以及壓縮質量能夠在保證視覺效果的狀況下,加速網站的呈現。下面針對不一樣圖片格式的特性來作一下對比:

類型 動畫 壓縮類型 瀏覽器支持 透明度
GIF 支持 無損壓縮 全部 支持
PNG 不支持 無損壓縮 全部 支持
JPEG 不支持 有損壓縮 全部 不支持
webP 不支持 無損壓縮或有損壓縮 Chrome、Opera、Firefox、Edge、Android 支持

回憶本文開頭介紹的不一樣圖片格式的特色,你們能夠參考下圖選擇合適的使用場景:

image

◎ 多倍圖

在 Retina 視網膜屏幕面世以前人們不多關注像素密度與設備像素比,隨着 Retina 屏在移動設備中愈來愈普遍地應用,爲了保證圖片在不一樣 DPR(設備像素比)的設備上顯示足夠清晰,開發者須要針對不一樣設備適配不一樣倍數的圖片。

像素相關概念

  • DP 設備像素,又名物理像素,即設備屏幕上真實的物理像素,以矩陣的形式排列,如 iphone X 屏幕分辨率爲 2436*1125,即屏幕每行包含 1125 個物理像素,每列包含 2436 個物理像素。
  • DIP 設備無關像素,是一種基於屏幕座標的抽象像素,應用程序以抽象像素爲單位,如咱們 CSS 中使用的 px,實際渲染時經過底層程序轉換爲物理像素。
  • DPR 設備像素比,設備像素 / 設備無關像素的值即爲設備像素比,在 Javascript 中能夠經過 window.devicePixelRatio 來獲取。

多倍圖概念

瞭解以上的概念,咱們不難理解:

  • 在 DPR 爲 1 的設備(一倍屏)上,使用 1 * 1 個物理像素展現一個 CSS 像素。
  • 在 DPR 爲 2 的設備(二倍屏)上,使用 2 * 2 個物理像素展現一個 CSS 像素。
  • 在 DPR 爲 3 的設備(三倍屏)上,使用 3 * 3 個物理像素展現一個 CSS 像素。

針對一張 30px 30px 的圖片,在 1 倍屏上,按照 1 : 1 平鋪,圖片質量並不損失。可是在 2 倍屏、3 倍屏上,分別經過 60 60 與 90 * 90 個物理像素渲染這張圖片就會出現模糊、失真的現象,從而影響用戶體驗。因此,咱們須要根據不一樣 DPR 去加載不一樣倍數的圖片:

  • 一倍屏上加載 30px * 30px 的圖片,咱們稱之爲一倍圖。
  • 二倍屏上加載 60px * 60px 的圖片,圖片名通常加上 @2x 標識,咱們稱之爲二倍圖。
  • 三倍屏上加載 30px * 30px 的圖片,圖片名通常加上 @3x 標識,咱們稱之爲三倍圖。

自適應 DPR 加載圖片

在高分辨率顯示屏如 2x 上,在頁面中使用二倍圖能夠保證清晰度,可是當此頁面在低 DPR 設備打開時,咱們只須要 50% 長寬的圖片就能保證顯示效果,而此時帶寬開銷倒是同樣的。因此爲了解約傳輸流量,咱們須要告訴瀏覽器,根於不一樣的 DPR 加載不一樣尺寸的圖片,一般有如下三種方法:

  1. 使用 picture 標籤,除了 IE,現有主瀏覽器均已支持該標籤,兼容性參考文檔)。
<picture>  
  <source srcset="photo@3x.jpg" media="(min-width: 800px)">  
  <source srcset="photo@2x.jpg" media="(min-width: 600px)">  
  <img srcset="photo.jpg">  
</picture>
  1. 使用 img srcset 屬性,除了 IE,現有主瀏覽器均已支持該屬性,兼容性參考文檔
<img src="photo.png" srcset="photo@2x.png 2x, photo@3x.png 3x" alt="photo" />
  1. 使用 CSS3 img-set 函數,兼容性相較於前二者較差,參考文檔)。
background-image: image-set("photo.png" 1x,
                            "photo@2x.png" 2x,
                            "photo@3x.png" 3x);

勿忘無障礙,關懷弱視力羣體

根據世界健康組織的統計,全球約有 2.85 億視力障礙人士,僅美國就有 810 萬網民患視力障礙,而在中國,這個數字要被乘以 2。不一樣於咱們瀏覽網頁的方式是看,視力障礙人員瀏覽互聯網信息主要是靠聽 —— 靠屏幕閱讀器讀出網頁的有效信息,經過聽這些信息來獲知內容。對於前端工程師而言,關注到一些細節的優化,能更好的服務於這些視力障礙人士。

◎ 設置 Alt 屬性

最基礎的方式,是裝飾性圖片歸類到背景圖,經過 CSS 背景圖進行設置;功能性圖片放到 HTML 中,經過 img 標籤引入,且要設置 alt 屬性,以便被屏幕閱讀器識別並閱讀。圖片 alt 信息應簡短,介紹圖片信息便可,避免內容冗餘。圖片的長信息介紹應被放到 longdesc 屬性中:

<img src="" alt="圖片說明" />
<img src="" longdesc="一段很長的文字一段很長的文字一段很長的文字一段很長的文字" />
  • 寬或高不到 8px 或者沒有 alt 的圖片(特別是裝飾性的圖片)應該被移除,CSS 技術能夠用來控制樣式
  • alt 是用來描述圖片的,而非單純的新聞標題或者名詞
  • alt 屬性不該包含圖片的文件名
  • alt 值不該包含冗長的信息(若是很長可使用<img longdesc="很長很長的內容很長很長的內容" />)
  • 每一個 img 標籤要應該設置 alt 屬性
  • 不能只依賴圖片上的文字信息
  • Banner、頭圖上的文字信息必須在代碼中有所體現

更多無障礙相關,可參考《騰訊網無障礙說明》。

◎ 考慮 IMG Sprite

「高對比度模式」 是一種 Windows 系統的設置主題,其用意是爲了保證視力受損的用戶,在查看 Web 信息時提供方便。它經過使用對比鮮明的色彩和字號來提升文本的可讀性,高對比度模式下網頁的背景默認會變成全黑。

CSS Image Sprites(CSS 雪碧圖)是一項用來減小網頁中圖片 HTTP 請求數的技術,但其會致使在 Windows 高對比度模式下背景圖片消失,其服務的 Web 應用性能的提高和對無障礙體驗被破壞之間的矛盾,已經引發了 Web 開發者的關注。Sprite 技術的使用的確爲更多網站的優化加載速度的體驗貢獻甚大,但咱們要認可,這個過程當中咱們忽略並損害了使用高對比度模式用戶的體驗。因爲 <img> 元素能夠在高對比度模式下顯示,故而在此場景下,使用基於 <img> 標籤的 Sprite 技術,能夠獲得比基於 CSS 背景圖的 Sprite 更多的收益。

關於 IMG Sprite 技術的應用,能夠在此文中學習到 《Foreground Sprites – High Contrast Mode Optimization

總結

就前端性能優化而言,圖片優化可謂是其必不可少的環節。可是與其說是在作優化,不如說是在作「權衡」。一些操做是以犧牲一部分紅像質量爲代價的。咱們的主要任務,是儘量的去尋求一個質量與性能之間的平衡點,並在不一樣業務場景下,作好圖片方案的選型工做。

更多閱讀:

招賢納士

政採雲前端團隊(ZooTeam),一個年輕富有激情和創造力的前端團隊,隸屬於政採雲產品研發部,Base 在風景如畫的杭州。團隊現有 50 餘個前端小夥伴,平均年齡 27 歲,近 3 成是全棧工程師,妥妥的青年風暴團。成員構成既有來自於阿里、網易的「老」兵,也有浙大、中科大、杭電等校的應屆新人。團隊在平常的業務對接以外,還在物料體系、工程平臺、搭建平臺、性能體驗、雲端應用、數據分析及可視化等方向進行技術探索和實戰,推進並落地了一系列的內部技術產品,持續探索前端技術體系的新邊界。

若是你想改變一直被事折騰,但願開始能折騰事;若是你想改變一直被告誡須要多些想法,卻無從破局;若是你想改變你有能力去作成那個結果,卻不須要你;若是你想改變你想作成的事須要一個團隊去支撐,但沒你帶人的位置;若是你想改變既定的節奏,將會是「5 年工做時間 3 年工做經驗」;若是你想改變原本悟性不錯,但老是有那一層窗戶紙的模糊… 若是你相信相信的力量,相信平凡人能成就非凡事,相信能遇到更好的本身。若是你但願參與到隨着業務騰飛的過程,親手推進一個有着深刻的業務理解、完善的技術體系、技術創造價值、影響力外溢的前端團隊的成長曆程,我以爲咱們該聊聊。任什麼時候間,等着你寫點什麼,發給 ZooTeam@cai-inc.com

相關文章
相關標籤/搜索