浅谈 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学习总结之元素的相对定位和选择器(持续更新)
Apr 26 Javascript
IE6/7 and IE8/9/10(IE7模式)依次隐藏具有absolute或relative的父元素和子元素后再显示父元素
Jul 31 Javascript
extjs实现选择多表自定义查询功能 前台部分(ext源码)
Dec 20 Javascript
jQuery 下拉列表 二级联动插件分享
Mar 29 Javascript
jQuery动态创建html元素的常用方法汇总
Sep 05 Javascript
整理Javascript基础语法学习笔记
Nov 29 Javascript
Js类的静态方法与实例方法区分及jQuery拓展的两种方法
Jun 03 Javascript
百度搜索框智能提示案例jsonp
Nov 28 Javascript
vue项目关闭eslint校验
Mar 21 Javascript
vue 纯js监听滚动条到底部的实例讲解
Sep 03 Javascript
区别JavaScript函数声明与变量声明
Sep 12 Javascript
JS实现图片切换特效
Dec 23 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 stripslashes和addslashes的区别
2014/02/03 PHP
php自定义分页类完整实例
2015/12/25 PHP
PHP实现mysqli批量执行多条语句的方法示例
2017/07/22 PHP
List Information About the Binary Files Used by an Application
2007/06/18 Javascript
document.getElementById介绍
2011/09/13 Javascript
javascript 系统文件夹文件操作及参数介绍
2013/01/08 Javascript
登陆成功后自动计算秒数执行跳转
2014/01/23 Javascript
Javascript实现字数统计
2015/07/03 Javascript
微信小程序 详解页面跳转与返回并回传数据
2017/02/13 Javascript
Easyui Datagrid自定义按钮列(最后面的操作列)
2017/07/13 Javascript
轻松理解vue的双向数据绑定问题
2017/10/30 Javascript
JS二分查找算法详解
2017/11/01 Javascript
js中null与空字符串&quot;&quot;的区别讲解
2019/01/17 Javascript
Vue核心概念Action的总结
2019/01/18 Javascript
浅谈vue限制文本框输入数字的正确姿势
2019/09/02 Javascript
openLayer4实现动态改变标注图标
2020/08/17 Javascript
Python实现优先级队列结构的方法详解
2016/06/02 Python
同时安装Python2 &amp; Python3 cmd下版本自由选择的方法
2017/12/09 Python
简单实现Python爬取网络图片
2018/04/01 Python
Python unittest单元测试框架总结
2018/09/08 Python
Python实现的读取文件内容并写入其他文件操作示例
2019/04/09 Python
Python2.7版os.path.isdir中文路径返回false的解决方法
2019/06/21 Python
Python Pandas中根据列的值选取多行数据
2019/07/08 Python
教你如何编写、保存与运行Python程序的方法
2019/07/12 Python
python multiprocessing多进程变量共享与加锁的实现
2019/10/02 Python
GIVENCHY纪梵希官方旗舰店:高定彩妆与贵族护肤品
2018/04/16 全球购物
TCP协议通讯的过程和步骤是什么
2015/10/18 面试题
Linux如何为某个操作添加别名
2013/03/01 面试题
医院办公室主任职责
2013/12/29 职场文书
八年级音乐教学反思
2014/01/09 职场文书
社区活动邀请函范文
2014/01/29 职场文书
党员一帮一活动总结
2014/07/08 职场文书
幼儿园见习报告范文
2014/10/30 职场文书
2015年度团总支工作总结
2015/04/23 职场文书
在Windows下安装配置CPU版的PyTorch的方法
2021/04/02 Python
深入讲解Vue中父子组件通信与事件触发
2022/03/22 Vue.js