浅谈 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 相关文章推荐
IE和firefox浏览器的event事件兼容性汇总
Dec 06 Javascript
jquery 插件学习(一)
Aug 06 Javascript
JavaScript高级程序设计(第3版)学习笔记12 js正则表达式
Oct 11 Javascript
js 弹出框只弹一次(二次修改之后的)
Nov 26 Javascript
调用DOM对象的focus使文本框获得焦点
Feb 19 Javascript
javascript实现动态模态绑定grid过程代码
Sep 22 Javascript
深入理解JS中的substr和substring
Apr 26 Javascript
关于RequireJS的简单介绍即使用方法
Oct 20 Javascript
AngularJS自定义服务与fliter的混合使用
Nov 24 Javascript
react实现pure render时bind(this)隐患需注意!
Mar 09 Javascript
JS实现的将html转为pdf功能【基于浏览器端插件jsPDF】
Feb 06 Javascript
Vue组件通信的四种方式汇总
Feb 08 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+java实现自动新闻滚动窗口
2006/10/09 PHP
php读取EXCEL文件 php excelreader读取excel文件
2012/12/06 PHP
对淘宝URL中ID提取的PHP代码
2013/09/01 PHP
PHP连接MySQL数据库并以json格式输出
2018/05/21 PHP
php图片裁剪函数
2018/10/31 PHP
thinkphp5 框架结合plupload实现图片批量上传功能示例
2020/04/04 PHP
表单项的name命名为submit、reset引起的问题
2007/12/22 Javascript
Javascript 去除数组的重复元素
2010/05/04 Javascript
jquery validate.js表单验证的基本用法入门
2010/05/13 Javascript
javascript中substr,substring,slice.splice的区别说明
2010/11/25 Javascript
JavaScript 计算图片加载数量的代码
2011/01/01 Javascript
js 处理数组重复元素示例代码
2013/12/27 Javascript
禁止页面刷新让F5快捷键及右键都无效
2014/01/22 Javascript
jquery实现全屏滚动
2015/12/28 Javascript
微信小程序 触控事件详细介绍
2016/10/17 Javascript
js定时器实例分享
2016/12/20 Javascript
JavaScript基本语法_动力节点Java学院整理
2017/06/26 Javascript
javascript数组定义的几种方法
2017/10/06 Javascript
浅谈Webpack下多环境配置的思路
2018/06/27 Javascript
jQuery简单实现根据日期计算星期几的方法
2019/01/09 jQuery
vue 自定义右键样式的实例代码
2019/11/06 Javascript
[03:07]【DOTA2亚洲邀请赛】我们,梦开始的地方
2017/03/07 DOTA
python迭代器的使用方法实例
2013/11/21 Python
python使用装饰器和线程限制函数执行时间的方法
2015/04/18 Python
python interpolate插值实例
2020/07/06 Python
python获取命令行参数实例方法讲解
2020/11/02 Python
洛杉矶生活休闲而精致的基础品牌:Mika Jaymes
2018/01/07 全球购物
夏尔巴人登珠峰品牌:Sherpa Adventure Gear
2018/02/08 全球购物
联想阿根廷官方网站:Lenovo Argentina
2019/10/14 全球购物
花卉与景观设计系大学生求职信
2013/10/01 职场文书
《乡愁》教学反思
2014/02/18 职场文书
技术股东合作协议书
2014/12/02 职场文书
公司处罚决定书
2015/06/24 职场文书
新学期家长寄语2016
2015/12/03 职场文书
如何用 Python 子进程关闭 Excel 自动化中的弹窗
2021/05/07 Python
Vue中插槽slot的使用方法与应用场景详析
2021/06/08 Vue.js