vue-cli+router实现异步组件配合路由进行性能优化
配置属性对打包资源进行静态分析
一般优化分为首屏优化与交互优化,而交互优化主要方式就是缩短js动画效果的执行时间,首屏优化就是减少首屏的请求静态资源的体积等。如果是静态路由打包后,会在首屏加载所有的路由组件和页面,会极大的增加app.js的打包体积,而我们平常在首屏时候是不需要加载首屏以外的其他组件的,所以我们应该使用异步按需加载的方式。
首先在vue.config.js文件中,配置如下:
module.exports = {
css: {},
devServer: {},
// 重点:静态打包资源分析
configureWebpack: (config) => {
// process.env.npm_config_report
// 只有在执行run build的时候为true 这时候就可以使用这个插件来分析js打包资源
if (process.env.npm_config_report) {
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
config.plugins.push(new BundleAnalyzerPlugin())
}
},
// 生产环境不开SourceMap,一旦开启别人会看到源码
productionSourceMap: false,
publicPath: process.env.NODE_ENV === 'production' ? '' : '/'
}
process.env.npm_config_report:只有执行npm run build的时候,会为true。
这时候就可以对打包资源的js进行分析。
然后用浏览器 访问127.0.0.1:8888即可在网页中查看各个静态资源的分析。
将静态同步路由改为异步路由
平常的路由我会这么写(以下为一个项目中静态路由的完整示例):
// 静态引用会在首屏加载时候载入全部组件
import { createRouter, createWebHashHistory } from 'vue-router'
import Recommend from '@/views/recommend'
import Singer from '@/views/singer'
import TopList from '@/views/top-list'
import Search from '@/views/search'
import SingerDetail from '@/views/singer-detail'
import Album from '@/views/album'
import TopDetail from '@/views/top-detail'
import UserCenter from '@/views/user-center'
// 路由配置
const routes = [
// 配置当访问根路径/的时候,跳转到/recommend的路径 渲染Recommend组件
{
path: '/',
redirect: '/recommend'
},
{
path: '/recommend',
component: Recommend,
children: [
{
path: ':id',
component: Album
}
]
},
{
path: '/singer',
component: Singer,
// 指定子路由 每个对象都是子路由配置
children: [
{
// 动态参数每个singer传递的Id是不同的
path: ':id',
component: SingerDetail
}
]
},
{
path: '/top-list',
component: TopList,
children: [
{
path: ':id',
component: TopDetail
}
]
},
{
path: '/search',
component: Search,
// 将歌手组件定义为search的二级路由
children: [
{
path: ':id',
component: SingerDetail
}
]
},
{
path: '/user',
components: {
user: UserCenter
}
}
]
const router = createRouter({
history: createWebHashHistory(),
routes
})
export default router
这个路由的缺点就是在首屏的时候,会加载全部的组件,导致首屏加载缓慢。如果要对首屏加载进行优化,那么就要使用动态的异步路由:只有在点击tag触发请求的时候才去获取组件对应的Js。
所以,我们使用import()函数,将组件的请求改为异步方法。
// 这种写法是同步组件 首屏就要加载 import Recommend from '@/views/recommend'
// 异步组件配合路由进行性能优化这样打包后的app.js就不会很大,下面这种写法是将同步组件变为异步组件 只有触发时候才按需加载
const Recommend = () => import('@/views/recommend')
const Singer = () => import('@/views/singer')
const TopList = () => import('@/views/top-list')
const Search = () => import('@/views/search')
const SingerDetail = () => import('@/views/singer-detail')
const Album = () => import('@/views/album')
const TopDetail = () => import('@/views/top-detail')
const UserCenter = () => import('@/views/user-center')
这时候,我们运行项目,如下图:
这时,我们发现,当我们切换组件的时候,F12会查看到每当请求不同的组件的时候,才回去请求对应的js(组件)。
当然,默认名称是0.js,1.js,那么有没有办法让js名称友好一些?
为请求的组件js加一个名字
webpackChunkName为请求的组件js加一个名字,如果不加,默认是1.js, 0.js等。如果加了 那么在请求的时候就是recommend.js,F12在网络-js那部分看,这样就可以一眼就看出这是recommend组件对应的js。
具体的语法格式为:
/* webpackChunkName:"指定的名称" */
需要注意的是:/*【空格】webpack..:“xxx"【空格】*/,如果不这样写,就会有语法错误的提示。
真实使用例:
const Recommend = () => import('@/views/recommend'/* webpackChunkName:"recommend" */)
为recommend组件请求时候,指定的js名称为recommend.js。
更改后最终效果如下:
/*
* webpackChunkName为请求的组件js加一个名字,如果不加,默认是1.js, 0.js等到
* 如果加了 那么在请求的时候就是recommend.js
* F12在网络-js那部分看,这样就可以一眼就看出这是recommend组件对应的js
* */
const Recommend = () => import('@/views/recommend'/* webpackChunkName:"recommend" */)
const Singer = () => import('@/views/singer'/* webpackChunkName:"singer" */)
const TopList = () => import('@/views/top-list'/* webpackChunkName:"top-list" */)
const Search = () => import('@/views/search'/* webpackChunkName:"search" */)
const SingerDetail = () => import('@/views/singer-detail'/* webpackChunkName:"singer-detail" */)
const Album = () => import('@/views/album'/* webpackChunkName:"album" */)
const TopDetail = () => import('@/views/top-detail'/* webpackChunkName:"top-detail" */)
const UserCenter = () => import('@/views/user-center'/* webpackChunkName:"user-center" */)
然后当我们在运行项目的时候,就可以在控制台看到: