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阅读 217,406评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,732评论 3 393
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,711评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,380评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,432评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,301评论 1 301
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,145评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,008评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,443评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,649评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,795评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,501评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,119评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,731评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,865评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,899评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,724评论 2 354

推荐阅读更多精彩内容

  • 版权声明:本文为博主原创文章,未经博主允许不得转载。 webpack介绍和使用 一、webpack介绍 1、由来 ...
    it筱竹阅读 11,121评论 0 21
  • 1 Webpack 1.1 概念简介 1.1.1 WebPack是什么 1、一个打包工具 2、一个模块加载工具 3...
    Kevin_Junbaozi阅读 6,660评论 0 16
  • 目录第1章 webpack简介 11.1 webpack是什么? 11.2 官网地址 21.3 为什么使用 web...
    lemonzoey阅读 1,735评论 0 1
  • webpack 是什么? 本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包器(mo...
    IT老马阅读 3,319评论 2 27
  • 作者 【每日计划(早宣晚结)】 聚才LP3所向披靡!学员:欧阳丽。职务:时间廊、财务。约誓:我是一个自信.付出、...
    镜由心生阅读 116评论 0 0