- 引入生产环境的 Vue 文件
更小的资源开销
- 使用单文件组件预编译模板
预编译模板最简单的方式就是使用单文件组件——相关的构建设置会自动把预编译处理好,所以构建好的代码已经包含了编译出来的渲染函数而不是原始的模板字符串。
- 提取组件的 CSS 到单独到文件
当使用单文件组件时,组件内的 CSS 会以 <style>
标签的方式通过 JavaScript
动态注入。这有一些小小的运行时开销,将所有组件的 CSS 提取到同一个文件可以避免这个问题,也会让 CSS 更好地进行压缩和缓存。
- 利用Object.freeze()提升性能
Vue 在遇到像 Object.freeze()
这样被设置为不可配置之后的对象属性时,不会为对象加上 setter getter
等数据劫持的方法
如果你确定某些 data
数据只是用于展示,后续不会有任何改变,那么可以尝试使用
- 扁平化 Store 数据结构
{
"id": "123",
"author": {
"id": "1",
"name": "Paul"
},
"title": "My awesome blog post",
"comments": [
{
"id": "324",
"commenter": {
"id": "2",
"name": "Nicole"
}
}
]
}
类似上述层级较深的数据结构,在进行频繁查找的时候会带来额外的性能开销,假设我们把用户信息在 store
内统一存放成 users[id]
这样的结构,修改和读取用户信息的成本就变得非常低。
可以自己手动写个工具函数,或者使用 normalizr
- 优化无限列表性能
如果你的应用存在非常长或者无限滚动的列表,那么采用 窗口化 的技术来优化性能,只需要渲染少部分区域的内容,减少重新渲染组件和创建 dom 节点的时间。】
相关的开源项目vue-virtual-scroll-list、vue-virtual-scroller
- 组件渲染懒加载优化超长应用内容初始渲染性能
上面提到的无限列表的场景,比较适合列表内元素非常相似的情况,不过有时候,你的 Vue 应用的超长列表内的内容往往不尽相同,例如在一个复杂的应用的主界面中,整个主界面由非常多不同的模块组成,而用户看到的往往只有首屏一两个模块。在初始渲染的时候不可见区域的模块也会执行和渲染,带来一些额外的性能开销。 使用组件懒加载在不可见时只需要渲染一个骨架屏,不需要真正渲染组件
-
利用服务端渲染(
SSR
)和预渲染(Prerender
)来优化加载性能 -
组件懒加载
我们通常会在项目初始化的时候,同时进行 Vuex
的初始化,静态集中注册 Vuex
的全部模块
// store.js
import { userAccountModule } from './modules/userAccount'
import { adminModule } from './modules/admin'
const store = new Vuex.Store({
modules: {
user: userAccountModule,
admin: adminModule
}
})
但是可能并不是每个用户都会使用其中所有的模块,比如一部分用户不需要 adminModule
,那么加载的 adminModule
就相当于是无用代码,可通过模块的动态注册来解决:
// store.js
import { userAccountModule } from './modules/userAccount'
export const store = new Vuex.Store({
modules: {
user: userAccountModule,
}
})
// Admin.vue
import adminModule from './admin.js'
export default {
mounted () {
// 在组件内部进行 vuex模块的动态注册
this.$store.registerModule('admin', adminModule)
},
beforeDestroy () {
// 在组件内部进行 vuex模块的动态卸载,
// 防止同一模块被多次注册
this.$store.unregisterModule('admin')
}
}
假设 Home.vue
上有客户评价部分,我们希望显示客户对服务的积极评价。因为有很多,所以我们不想在用户进入网站后立即显示它们,而是在用户需要查看时才显示它们。我们可以添加一个Show Testimonials
按钮,点击这个按钮后将加载并显示客户评价。
为了保存客户评价数据,我们还需要另外一个 Vuex
模块,我们把它叫作 testimonials
。这个模块将负责显示之前添加的评价和添加新的评价,但我们不需要了解实现细节。
我们希望只在用户单击了按钮后才下载 testimonials
模块,因为在这之前不需要它。让我们来看看如何利用动态模块注册和动态导入来实现这个功能。Testimonials.vue
是 Home.vue
中的一个组件
// Testimonials.vue
<template>
<button @click="showTestimonials">Testimonials</button>
</template>
<script>
const getTestimonialsModule = () => import('./testimonials.js')
export default {
methods: {
showTestimonials () {
getTestimonialsModule().then(testimonialsModule => {
this.isModuleRegistered = true
this.$store.registerModule('testimonials', testimonialsModule)
this.$store.dispatch('testimonials/load')
})
}
},
beforeDestroy () {
if (this.isModuleRegistered) {
this.$store.unregisterModule('testimonials')
}
}
}
</script>