webpack圖片打包問題

最近終于講完了Gemba Walk,終于有時間大把的時間好好補補最近落下的知識了。

背景描述

最近需要給項目中加上一個icon,第一反應就是問UX要個png的icon圖片,圖片拿上之后,上手就開始做。

這是第一次在某個repo工作,看完這個庫的pattern之后,猛然發現整個庫沒有一個png文件,全是svg,出于懶惰心里,全然沒有管,直接用了component中用了png文件。寫完發現都沒啥問題,行吧部署staging,等待第二天showcase。

第二天,果然,icon出不來了。。打開控制臺network:

  • 圖片請求403,并且請求路徑是s3
  • 手動打開aws看到這個bucket下竟然沒有這個圖片文件(原來是被打包坑了的。。。)
  • 我氣沖沖的打開webpack配置文件,發現:
    • png的loader是存在的。。。。
  • 行8,本地build一下吧,發現,果然和webpack里配置的一樣,在build的結果目錄下一個images目錄下孤零零的躺著一個我的png icon

------------懵逼分割線

不得以,開始看部署文件。。。

  • 發現package步驟不僅有webpack打包,還有gulp publish
  • 果然在gulpfile.js中發現,他們竟然只把我打包結果中的js和css文件作為result扔到s3上,根本沒有管images

本想氣沖沖的把打包結果中的images目錄扔到s3上,但是猛然覺得有點不對。。。諾大的項目中沒有一個png只有svg,這才是人家的pattern,然后引發了我幾個問題:

Q1: svg和png圖片的優劣都是啥,為什么有些項目不管什么類型的圖片都可以接受,但是有些項目必須要svg?

Q2: 使用webpack打包svg和png的異同?

Q3: 那么svg打包的結果也是單獨文件嗎?

.......

學習過程

瀏覽器對圖片的處理

對于瀏覽器而言,可以支持多種類型的文件:css/html/image ,那么圖片一般通過兩種方式其嵌入HTML:

  • HTML tag <img src=**/>
  • 通過css中 backgroung: url(***)

那么src或者說url的參數中應該填寫什么樣的format呢?

  • src/url的參數可以是Http URL
  • src/url的參數也可以是Data URL

什么是Data URL?開發的時候應該選擇Http URL還是Data URL?

DataURL
  • What

    DataURL:將文件通過某種編碼方式(可以使base64編碼)轉化成一串字符,瀏覽器能夠通過直接讀取字符還原文件。換句話說此處的URL不代表資源的地址,而直接是資源。

  • How
    Data URLs 由四個部分組成:

    • 前綴(data:)
    • 指示數據類型的MIME類型
    • 如果非文本則為可選的base64標記
    • 數據本身

    data:[<mediatype>][;base64],<data>
    data:image/gif;base64,**********

  • Why

    我們所看到的網頁上的每一個圖片,都是需要消耗一個 http 請求下載而來的, 使用DataURL,圖片就可以跟隨HTML(<img>)或者css (background:url())一起被拿回來,不用重新發送請求了。

  • Pros

    • 節省http請求(雖然CssSprites也可以)
    • 沒有跨域問題
  • Cons

    • 圖片被編碼之后,生成的字符串編碼大小一般而言都會比原文件大30%。如果把大圖片編碼到 html / css 中,會造成后者體積明顯增加,明顯影響網頁的打開速度。
    • base64 無法緩存,要緩存只能緩存包含 base64 的文件(HTML/CSS文件)

綜上所述,如果圖片足夠小(比如icon)且無法被制作成雪碧圖(CssSprites),base64是個很好的選擇。

svg和png以及jpg的優劣

我們都知道,一個web項目能夠支持JPG/PNG/SVG多種圖片文件格式,那么當我們需要圖片時候應該選用哪一種format呢?

那么問題應該什么樣的圖片能夠提升瀏覽器性能?
  1. 降低圖片的大小:

    如果圖片使用HTTP URL,那么就意味著,瀏覽器需要發起HTTP請求獲取圖片,那么請求的response一定是盡可能的小才對。

    • 雖然對于瀏覽器而言,是異步發送圖片請求(預加載),因此render tree的生成肯定不會等到圖片拿回,但是圖片如果很久之后才能獲取,可能導致頁面重新布局重新渲染。

    方案:
    可以選擇使用svg格式的圖片,svg生成的文件很小,下載很快

  2. 選擇適當的圖片寬度尺寸(即響應式圖片)

    因為對于Mobile和Web端,圖片的分辨率要求不同而且尺寸要求也不同,因此根據不同的設備請求不同的圖片也是提升性能的一種方式。

    如何實現呢?

    • 通過css media實現
    • Img的srcset和sizes的方法
    • 通過picture元素,picturefill或平臺判斷來為不同終端平臺輸出不同的圖片
  3. 減少HTTP的網絡資源請求

    如果圖片的總數量沒法改變,一個一個請求就意味著要發很多次HTTP 請求,那么將多個圖片作為一個response的結果就可以減少Http請求的數量,那么有什么方案能夠做到呢?

    • 使用Data URL替代Http URL
    • 合并圖片sprite(雪碧圖))
  4. 圖片延遲加載(懶惰加載)

    首屏不需要將所有圖片取回而是只把視窗內的圖片取回

不同的圖片format
  • png:
    • pros:
      • 透明背景
      • 支持高級別無損耗壓縮
    • cons:
      • 圖片尺寸相對較大
  • svg:
    • pros:
      • 透明背景
      • 對于高分辨率設備表現很好
      • 可編程
  • jpg:
    • pros:
      • 可以把文件壓縮到最小,適合應用于WEB圖片,可減少圖像的傳輸時間
      • 可利用可變的壓縮比以控制文件大小
    • cons:
      • 不是透明背景,因此不適于做icon,線條
      • 會造成質量下降,當您每編輯和重新保存 JPEG 文件時,JPEG 會混合原始圖片數據的質量下降。這種下降是累積性的、永久性的

看起來svg簡直是完美,但是請注意png不能裝成svg,但是svg可以轉成png(質量降低)

------> 好了現在可以解釋,為啥我們項目的icon要使用svg了,圖片有小又是透明背景,秒殺我的png,那么為啥不選擇使用jpg呢?

圖片透明背景的意義

試想一個場景,一個icon他的格式是jpg(非透明背景),放在一個非白色背景上,然后出現這樣的場景


左上角的icon是jpg格式

不對呀,怎么能是這樣!應該長這樣的啊


image.png
  • 因此當你的圖中是icon或者是有鏤空的部分,必須選用透明背景格式的圖片
  • 但是,當你的圖片是一張純背景,沒有鏤空,就可以選用jpg,比如背景圖片

webpack如何打包這些不同類型的圖片呢?

我們需要loader去處理這些圖片,不同的loader有不同的作用

url-loader:

將文件轉成base64編碼的DataUrl string, 根據上文所知:我們希望只有文件足夠小的時候被轉成base64,所以這個loader有兩個參數很重要:

  • limit: 指明被轉成base64的文件最大尺寸
    • 小于這個值的圖片被轉成base64,webpack會替換src的值成為base64編碼
    • 大于這個值的圖片會被file-loader處理,并將這個loader的options轉給file-loader
  • fallback: 指定一個當圖片尺寸大于limit時候使用的loader(不指定就是file-loader
file-loader:

將圖片打包到某一個文件中,并替換src變成打包后圖片的Http URL,可以自定義圖片打包后的文件名和位置

svg-url-loader:

將文件轉成utf-8編碼的DataUrl string,和url-loader不同不會轉成base64這樣做的好處是:

  • 更小
  • 瀏覽器更快的讀
  • 壓縮的更好

URL-loader一樣可以設置limit確定什么樣大小的圖片可以被轉成DataURL什么樣的圖片使用file-loader

但是使用的過程中,這些option很重要:

  • noquotes:true:在轉碼成DataURL的時候不要帶引號,保證DataURL一定能被瀏覽器解析成正確的svg圖片
  • limit
  • iesafe:true:只有這個屬性設置為true才能保證limit超過之后被file-loader解析

資料

https://www.itcodemonkey.com/article/3002.html

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,565評論 6 539
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,115評論 3 423
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,577評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,514評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,234評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,621評論 1 326
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,641評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,822評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,380評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,128評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,319評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,879評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,548評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,970評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,229評論 1 291
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,048評論 3 397
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,285評論 2 376

推薦閱讀更多精彩內容

  • 版權聲明:本文為博主原創文章,未經博主允許不得轉載。 webpack介紹和使用 一、webpack介紹 1、由來 ...
    it筱竹閱讀 11,212評論 0 21
  • 1 Webpack 1.1 概念簡介 1.1.1 WebPack是什么 1、一個打包工具 2、一個模塊加載工具 3...
    Kevin_Junbaozi閱讀 6,699評論 0 16
  • 目錄第1章 webpack簡介 11.1 webpack是什么? 11.2 官網地址 21.3 為什么使用 web...
    lemonzoey閱讀 1,747評論 0 1
  • webpack 是什么? 本質上,webpack 是一個現代 JavaScript 應用程序的靜態模塊打包器(mo...
    IT老馬閱讀 3,336評論 2 27
  • 作者 【每日計劃(早宣晚結)】 聚才LP3所向披靡!學員:歐陽麗。職務:時間廊、財務。約誓:我是一個自信.付出、...
    鏡由心生閱讀 121評論 0 0