浅谈 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 表单验证常见正则
Sep 28 Javascript
javascript void(0)的妙用
Oct 21 Javascript
javascript预加载图片、css、js的方法示例介绍
Oct 14 Javascript
Javascript中的apply()方法浅析
Mar 15 Javascript
关于JavaScript的变量的数据类型的判断方法
Aug 14 Javascript
三个js循环的关键字示例(for与while)
Feb 16 Javascript
BootStrap响应式导航条实例介绍
May 06 Javascript
[原创]JavaScript语法高亮插件highlight.js用法详解【附highlight.js本站下载】
Nov 01 Javascript
轻松实现jQuery添加删除按钮Click事件
Mar 13 Javascript
JS运动特效之链式运动分析
Jan 24 Javascript
Vue3.x源码调试的实现方法
Oct 13 Javascript
详解React 条件渲染
Jul 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环境搭建最新方法
2006/09/05 PHP
一个捕获函数输出的函数
2007/02/14 PHP
删除html标签得到纯文本可处理嵌套的标签
2014/04/28 PHP
php函数与传递参数实例分析
2014/11/15 PHP
PHP中preg_match函数正则匹配的字符串长度问题
2015/05/27 PHP
Yii 框架使用数据库(databases)的方法示例
2020/05/19 PHP
再次更新!MSClass (Class Of Marquee Scroll通用不间断滚动JS封装类 Ver 1.6)
2007/02/05 Javascript
JS之小练习代码
2008/10/12 Javascript
javascript开发随笔一 preventDefault的必要
2011/11/25 Javascript
jquery实现两边飘浮可关闭的对联广告
2015/11/27 Javascript
解决jQuery使用JSONP时产生的错误
2015/12/02 Javascript
JS库之ParticlesJS使用简介
2017/09/12 Javascript
VSCode配置react开发环境的步骤
2017/12/27 Javascript
一次记住JavaScript的6个正则表达式方法
2018/02/22 Javascript
详解基于mpvue的小程序markdown适配解决方案
2018/05/08 Javascript
Node.js中的cluster模块深入解读
2018/06/11 Javascript
JS使用cookie保存用户登录信息操作示例
2019/05/30 Javascript
Vue实现页面添加水印功能
2019/11/09 Javascript
[01:25]2014DOTA2国际邀请赛 zhou分析LGD比赛情况
2014/07/14 DOTA
Pyhthon中使用compileall模块编译源文件为pyc文件
2015/04/28 Python
Python中用post、get方式提交数据的方法示例
2017/09/22 Python
JS设计模式之责任链模式实例详解
2018/02/03 Python
详解Python:面向对象编程
2019/04/10 Python
pytorch 可视化feature map的示例代码
2019/08/20 Python
python处理自动化任务之同时批量修改word里面的内容的方法
2019/08/23 Python
多个python文件调用logging模块报错误
2020/02/12 Python
一文弄懂Pytorch的DataLoader, DataSet, Sampler之间的关系
2020/07/03 Python
详解python tcp编程
2020/08/24 Python
Luxplus瑞典:香水和美容护理折扣
2018/01/28 全球购物
Furla官网:意大利著名的皮革品牌
2019/08/06 全球购物
Rowdy Gentleman服装和配饰:美好时光
2019/09/24 全球购物
编程实现当输入某产品代码则打印出该产品记录的功能
2014/05/03 面试题
《跟踪台风的卫星》教学反思
2014/04/10 职场文书
生产操作工岗位职责
2014/09/16 职场文书
2015年小学美术工作总结
2015/05/25 职场文书
2016年度优秀辅导员事迹材料
2016/02/26 职场文书