浅谈 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 相关文章推荐
jQuery中的bind绑定事件与文本框改变事件的临时解决方法
Aug 13 Javascript
jquery蒙版控件实现代码
Dec 08 Javascript
Javascript合并表格中具有相同内容单元格示例
Aug 11 Javascript
js图片预加载示例
Apr 30 Javascript
jquery得到iframe src属性值的方法
Sep 25 Javascript
JS与jQ读取xml文件的方法
Dec 08 Javascript
教你用javascript实现随机标签云效果_附代码
Mar 16 Javascript
jquery实现(textarea)placeholder自动换行
Dec 22 Javascript
JS中去掉array中重复元素的方法
May 26 Javascript
react-redux中connect()方法详细解析
May 27 Javascript
VUE解决微信签名及SPA微信invalid signature问题(完美处理)
Mar 29 Javascript
WEEX环境搭建与入门详解
Oct 16 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用header函数实现301跳转代码实例
2013/11/25 PHP
php判断手机浏览还是web浏览,并执行相应的动作简单实例
2016/07/28 PHP
php支付宝在线支付接口开发教程
2016/09/19 PHP
PHP实现求连续子数组最大和问题2种解决方法
2017/12/26 PHP
seaJs的模块定义和模块加载浅析
2014/06/06 Javascript
使用text方法获取Html元素文本信息示例
2014/09/01 Javascript
jQuery控制cookie过期时间的方法
2015/04/07 Javascript
jQuery仿gmail实现fixed布局的方法
2015/05/27 Javascript
Nodejs Stream 数据流使用手册
2016/04/17 NodeJs
每日十条JavaScript经验技巧(一)
2016/06/23 Javascript
Bootstrap基本组件学习笔记之input输入框组(9)
2016/12/07 Javascript
原生JS实现图片轮播切换效果
2016/12/15 Javascript
jQuery插件HighCharts实现的2D堆条状图效果示例【附demo源码下载】
2017/03/14 Javascript
Angular.JS中的指令引用template与指令当做属性详解
2017/03/30 Javascript
JavaScript中使用webuploader实现上传视频功能(demo)
2017/04/10 Javascript
Vuejs入门教程之Vue生命周期,数据,手动挂载,指令,过滤器
2017/04/19 Javascript
用js实现before和after伪类的样式修改的示例代码
2017/09/07 Javascript
Angular 4.x+Ionic3踩坑之Ionic3.x pop反向传值详解
2018/03/13 Javascript
如何使用pm2快速将项目部署到远程服务器
2019/03/12 Javascript
浅谈layui数据表格判断问题(加入表单元素),设置单元格样式
2019/10/26 Javascript
three.js 如何制作魔方
2020/07/31 Javascript
JavaScript对象访问器Getter及Setter原理解析
2020/12/08 Javascript
[03:02]生活中的Dendi之野外度假篇
2016/08/09 DOTA
[01:21]DOTA2 新英雄 森海飞霞
2020/12/18 DOTA
[43:24]完美世界DOTA2联赛PWL S3 INK ICE vs DLG 第二场 12.12
2020/12/17 DOTA
解决谷歌搜索技术文章时打不开网页问题的python脚本
2013/02/10 Python
使用python装饰器验证配置文件示例
2014/02/24 Python
Sanic框架请求与响应实例分析
2018/07/16 Python
Django MEDIA的配置及用法详解
2019/07/25 Python
matplotlib教程——强大的python作图工具库
2020/10/15 Python
欧洲、亚洲、非洲和拉丁美洲的度假套餐:Great Value Vacations
2019/03/30 全球购物
函数指针的定义是什么
2016/08/14 面试题
十八届三中全会宣传方案
2014/02/21 职场文书
《小乌鸦爱妈妈》教学反思
2016/02/19 职场文书
instantclient客户端 连接oracle数据库
2022/04/26 Oracle
MySQL的存储过程和相关函数
2022/04/26 MySQL