Vue.js 应用性能优化的几条建议,最后一条你用过吗?

任何项目达到一定规模,往往会带来性能问题,Vue.js 也不例外。本文简单介绍几个小技巧,帮你在一定程度上对项目做性能上的优化。 图片懒加载 如果应用里需要展示大量图片,比如电商网站,通常的做法是懒加载图片。懒加载的基本原理是提前准备好图片 URL,当图片真正进入可视范围时才去加载。可以手动实现懒加载机制,不过更方便的是直接用现成的插件,比如 [vue-lazyload] 安装: npm i vue-lazyload -S 入口文件里引入: // in main.js import Vue from 'vue' import App from './App.vue' import VueLazyload from 'vue-lazyload' Vue.use(VueLazyload) new Vue({ el: '#app', components: { App } }) 在模板里使用该插件提供的指令:
按需使用第三方库 如今前端开发生态可谓是蓬勃发展,各种第三方库应有尽有。但是,项目引入过多的第三方库也会增大项目体积,带来性能问题。以 Bootstrap 为例,如果你只是用一下它的响应式机制,还不如自己手写相关的 CSS,也不会太复杂,完全没有必要引入整个库。再比如 Moment.js,如果只是简单做下日期时间格式化,自己写个工具函数也就几行代码,引入庞大的完整包也是大材小用。这些库为了普适性,提供了尽可能多的功能,但你的项目可能只用了极少部分。我们不鼓励重复造轮子,但是要按需引入。现在很多库都提供了 ES 模块化的方式,也可以做到这一点。 路由懒加载 路由懒加载也可以提高入口页面的加载速度,因为很多路由页面在多数情况下并没有被访问,在打包的时候放到单独的文件里可以减少入口页的体积。路由懒加载是通过 webpack 的动态 import来实现的。 // in router.js import Home from '@/views/Home.vue'; // 静态 import const About = () => import('@/views/About.vue'); // 动态 import const router = new VueRouter({ routes: [ { path: '/', component: Home }, { path: '/about', component: About } ] }) 另外,这些懒加载的路由还可以分组,让相关性模块的多个路由页面打包到同一个 chunk,算是一种折中方案:既实现了按需加载,又不会过于碎片化。适用于子路由页面。 // in router.js import Home from '@/views/Home.vue'; // traditonal imports import User from '@/views/User.vue'; const About = () => import('@/views/About.vue'); // dynamic import const router = new VueRouter({ routes: [ { path: '/', component: Home }, { path: '/about', component: About }, { path: '/user/:id', component: User, children: [ { path: '/settings', component: () => import(/* webpackChunkName: "user" */ '@/views/UserSettings') }, { path: '/articles', component: () => import(/* webpackChunkName: "user" */ '@/views/UserArticles') } ] } ] }) 这是通过 webpack 的注释语法/* webpackChunkName: "user" */实现的,webpackChunkName相同的路由会打进同一个 chunk文件。 不要滥用 Vuex store Vuex 几乎是 Vue.js 项目全局状态管理的标配,以至于有些人一上来就把接口请求的数据全部往 store 里塞。时间一长,store 里的字段搞得一团糟。所谓全局状态,应该是在多个组件里都要用到的数据。经验值是少于三个组件的话,就没必要放在 Vuex 里了。store 过大会影响性能,也不方便管理。 大列表禁用响应式功能 默认情况下,定义在 Vue 组件data 里的数据都是响应式的,这种机制方便了数据绑定,当数据变化时界面得到自动更新。但有时候我们只是将数据显示到界面上,之后也不会改变它。这种情况下我们根本用不上响应式机制,而实现响应式是有性能代价的,特别是对于大对象和大列表。 export default { data: () => ({ users: {} }), async created() { const users = await axios.get("/api/users"); this.users = users; } }; 上面代码里的 users可能包含了非常多的数据,这样的对象数组要实现响应式会比较耗时。如果只是为了显示,不用于编辑,可以通过Object.freeze()禁用对象的响应式特性。 export default { data: () => ({ users: {} }), async created() { const users = await axios.get("/api/users"); this.users = Object.freeze(users); } }; 在 Vuex 里也一样: const mutations = { setUsers(state, users) { state.users = Object.freeze(users); } }; 如果确实需要修改数据,也可以重新生成数组: state.users = Object.freeze([...state.users, user]); 根据测试,优化后的代码,对于同样的数据量,组件初始化的时间从几百毫秒缩短到几毫秒。 总结 以上是 Vue.js 应用代码优化的一点经验之谈,希望对你有用。欢迎在评论区留言,补充更多优化方法! 看到这个颇有气质的 logo,不来关注下吗? image

本文章由javascript技术分享原创和收集

发表评论 (审核通过后显示评论):