资讯专栏INFORMATION COLUMN

Webpack 项目优化杂记

incredible / 3437人阅读

摘要:入口文件打包出口地址在中可以配置我们的地址这里你要有一个七牛云的账户。特别像是七牛云这样拥有图片处理引擎的服务商,我们还可以通过来处理上传至的图片。

本项目源码均可在 这里 找到。

之前公司的官网项目静态文件都是放在静态服务器中,这其中的弊端就不赘述了。简单说一下 CDN 的好处:

CDN 可以解决因分布、带宽、服务器性能带来的访问延迟问题,适用于站点加速、点播、直播等场景。使用户可就近取得所需内容,解决 Internet 网络拥挤的状况,提高用户访问网站的响应速度和成功率。控制时延无疑是现代信息科技的重要指标,CDN 的意图就是尽可能的减少资源在转发、传输、链路抖动等情况下顺利保障信息的连贯性。CDN 就是扮演者护航者和加速者的角色,更快准狠的触发信息和触达每一个用户,带来更为极致的使用体验。
上传脚本文件

这里为了最小化演示路径,我们只上传项目所用的 js 文件。且 CDN 基于七牛云。

// webpack.config.js
module.exports = {
  // 入口文件
  entry: "./src/app.js",
  // 打包出口
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "app.js",
    publicPath: "http://example.clouddn.com/example/" // CDN 地址
  }
}

output.publicPath 中可以配置我们的 CDN 地址(这里你要有一个七牛云的 账户 )。之后我们引入 qn-webpack。

plugin 配置见该 plugin 源码即可。这里有一份示例配置:

// webpack.config.js
const qiniuWebpackPlugin = new QiniuWebpackPlugin({
  accessKey: "七牛云个人面板 > 密钥管理 > AK",
  secretKey: "七牛云个人面板 > 密钥管理 > SK",
  bucket: "对象存储空间名",
  path: "空间内保存路径",
  exclude: /index.html$/ // 需要排除上传的文件
});

module.exports = {
  // 加载插件
  plugins: [ qiniuWebpackPlugin ]
};

现在运行:

npm run build # webpack --mode=production

在终端中我们已经可以看到我们的 js 文件被上传至自己的 CDN 服务中。通过 html-webpack-plugin 我们引入 js 的路径也相应的替换成了 CDN 地址。

上传图片

很多时候,在我们的项目中,需要去:

import url from "./your/img/path";

图片挂上 CDN 也是很有必要的,图片视频文件之类的东西本身就比较大而且可以算是静态的内容,从动态服务器上分离出去,可以极大的减小服务的负载。特别像是七牛云这样拥有图片处理引擎的服务商,我们还可以通过 imageView2 来处理上传至 CDN 的图片。

说回图片上传,首先我们引入 file-loader ,Webpack 配置如下:

// webpack.config.js
module.exports = {
  module: {
    rules: [
      {
        test: /.(gif|png|jpe?g|svg|webp)$/i,
        use: [
          {
            loader: "file-loader",
            options: {
              // publicPath: 默认 `__webpack_public_path__` 为 `output.publicPath`
            }
          }
        ]
      }
    ]
  }
}

file-loader 会指示 Webpack 将所需的对象作为文件引入并返回其公共 URL 。

再次运行:

npm run build # webpack --mode=production

两个文件已经被上传至 CDN ,且路径被替换。但是, 2.74 MiB 与后面的 [big] 很是鲜艳,下一步我们需要压缩图片以减少文件体积。

处理图片

之前我们可以看看 Chrome 控制台:

2.7 MiB 的图片就算放在 CDN ,请求时间也超过了 100ms,那么我们开始处理图片。

引入 image-webpack-loader 并开始配置 Webpack :

//webpack.config.js
module.exports = {
  module: {
    rules: [{
      test: /.(gif|png|jpe?g|svg|webp)$/i,
      use: [
        {
          loader: "file-loader",
          options: {
            // publicPath: 默认 `__webpack_public_path__` 为 `output.publicPath`
          }
        }, {
          loader: "image-webpack-loader",
          options: {
            mozjpeg: {
              progressive: true,
              quality: 65
            },
            optipng: {
              enabled: false,
            },
            pngquant: {
              quality: "65-90",
              speed: 4
            },
            gifsicle: {
              interlaced: false,
            },
            WebP: {
              quality: 75
            }
          }
        },
      ],
    }]
  }
}

详细配置参见 文档 。

再次打包:

发现图片大小从 2.74 MiB -> 1.16 MiB 虽然还是有点大,但是已经有很明显的大小变化。再来看看 Chrome 控制台:

效果很明显 140 ms -> 43 ms

WebP

在进行这一步之前,需要简单了解一下什么是 WebP 格式图片。

目前移动端 Android 4.0 以上、PC 端 Chorme 10+(14 ~ 16 有渲染bug)、Opera 11+ 、Safri 均支持 WebP 格式图片。 WebP 与 jpg 相比较,编码速度慢 10 倍,解码速度慢 1.5 倍,而绝大部分的网络应用中,图片都是静态文件,所以对于用户使用只需要关心解码速度即可。但实际上,webp 虽然会增加额外的解码时间,但是由于减少了文件体积,缩短了加载的时间,实际上文件的渲染速度反而变快了。

搬运知乎上的一张图片:

所以我们可以得出结论:WebP 体积大幅减少,图片质量也有保障,除了兼容性不太好。

对于兼容性,我们可以看这张图:

考虑到兼容性的问题,我们之后会进行专门处理。现在第一步则是转化 png & jpg -> Webp

这里选用 gulp 作为转化图片为 WebP 的自动化构建工具。Webpack 社区插件看 这里,我这里选用 gulp 作为构建工具也是希望自己能够控制 WebP 图片的制作,在本地生成而不是 CI 打包时(时间有点长... 。

//gulpfile.js
const gulp = require("gulp");
const webp = require("gulp-webp"); // 基于 cwebp 的 gulp 插件

// 基于 cwebp 转化图片
gulp.task("webp", () =>
  gulp.src("src/img/*.{png,jpg,jpeg}")
    .pipe(webp({ quality: 75 })) // 详情配置见:https://github.com/imagemin/imagemin-webp#api
    .pipe(gulp.dest("src/img"))
);

// 监听文件夹变化
gulp.task("watch", () =>
  gulp.watch("src/img/*.{png,jpg,jpeg}", ["webp"])
);

gulp.task("default", () =>
  gulp.start("watch")
);

配置之后我们运行打包可以比较一下:

使用 WebP 格式前

使用 WebP 格式后

最后我们在项目中使用 WebP 时候,需要判断一下浏览器是否支持 WebP 格式图片:

const canUseWebp = (() => {
  return document.createElement("canvas").toDataURL("image/webp").indexOf("data:image/webp") > -1;
})()

// 如果可以使用 WebP ,则给顶部元素加上一个 class
if (canUseWebp) {
 document.getElementsByTagName("body")[0].className += " webp";
}

将这段 js 内联在 head 标签中后,我们可以利用 CSS 预处理器来判断是否需要使用 WebP 格式图片。

// stylus
bg($url, $type)
  background-image url($url + $type)
  .webp & // 如果拥有 .webp 类名,则使用 WebP 格式图片
    background-image url($url + ".webp")
// less
.mixin(@url, @type) {
  background-image: url(@{url}.@{type});
  .webps & {
    background-image: url("@{url}.webp");
  }
}
// scss
@mixin bg($url, $type) {
  background-image: url($url + $type);
  @at-root(with: all) .webps & {
    background-image: url($url + ".webp");
  }
}

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/99740.html

相关文章

  • Webpack系列-第一篇基础杂记

    摘要:系列文章系列第一篇基础杂记系列第二篇插件机制杂记系列第三篇流程杂记前言公司的前端项目基本都是用来做工程化的,而虽然只是一个工具,但内部涉及到非常多的知识,之前一直靠来解决问题,之知其然不知其所以然,希望这次能整理一下相关的知识点。 系列文章 Webpack系列-第一篇基础杂记 Webpack系列-第二篇插件机制杂记 Webpack系列-第三篇流程杂记 前言 公司的前端项目基本都是用...

    Batkid 评论0 收藏0
  • Webpack系列-第三篇流程杂记

    摘要:最后执行了的回调函数,触发了事件点,并回到函数的回调函数触发了事件点执行对于当前模块,或许存在着多个依赖模块。 系列文章 Webpack系列-第一篇基础杂记 Webpack系列-第二篇插件机制杂记 Webpack系列-第三篇流程杂记 前言 本文章个人理解, 只是为了理清webpack流程, 没有关注内部过多细节, 如有错误, 请轻喷~ 调试 1.使用以下命令运行项目,./scrip...

    xorpay 评论0 收藏0
  • webpack系列-插件机制杂记

    摘要:系列文章系列第一篇基础杂记系列第二篇插件机制杂记系列第三篇流程杂记前言本身并不难,他所完成的各种复杂炫酷的功能都依赖于他的插件机制。的插件机制依赖于一个核心的库,。是什么是一个类似于的的库主要是控制钩子函数的发布与订阅。 系列文章 Webpack系列-第一篇基础杂记 Webpack系列-第二篇插件机制杂记 Webpack系列-第三篇流程杂记 前言 webpack本身并不难,他所完成...

    Neilyo 评论0 收藏0
  • 前端模块化杂记

    摘要:入口模块返回的赋值给总结在剖析了整体的流程之后,可以看到相关的技术细节还是比较清晰的,学无止境引用混合使用详解的语法前端模块化规范 前言 CMDAMD简介 Commonjs简介 Module简介 Common和Module的区别 Module与webpack Module与Babel 一些问题 总结 引用 前言 前端模块化在近几年层出不穷,有Node的CommonJs,也有属于cl...

    GitCafe 评论0 收藏0
  • 4月份前端资源分享

    摘要:更多资源请文章转自月份前端资源分享关于的思考一款有趣的动画效果跨站资源共享之二最流行的编程语言能做什么到底什么是闭包的第三个参数跨域资源共享详解阮一峰前端要给力之语句在中的值周爱民中国第二届视频花絮编码规范前端工程师手册奇舞周刊被忽视的 更多资源请Star:https://github.com/maidishike... 文章转自:https://github.com/jsfron...

    jsdt 评论0 收藏0

发表评论

0条评论

incredible

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<