浅谈 Webpack 如何处理图片(开发、打包、优化)


Posted in Javascript onMay 15, 2019

从 webpack book 的 Loading Assets 一章中延申出来。

改善前端项目体验中,很重要的点就是静态资源的优化。它是由于浏览器客户端在同一时间针对同一 域名 的请求有一定资源限制。如果资源过多、过大就会使得页面卡顿。

静态资源中,又以图片最为典型。那么我们在开发中该如何处理图片呢?

webpack 是前端较为常用的手脚架工具,本文以它为例。

主要分为 开发 、 打包 、 优化 三个方面来介绍

示例地址: webpack demo

开发

webpack 可以用使用url-loader  将静态图片转化为 base64 编码的字符串,并内联在对应的脚本中。大幅度地较少了页面的请求数,所以在开发阶段可以无限制地使用。具体方法

// npm install url-loader --save-dev

rules: [{
  test: /\.(png|jpg)$/,
  use: {
    loader: 'url-loader',
  },
}]

以 demo-example 为例,Gakki.jpg 被转化为了 base 64 编码的图片。在开发阶段,没什么问题,但是如果在实际环境中,会发现一个很大的问题,将图片越大转化为base 64 编码的字符串就越长,将会导致整个 Js 脚本的大小飙升。

打包

为了减小脚本的大小,我们需要告诉 webpack 什么情况下采用 url-loader 去内联图片,什么情况下采用其他的 loader。所以首先需要对 url-loader 进行配置

rules: [{
  test: /\.(png|jpg)$/,
  use: {
    loader: 'url-loader',
   options: {
      limit: 15000,
      name: '[name].[ext]',
    },
  },
}]

在 options 中设定一个阈值属性 limit: 15000 ,表明当图片小于该阈值 15kb 时,采用内联形式加载。那么如果超过阈值,我们该怎么办?

可以利用 fallback 属性指定采用file-loader  来处理,具体见配置

options: {
  limit: 15000,
 fallback: 'file-loader',
  name: 'images/[name].[hash].[ext]',
},

默认情况下,file-loader 会返回 options 依据 文件内容返回一个 MD5 Hash 来构建文件名。

如果同时需要 file-loader 与 url-loader 的情况,需要设置 limit来做区分。

优化

为了进一步地优化体验,我们可以采用以下策略:

  1. 控制图片质量,压缩图片大小;
  2. 配置 <img /> 标签的 srcset 来适应不同的屏幕;
  3. 合成雪碧图,减少图片资源请求数;
  4. 使用占位图。

控制图片质量,压缩图片大小

为了和 url-loader 配合,引入image-webpack-loader ,同时配置图片的 loader

{
  test: /\.(png|jpg)$/,
  use: [
    {
      loader: 'url-loader',
      // 同上
      options,
    },
    {
      loader: 'image-webpack-loader',
      // 配置不同图片的质量
      options: {
        mozjpeg: {
          progressive: true,
          quality: 65,
        },
        optipng: {
          enabled: true,
        },
        pngquant: {
          quality: '65-90',
          speed: 4,
        },
        gifsicle: {
          interlaced: false,
        },
        webp: {
          quality: 75,
        },
      },
    },
  ],
}

然后运行 npm run build ,很明显的发现,图片的大小有了明显的变化。这种对于图片的压缩对于生产环境特别有价值,因为它减少了下载图像资源所需的带宽量,从而加快了站点或应用程序的速度。

也可以采用 imagemin-webpack-plugin 插件。

配置 <img /> 标签的 srcset 来适应不同的屏幕

resize-image-loader 和responsive-loader 可以生成 srcset 的图片合集,可以在现代游览器上获得更好地体验,同时可以更好地控制浏览器加载哪些图像以及何时获得更高的性能。

合成雪碧图,减少图片资源请求数

Spriting技术允许将多个较小的图像组合成单个图像。它对于Web开发很有价值,同时也避免了请求开销。

webpack-spritesmith 能够生成雪碧图和 Sass / Less / Stylus mixins。必须设置 SpritesmithPlugin,将其指向目标图像,并设置生成的mixin的名称。

使用占位图

与以上对比,这个 loader 使用起来相对复杂,它加载图像并将其转化为 image / svg + xml URL 编码数据。通常它可以与file-loader和url-loader一起使用,以便在加载实际图像时显示占位符。配置为

{
  test: /\.(gif|png|jpe?g)$/i,
    use: [
      {
        loader: 'image-trace-loader'
      },
      {
        loader: 'url-loader',
        options: {
          limit: 8192
        }
      }
    ]
}

这样,你在 loader 图片时,就会获得

// src 为图片,trace 为loader生成的占位图
import { src, trace } from './assets/images/gakki-363kb.jpg'

// 定义图片组件为
export const img = ({ src, trace }) => {
  const img = new Image()

  img.src = trace
  img.onload = function () {
     img.src = src
  }
  
  return img
}
// 挂载在 document.body 上
document.body.appendChild(img({ src, trace }))

参考:

  • webpack book
  • webpack doc
  • 若干 npm readme

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JavaScript 不只是脚本
May 30 Javascript
Jquery Autocomplete 结合asp.net使用要点
Oct 29 Javascript
javascript 图片裁剪技巧解读
Nov 15 Javascript
javascript中自定义对象的属性方法分享
Jul 12 Javascript
javascript获取xml节点的最大值(实现代码)
Dec 11 Javascript
js 验证身份证信息有效性
Mar 28 Javascript
JS实现简单的图书馆享元模式实例
Jun 30 Javascript
js实现左侧网页tab滑动门效果代码
Sep 06 Javascript
jQuery插件datatables使用教程
Apr 21 Javascript
js removeChild 方法深入理解
Aug 16 Javascript
基于layer.js实现收货地址弹框选择然后返回相应的地址信息
May 26 Javascript
详解原生js实现offset方法
Jun 15 Javascript
JavaScript页面倒计时功能完整示例
May 15 #Javascript
vue组件间通信六种方式(总结篇)
May 15 #Javascript
JS正则表达式封装与使用操作示例
May 15 #Javascript
微信小程序实现授权登录
May 15 #Javascript
基于vue实现一个神奇的动态按钮效果
May 15 #Javascript
微信小程序导航栏跟随滑动效果的实现代码
May 14 #Javascript
详解VSCode配置启动Vue项目
May 14 #Javascript
You might like
php定义数组和使用示例(php数组的定义方法)
2014/03/29 PHP
php验证码实现代码(3种)
2015/09/07 PHP
Ajax中的JSON格式与php传输过程全面解析
2017/11/14 PHP
PHP实现求连续子数组最大和问题2种解决方法
2017/12/26 PHP
表单填写时用回车代替TAB的实现方法
2007/10/09 Javascript
JavaScript之appendChild、insertBefore和insertAfter使用说明
2010/12/30 Javascript
JS中获取数据库中的值的方法
2013/07/14 Javascript
解决Extjs4中form表单提交后无法进入success函数问题
2013/11/26 Javascript
父节点获取子节点的字符串示例代码
2014/02/26 Javascript
JS实现图片无间断滚动代码汇总
2014/07/30 Javascript
innerHTML中标签可以换行的方法汇总
2015/08/14 Javascript
微信小程序-获得用户输入内容
2017/02/13 Javascript
JS实现中国公民身份证号码有效性验证
2017/02/20 Javascript
原生JS与jQuery编写简单选项卡
2017/10/30 jQuery
Vue仿今日头条实例详解
2018/02/06 Javascript
JavaScript选择排序算法原理与实现方法示例
2018/08/06 Javascript
学习使用ExpressJS 4.0中的新Router的用法
2018/11/06 Javascript
JS开发常用工具函数(小结)
2019/07/04 Javascript
javascript实现前端分页效果
2020/06/24 Javascript
vue-quill-editor的使用及个性化定制操作
2020/08/04 Javascript
详解Python中的文件操作
2016/08/28 Python
Python随机生成均匀分布在单位圆内的点代码示例
2017/11/13 Python
Python自定义函数计算给定日期是该年第几天的方法示例
2019/05/30 Python
python redis 批量设置过期key过程解析
2019/11/26 Python
python3 实现口罩抽签的功能
2020/03/11 Python
python图片验证码识别最新模块muggle_ocr的示例代码
2020/07/03 Python
纯CSS实现的大小渐变、渐远效果
2014/04/15 HTML / CSS
CSS3 仿微信聊天小气泡实例代码
2017/04/05 HTML / CSS
巴西购物网站:Onofre Agora
2020/06/08 全球购物
数控专业个人求职信范文
2014/02/05 职场文书
超市重阳节活动方案
2014/02/10 职场文书
捐款活动总结
2014/08/27 职场文书
祝福语集锦:送给毕业同学祝福语
2019/11/21 职场文书
发工资啦!教你用Python实现邮箱自动群发工资条
2021/05/10 Python
MySQL连表查询分组去重的实现示例
2021/07/01 MySQL
MySQL into_Mysql中replace与replace into用法案例详解
2021/09/14 MySQL