分包策略
默认情况下,浏览器重复请求相同名称的静态资源时,会直接使用缓存的资源。利用这个机制我们可以将不会经常更新的代码单独打包成一个 js 文件,这样我们可以减少 HTTP 请求,同时降低服务器压力。
import { defineConfig } from "vite";
export default defineConfig({
build: {
rollupOptions: {
output: {
chunkFileNames: "static/js/[name]-[hash].js",
entryFileNames: "static/js/[name]-[hash].js",
assetFileNames: "static/[ext]/[name]-[hash].[ext]",
// ------ 开始 ------
manualChunks(id) {
if (id.includes("node_modules")) {
return id
.toString()
.split("node_modules/")[1]
.split("/")[0]
.toString();
}
},
// ------ 结束 ------
},
},
},
});
配置前:
配置后:js文件由一个被拆分成了多个,并且每次打包并不是所有的文件名都发生了变化
treeshaking
treeshaking 也被称为 “摇树优化”。简单来讲,就是在保证代码运行结果不变的前提下,去除无用的代码。Vue3 中,许多 ApI 的引入都支持 treeshaking 优化。也就是说只打包你用到的 API,忽略那些没有用到的。
Vue3 会默认使用 Rollup 进行 treeshaking ,不需要额外进行配置。但有一个条件,必须是 ES6 module 模块才行。
以 lodash 为例
npm install lodash
<script setup>
import { concat } from "lodash";
import { onMounted } from "vue";
onMounted(() => {
console.log(concat([1], [2]));
});
</script>
<style lang="scss" scoped></style>
lodash 打包后的体积大小:
由于 lodash 是使用 CommonJS 规范的模块,所以无法进行 treeshaking ,Vue 会把整个 lodash 依赖打包进来。整个依赖文件的大小是 70.69 KB 。
这时我们可以使用 ESM 版的 lodash 对比下:
npm install lodash-es
<!-- 组件中使用 -->
<script setup>
import { concat } from "lodash-es";
import { onMounted } from "vue";
onMounted(() => {
console.log(concat([1], [2]));
});
</script>
<style lang="scss" scoped></style>
打包后的体积如下:
可以看到依赖体积瞬间变成了 1.44 KB ,原因是只将 lodash concat 模块的代码打包了进来。
GZIP 压缩
gzip 是一种压缩算法,在网络传输中使用非常普遍。需要注意的是,Gzip 压缩仅对于文本类型的资源有明显提升,压缩后的体积大约减小 1/3 左右。对于图片,音视频等媒体资源,本身就采用了有损压缩,所以在使用 gzip 压缩并不能得到很大提升,有时候还会适得其反。而 JS,CSS 资源就非常适合 gzip 压缩。
浏览器解压也需要时间,所以代码体积不是很大的话不建议使用 gzip 压缩,因此我们可以设置一个最小压缩体积。
gzip 压缩后服务端也要进行相应的配置(后端应该知道),否则网页将无法正常打开。
npm i vite-plugin-compression -D
import { defineConfig } from "vite";
import viteCompression from "vite-plugin-compression";
export default defineConfig({
plugins:{
viteCompression({
verbose: true, // 是否在控制台输出压缩结果,默认为true
disable: false,// 是否禁用压缩,默认为false
threshold: 10240, // 启用压缩的文件大小限制,默认为0
algorithm: "gzip", // 采用的压缩算法,默认是gzip
ext: ".gz",// 生成的压缩包后缀
filter: "", // 过滤器,对哪些文件进行压缩,默认为/.(js|mjs|json|css|html)$/i’
deleteOriginFile: false // 压缩后是否删除原文件,默认为false
}),
}
});
效果:
CDN 加速
内容分发网络(Content Delivery Network,简称 CDN)就是让用户从最近的服务器请求资源,提升网络请求的响应速度。通常我们请求依赖模块使用 CDN ,而请求项目代码依然使用自己的服务器。
我们知道文件越大,对于网络带宽和访问速度的要求也就越高。这也是我们优化的方向,我们可以把较大的第三方依赖文件打包上线的时候排除掉,把它们放到 CDN 服务器去,减小整体包的体积,使用 CDN 服务器加快我们的插件访问速度。
以 echarts 插件为例:
npm install echarts
<template>
<div ref="echart" class="echart"></div>
</template>
<script setup lang="ts">
import { onMounted, ref } from "vue";
import * as echarts from "echarts";
const echart = ref();
onMounted(() => {
const myEchart = echarts.init(echart.value);
myEchart.setOption({
title: {
text: "ECharts 入门示例",
},
tooltip: {},
xAxis: {
data: ["衬衫", "羊毛衫", "雪纺衫", "裤子", "高跟鞋", "袜子"],
},
yAxis: {},
series: [
{
name: "销量",
type: "bar",
data: [5, 20, 36, 10, 10, 20],
},
],
});
});
</script>
<style lang="scss" scoped>
.echart {
width: 400px;
height: 300px;
}
</style>
效果:
使用 echarts 后打包的项目体积大小:
我们可以看到使用 echarts 插件后直接导致我们的包的体积增加了将近 1M 的大小。
使用 CDN:
npm install vite-plugin-html rollup-plugin-external-globals --save-dev
// vite.config.js
import { defineConfig } from "vite";
import externalGlobals from "rollup-plugin-external-globals";
import { createHtmlPlugin } from 'vite-plugin-html'
export default defineConfig({
plugins: [
createHtmlPlugin({
minify: true, // html 压缩
inject:{
data:{
echartsSciprt: '<script src="https://cdnjs.cloudflare.com/ajax/libs/echarts/5.4.3/echarts.min.js"></script>'
}
}
})
],
build: {
rollupOptions: {
external: ["echarts"],
plugins: [
externalGlobals({
echarts: "echarts",
}),
]
},
}
});
<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<!-- 注意看这里,没写这个的话,createHtmlPlugin就白写了 -->
<%- echartsSciprt %>
<title>Vite + Vue</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>
效果:
我们可以看到 echarts 没有被打包进去,这时候我们看看图表是否正常显示。
npm install serve --config
控制台输入 serve dist 就可以在本地模拟服务器运行
效果:图片也有正常显示出来