前端开发——性能优化,包体积压缩82%、打包速度提升65%

15 篇文章 0 订阅

关于本文

来自:海阔_天空

https://juejin.cn/post/7186315052465520698

压缩项目打包后的体积大小、提升打包速度,是前端性能优化中非常重要的环节,笔者结合工作中的实践总结,梳理出一些 常规且有效 的性能优化建议

项目背景

技术栈:vue-cli3 + vue2 + webpack4
主要插件:elementUI + echarts + axios + momentjs

目标: 通过一系列的优化方案,对比打包体积和速度的前后变化,来验证方案的有效性

项目初始体积与速度

  • 初始体积 2.25M

vue 项目可以通过添加--report命令:"build": "vue-cli-service build --report",打包后 dist 目录会生成 report.html 文件,用来分析各文件的大小

或者通过安装 webpack-bundle-analyzer 插件来分析,步骤如下:

1)安装

npm install webpack-bundle-analyzer -D
复制代码

2)vue.config.js中 引入

const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
module.exports = {
  configureWebpack: {
      plugins: [
         new BundleAnalyzerPlugin()
      ]
  }
}
复制代码

3)npm run serve运行后,在浏览器打开http://127.0.0.1:8888/  可以看到分析页面

  • 初始打包速度 25386ms

 

开始优化 ✈︎

1、externals 提取项目依赖

从上面的打包分析页面中可以看到,chunk-vendors.js 体积为 2.21M,其中最大的几个文件都是一些公共依赖包,那么只要把这些依赖提取出来,就可以解决 chunk-vendors.js 过大的问题

可以使用 externals 来提取这些依赖包,告诉 webpack 这些依赖是外部环境提供的,在打包时可以忽略它们,就不会再打到 chunk-vendors.js 中

1)vue.config.js 中配置:

module.exports = {
  configureWebpack: {
    externals: {
      vue: 'Vue',
      'vue-router': 'VueRouter',
      axios: 'axios',
      echarts: 'echarts'
    }
}
复制代码

2)在 index.html 中使用 CDN 引入依赖

  <body>
    <script src="http://lib.baomitu.com/vue/2.6.14/vue.min.js"></script>
    <script src="http://lib.baomitu.com/vue-router/3.5.1/vue-router.min.js"></script>
    <script src="http://lib.baomitu.com/axios/1.2.1/axios.min.js"></script>
    <script src="http://lib.baomitu.com/echarts/5.3.2/echarts.min.js"></script>
  </body>
复制代码

验证 externals 的有效性:

重新打包,最新数据如下:

打包体积:1.12M

 

打包速度:18879ms

 

使用 externals 后,包体积压缩50%、打包速度提升26%

2、组件库的按需引入

为什么没有使用 externals 的方式处理组件库呢?

externals缺点:直接在html内引入的,失去了按需引入的功能,只能引入组件库完整的js和css

组件库按需引入的原理:最终只引入指定组件和对应的样式

elementUI 需要借助 babel-plugin-component[1] 插件实现,插件的作用如下:

如按需引入 Button 组件:

import { Button } from 'element-ui'

Vue.component(Button.name, Button)
复制代码

编译后的文件(自动引入 button.css):

import _Button from "element-ui/lib/button";
import _Button2 from "element-ui/lib/theme-chalk/button.css";
// base.css是公共的样式
import "element-ui/lib/theme-chalk/base.css";

Vue.component(_Button.name, _Button);
复制代码

通过该插件,最终只引入指定组件和样式,来实现减少组件库体积大小

1)安装 babel-plugin-component

npm install babel-plugin-component -D
复制代码

2)babel.config.js中引入

module.exports = {
  presets: ['@vue/app'],
  plugins: [
    [
      'component',
      {
        libraryName: 'element-ui',
        styleLibraryName: 'theme-chalk'
      }
    ]
  ]
};
复制代码

验证组件库按需引入的有效性:

重新打包,最新数据如下:

打包体积:648KB

 

打包速度:15135ms

 

组件库按需引入后,包体积压缩72%、打包速度提升40%

同时 chunk-vendors.css 的体积也有了明显的减少,从206KB降到了82KB

原始体积:

 

按需引入后:

 

3、减小三方依赖的体积

继续分析打包文件,项目中使用了 momentjs,发现打包后有很多没有用到的语言包

使用 moment-locales-webpack-plugin 插件,剔除掉无用的语言包

1)安装

npm install moment-locales-webpack-plugin -D
复制代码

2)vue.config.js 中引入

const MomentLocalesPlugin = require('moment-locales-webpack-plugin');

module.exports = {
  configureWebpack: {
     plugins: [
       new MomentLocalesPlugin({localesToKeep: ['zh-cn']})
     ]
  }
}
复制代码

验证插件的有效性:

重新打包,最新数据如下:

打包体积:407KB

momentJsSize.png

打包速度:10505ms

momentJsTime.png

减小三方依赖体积后,包体积压缩82%、打包速度提升59%

4、HappyPack 多线程打包

由于运行在 Node.js 之上的 webpack 是单线程模型的,我们需要 webpack 能同一时间处理多个任务,发挥多核 CPU 电脑的威力

HappyPack 就能实现多线程打包,它把任务分解给多个子进程去并发的执行,子进程处理完后再把结果发送给主进程,来提升打包速度

1)安装

npm install HappyPack -D
复制代码

2)vue.config.js 中引入

const HappyPack = require('happypack');
const os = require('os');
// 开辟一个线程池,拿到系统CPU的核数,happypack 将编译工作利用所有线程
const happyThreadPool = HappyPack.ThreadPool({ size: os.cpus().length });

module.exports = {
  configureWebpack: {
     plugins: [
       new HappyPack({
        id: 'happybabel',
        loaders: ['babel-loader'],
        threadPool: happyThreadPool
      })
     ]
  }
}
复制代码

验证 HappyPack 的有效性:

重新打包,最新数据如下:

打包速度:8949ms

happyPackTime.png

使用HappyPack后,打包速度进一步提升了65%

由于测试项目较小,打包时间缩短的不算太多。实测发现越是复杂的项目,HappyPack 对打包速度的提升越明显

5、Gzip压缩

线上的项目,一般都会结合构建工具 webpack 插件或服务端配置 nginx,来实现 http 传输的 gzip 压缩,目的就是把服务端响应文件的体积尽量减小,优化返回速度

html、js、css资源,使用 gzip 后通常可以将体积压缩70%以上

这里介绍下使用 webpack 进行 gzip 压缩的方式,使用 compression-webpack-plugin 插件

1)安装

npm install compression-webpack-plugin -D
复制代码

2)vue.config.js 中引入

const CompressionPlugin = require('compression-webpack-plugin');

module.exports = {
  configureWebpack: {
     plugins: [
      new CompressionPlugin({
        test: /\.(js|css)(\?.*)?$/i, //需要压缩的文件正则
        threshold: 1024, //文件大小大于这个值时启用压缩
        deleteOriginalAssets: false //压缩后保留原文件
      })
     ]
  }
}
复制代码

验证插件的有效性:

重新打包,原来 407KB 的体积压缩为 108KB

gZip.png

6、DllPlugin 动态链接库

DllPlugin 与 externals 的作用相似,都是将依赖抽离出去,节约打包时间。区别是 DllPlugin 是将依赖单独打包,这样以后每次只构建业务代码,而 externals 是将依赖转化为 CDN 的方式引入

当公司没有很好的 CDN 资源或不支持 CDN 时,就可以考虑使用 DllPlugin ,替换掉 externals

DllPlugin 配置流程大致分为三步:

1)创建 dll.config.js 配置文件

import { DllPlugin } from "webpack";

export default {
    // 需要抽离的依赖
    entry: {
        vendor: ["vue", "vue-router", "axios", "echarts"]
    },
    mode: "production",
    optimization: {
        splitChunks: {
            cacheGroups: {
                vendor: {
                    chunks: "all",
                    name: "vendor",
                    test: /node_modules/
                }
            }
        }
    },
    output: {
        filename: "[name].dll.js", // 输出路径和文件名称
        library: "[name]", // 全局变量名称:其他模块会从此变量上获取里面模块
        path: AbsPath("dist/static") // 输出目录路径
    },
    plugins: [
        new DllPlugin({
            name: "[name]", // 全局变量名称:减小搜索范围,与output.library结合使用
            path: AbsPath("dist/static/[name]-manifest.json") // 输出目录路径
        })
    ]
};
复制代码

2)package.json 配置脚本

"build:dll": "webpack --config ./dll.config.js",
复制代码

3)使用 DllReferencePlugin 将打包生成的dll文件,引用到需要的预编译的依赖上来,并通过 html-webpack-tags-plugin 在打包时自动插入dll文件

vue.config.js 配置如下

import { DllReferencePlugin } from "webpack";
import HtmlTagsPlugin from "html-webpack-tags-plugin";

export default {
  configureWebpack: {
    plugins: [
      new DllReferencePlugin({
        manifest: AbsPath("dist/static/vendor-manifest.json") // manifest文件路径
      }),
      new HtmlTagsPlugin({
        append: false, // 在生成资源后插入
        publicPath: "/", // 使用公共路径
        tags: ["static/vendor.dll.js"] // 资源路径
      })
    ]
  }
};
复制代码

先运行 npm run build:dll 打包生成依赖文件,以后只用运行 npm run build 构建业务代码即可

优化总结

经过上面的一系列优化,可以看到:

  • 包体积由原来的 2.25M 减少到 407KB,压缩了82%

  • 打包速度由原来的 25386ms减少到 8949ms,提升了65%

这些方式虽然很常规,但确实可以有效地提升项目的性能

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue.js是一款流行的JavaScript前端框架,具有易学易用的特点,被广泛应用于前端开发中。《Vue.js前端开发实战》是一本针对Vue.js框架的开发实践书籍,主要介绍了Vue.js的基本概念和使用方法,并通过实例演示了如何开发具有实际功能的前端应用。 本书提供了未打包源码的下载链接,这意味着读者可以直接获取书中示例代码的源文件而无需进行打包操作。这对于初学者来说非常方便,因为他们可以直接运行源码并通过观察代码逐步学习Vue.js的使用。 未打包源码通常是指开发过程中的源代码,没有进行压缩打包的处理。例如,CSS文件、HTML模板和JavaScript脚本可以分别以独立的形式存在。通过使用未打包源码,读者可以更好地理解代码的结构和逻辑,并且可以自由地修改和调试源码以适应自己的需求。 对于读者来说,未打包源码的使用有一些优势和注意事项。首先,这个源码可以作为学习Vue.js的教材,通过观察和理解源码的运行过程,读者可以更好地掌握Vue.js的使用方法。其次,读者可以直接在此基础上进行修改和拓展,实现自己的前端应用。然而,需要注意的是,由于未打包源码没有经过优化处理,所以在生产环境中使用时可能会存在性能问题。因此,在实际应用中,通常需要对源码进行打包压缩处理。 总的来说,Vue.js前端开发实战的未打包源码可以帮助读者更好地学习和理解Vue.js框架,并可以作为开发实践的基础,但在实际应用中需要进行进一步的打包和优化处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值