浅谈 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获取窗口(容器)的大小及位置参数列举及简要说明
Dec 09 Javascript
JQuery-tableDnD 拖拽的基本使用介绍
Jul 04 Javascript
JavaScript 语言基础知识点总结(思维导图)
Nov 10 Javascript
关于JavaScript对象的动态选择及遍历对象
Mar 10 Javascript
jquery获得当前html页面源码的方法
Jul 14 Javascript
jquery实现的淡入淡出下拉菜单效果
Aug 25 Javascript
jquery实现可关闭的倒计时广告特效代码
Sep 02 Javascript
js创建对象的方法汇总
Jan 07 Javascript
基于jQuery实现中英文切换导航条效果
Sep 18 Javascript
扩展Bootstrap Tooltip插件使其可交互的方法
Nov 07 Javascript
Vuex,iView UI面包屑导航使用扩展详解
Nov 04 Javascript
javascript遍历对象的五种方式实例代码
Oct 24 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 无限分类的树类代码
2009/12/03 PHP
使用swoole扩展php websocket示例
2014/02/13 PHP
php实现redis数据库指定库号迁移的方法
2015/01/14 PHP
PHP实现批量生成App各种尺寸Logo
2015/03/19 PHP
Zend Framework教程之前端控制器Zend_Controller_Front用法详解
2016/03/07 PHP
基于JQuery的6个Tab选项卡插件
2010/09/03 Javascript
javascript检查表单数据是否改变的方法
2013/07/30 Javascript
jquery模拟SELECT下拉框取值效果
2013/10/23 Javascript
jQuery把表单元素变为json对象
2013/11/06 Javascript
js图片向右一张张滚动效果实例代码
2013/11/23 Javascript
javascript设计简单的秒表计时器
2020/09/05 Javascript
全面解析JavaScript的Backbone.js框架中的Router路由
2016/05/05 Javascript
Javascript缓存API
2016/06/14 Javascript
深入理解JavaScript中的for循环
2017/02/07 Javascript
vue单页面打包文件大?首次加载慢?nginx带你飞,从7.5M到1.3M蜕变过程(推荐)
2018/01/16 Javascript
Vue三层嵌套路由的示例代码
2018/05/05 Javascript
微信小程序实现简单跑马灯效果
2020/05/26 Javascript
利用Webpack实现小程序多项目管理的方法
2019/02/25 Javascript
详解js创建对象的几种方法及继承
2019/04/12 Javascript
从0到1搭建element后台框架优化篇(打包优化)
2019/05/12 Javascript
JavaScript中将值转换为字符串的五种方法总结
2019/06/06 Javascript
vue页面更新patch的实现示例
2020/03/25 Javascript
JavaScript面试中常考的字符串操作方法大全(包含ES6)
2020/05/10 Javascript
vue+element table表格实现动态列筛选的示例代码
2021/01/14 Vue.js
[48:28]完美世界DOTA2联赛循环赛FTD vs Magma第二场 10月30日
2020/10/31 DOTA
基于python的汉字转GBK码实现代码
2012/02/19 Python
使用pandas批量处理矢量化字符串的实例讲解
2018/07/10 Python
Python面向对象之类的内置attr属性示例
2018/12/14 Python
Python+Pyqt实现简单GUI电子时钟
2021/02/22 Python
PyTorch中常用的激活函数的方法示例
2019/08/20 Python
Pytorch环境搭建与基本语法
2020/06/03 Python
python利用opencv实现颜色检测
2021/02/23 Python
宣传策划类求职信范文
2014/01/31 职场文书
保险专业自荐信范文
2014/02/20 职场文书
2014购房个人委托书范本
2014/10/12 职场文书
教师求职自荐信范文
2015/03/04 职场文书