WebP格式,谷歌開發的一種旨在加快圖片加載速度的圖片格式。圖片壓縮體積大約只有JPEG的2/3,並能節省大量的服務器寬帶資源和數據空間。php
一、減少圖片加載資源的大小、節省用戶流量資源
二、下降服務器流量資源css
圖片壓縮結果,使用webp圖片格式後的圖片資源大幅度減少。html
結果:谷歌全面支持、安卓瀏覽器從4.2開始支持。那麼在頁面中對於安卓用戶中圖片資源加載大小會有大幅度降低。前端
淘寶中大量使用webp。html5
cdn
各大cdn也是支持webp圖片格式輸出。java
實踐中對h5活動頁採用webp圖片加載方案。h5 頁面查看地址: http://webp.leewr.comnode
一、經過js瀏覽器端判斷是否支持webpwebpack
function check_webp_feature(feature, callback) { var kTestImages = { lossy: "UklGRiIAAABXRUJQVlA4IBYAAAAwAQCdASoBAAEADsD+JaQAA3AAAAAA", lossless: "UklGRhoAAABXRUJQVlA4TA0AAAAvAAAAEAcQERGIiP4HAA==", alpha: "UklGRkoAAABXRUJQVlA4WAoAAAAQAAAAAAAAAAAAQUxQSAwAAAARBxAR/Q9ERP8DAABWUDggGAAAABQBAJ0BKgEAAQAAAP4AAA3AAP7mtQAAAA==", animation: "UklGRlIAAABXRUJQVlA4WAoAAAASAAAAAAAAAAAAQU5JTQYAAAD/////AABBTk1GJgAAAAAAAAAAAAAAAAAAAGQAAABWUDhMDQAAAC8AAAAQBxAREYiI/gcA" }; var img = new Image(); img.onload = function () { var result = (img.width > 0) && (img.height > 0); callback(feature, result); }; img.onerror = function () { callback(feature, false); }; img.src = "data:image/webp;base64," + kTestImages[feature]; }
二、瀏覽器向服務端發起請求的時候accept 會帶上image/webp 信息,在服務端判斷是否支持webp。nginx
map $http_accept $webp_suffix { default ""; "~*webp" ".webp"; }
經過nginx中map方法,查找是否有webp
字段,若是有設置$webp_suffix
爲.webp
值。經過該值就能夠來判斷是否支持webp。若是支持寫入cookie,前端經過檢測cookie作判斷,是否加載webp圖片。
nginx 中設置cookie代碼git
location / { if ($webp_suffix ~* webp) { add_header Set-Cookie 'webpAvaile=true; path= /; expires=3153600'; } }
經過設置根節點webpa類來處理css中圖片引入問題。
(function () { function addRootTag() { var className = document.documentElement.className; var name = className ? ' webpa' : 'webpa'; document.documentElement.className += name ; } if (/webpAvaile=true/.test(document.cookie)) { addRootTag(); window.webpAvaile = true; } })()
.webpbg(@url) { background-image: url(@url); .webpa & { background-image: url('@{url}.webp'); } }
在使用的時候採用
.header{ .webpbg('../image/header.jpg'); }
@mixin webpbg($url) { background-image: url($url); @at-root .webpa & { background-image: url($url+'.webp'); } }
在scss文件中使用
@include webpbg('../image/header.jpg');
經過流程能夠知道咱們在頁面上寫入了一個cookie(webpAvaile = true)。在加載頁面的時候咱們在頁面首圖後獲取cookie頁面是否存在webpAvaile,經過變量設置圖片格式。
var headImg = docoment.getElementById('#headImg') var srcUrl = headImg.getAttribute('data-url') if ( /webpAvaile=availeable/.test(document.cookies)) { // 修改首圖地址 headImg.setAttribute('src', srcUrl + '.webp') } else { headImg.setAttribute('src', srcUrl) }
這樣咱們就處理了首圖src的圖片格式。可是這樣頁面可能會由於父級元素、圖片都爲設定高度而產生抖動。那麼如何處理?直接設置圖片高度或者父級元素設置最小高度、或固定高度。
html5中有picture標籤能夠選擇加載不一樣圖片,是否能夠利用picture元素去掉js對圖片進行格式的選擇。實踐是可行的。
html5中的picture元素兼容性狀況。
<picture class="img" > <source class="img" srcset="images/banner.jpg.webp" type="image/webp"> <img class="img" id="headImg" src="images/banner.jpg"/> </picture>
在懶加載的時候,一樣將存儲在data-url中的值修改成是否須要加載webp格式的圖片。
$('[data-url]').each(function(item, index){ var ext = window.webpAvaile ? '.webp' : '' $(this).attr('src', $(this).attr('data-url') + ext) })
頁面模板可能由於後端php、java、node等不一樣的類型,處理方法不同當,但思路仍舊是同樣。經過後端判斷Accept中是否有image/webp,若是有在原圖片格式的後綴後加上.webp。
![]($!{banner.recordMap.get('圖片地址').value}.750x448.jpg$!{isWebp})
方案1、前端打包時node.js生成webp格式圖片
方案2、nginx + lua + imageMagic建立webp圖片
經過gulp任務,調用圖片轉化庫生成對應的webp圖片。這樣在打包上傳資源的時候同時把生成的webp圖片資源上傳到服務器。這裏採用了一個webp-batch-convert
的庫,其核心是採用cwebp-bin
將圖片轉換成webp。
var gulp = require('gulp'); var convert = require('webp-batch-convert'); gulp.task('webp', function () { var res = convert.cwebp('./images', './images', { q: 80, quiet: true }) console.log('total is: ' + res) })
略。
實現過程,對支持webp的請求設置cookies。利用nginx檢測圖片請求是否存在,若是不存在經過lua調用imageMagic建立webp圖片並返回。須要注意的是nginx須要安裝lua支持的模塊。[什麼是lua]()參考這裏。
user root; # nginx 用戶權限 執行lua建立圖片命令須要讀寫權限 # ... http { include mime.types; server { listen 80; server_name webp.leewr.com; root /home/leewr/mono/app/public/december; location / { if ($webp_suffix ~* webp) { add_header Set-Cookie 'webpAvaile=true; path= /;'; } } location ~* ^(.+\.(jpg|png|jpeg|gif))(.webp)$ { # 正則匹配圖片 paht/name.jpg.webp 格式的圖片請求 if (!-f $request_filename) { # 若是圖片不存在 access_log /usr/local/nginx/logs/december.log main; # 設置日誌文件 set $request_filepath /home/leewr/mono/app/public/december/$1; # 圖片真實路徑變量 set $ext $3; # 設置圖片擴展名$ext變量 content_by_lua_file lua/webp.lua; # 調用nginx/lua目錄下的webp.lua文件 } } } }
下面看lua, lua 中代碼很是簡單。定義command命令,調用系統os.execute(command)
執行convert圖片轉換命令。convert是ImageMagic的命令。..
lua 中字符串鏈接。ngx.var.ext是nginx中定義的變量。
local command command = "convert " ..ngx.var.request_filepath.. " " ..ngx.var.request_filepath..ngx.var.ext os.execute(command) ngx.exec(ngx.var.request_uri)
詳細見另外一篇文章,[nginx + lua + ImageMagic實現webp圖片剪切]()。
小結:webp圖片能夠經過webpack、gulp在前端打包的時候生成,也能夠經過nginx層自動完成圖片的轉換。二者均可以達到目的。經過nginx層建立圖片是一個更系統的方案。由於在對圖片進行處理的時,咱們的需求可能不僅是簡單的圖片格式轉換。當咱們須要在不一樣的情形調用不一樣的圖片大小、不一樣圖片格式的圖片的時候,這時候前端就無能爲力了,如須要支持90x90.jpg.webp
的圖片。webp格式的支持只是資源管理中一個小需求,爲了知足更多複雜的場景,選擇nginx作圖片轉換會是一個更好的選擇。
流程
一、nginx檢測webp支持狀況。
二、添加cookie
三、前端檢測cookie決定是否加載 webp圖片。
開發
一、html根節點添加webpa支持class
二、html中img資源能夠頭圖能夠採用picture方式加載。懶加載圖片手動判斷選擇加載webp圖片格式。
三、css中利用根節點的class編寫樣式。.webpbg('url')
或者 @include webpbg('url')
最後附上項目中全部代碼地址github , h5地址:http://webp.leewr.com