浅谈vue.js项目常见问题优化-首屏渲染慢,文件过大等

  • 从"0"入手入门webpack4(一):初始化项目
  • 从"0"入手入门webpack4(二):css篇css-loader less-loader postcss-loader autoprefixer
------------------------------------------ 2020-03-31更新 ---------------------------------
大家可以期待下webpack5 Module Federation 共享模块
"打包慢",是一个综合的因素,和vue关系不大。 1:确保下webpack,npm, node 及主要库版本要新,比如:4.x比3.x提升很多。 2:loader范围缩小到src项目文件!一些不必要的loader能关就关了吧 3:eslint代码校验其实是一个很费时间的一个步奏。 1:可以把eslint的范围缩小到src,且只检查*.js 和 *.vue 2:生产环境不开启lint,使用pre-commit或者husky在提交前校验 4:happypack多进程进行 如果上面优化后,时间还是不满意的话,就尝试下5,6吧。 5:动态链接库(DllPlugin),楼上已说。有点类似配置的externals。 补充一下: 缺点:将不能按需加载,会将配置的第三方库全部打包进去。 推荐:可以将使用率较高的包采用dll方案。 6:HardSourceWebpackPlugin会将模块编译后进行缓存,第一次之后速度会明显提升。

------------------------------------------------------------------------------
vue.js天生轻量、曲线平滑,被很多同学青睐。开发中常见的问题也比较多。
【浅谈vue.js项目常见问题优化-首屏渲染慢,文件过大等】一:首屏渲染
老生常谈首屏渲染是单页面spa的通病。有些同学打包出来的dist高达60+M。首页加载20+S。这个体验真的是会让用户崩溃。
常见解决方案

(1):路由懒加载
当打包构建应用时,Javascript 包会变得非常大,影响页面加载。如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就更加高效了。
写法:
{ path: '/index', name: 'HelloWorld', component: (resolve) => require(['../components/HelloWorld.vue'], resolve) },

或者改成
const HelloWorld = resolve => require(['@/components/HelloWorld.vue'], resolve) export default new Router({ routes: [ { path: '/', name: 'HelloWorld', component: HelloWorld }, ] })

(2):webpack优化
1:说到优化首提happypack, webpack默认是单线程进行的,而happypack则是启动node的多线程进行构建。查看具体配置方法
2:webpack.prod.conf.js文件devtool选择正确的 sourcemap 。生产环境直接去掉就好了。查看sourceMap
(3):服务端渲染SSR
SSR解决的两大痛点1:首屏渲染,2:seo。
但是ssr实现较为复杂一些,不做展开描述。目前官方文档有支持。另外推荐一个vue服务端渲染的框架:Nuxt.js
二:数组检测
官网说的很明白。因为vue响应式是主要依赖Object.defineProperty的getter和setter,Vue 不能检测以下变动的数组:
1:当你利用索引直接设置一个项时,例如:vm.items[indexOfItem] = newValue
2:当你修改数组的长度时,例如:vm.items.length = newLengthd
解决方法
// Vue.set Vue.set(vm.items, indexOfItem, newValue); // Array.prototype.splice vm.items.splice(indexOfItem, 1, newValue);

三:nextTick()
在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。类似生命周期created和mounted的区别。
比如这么一个场景:你需要获取拿到数据后的某个文档的高度,请求结束后页面还没更新,获取的肯定不对。这个时候就需要在数据渲染结束后去获取。
updateList(){ this.itemList = ['super', 'tom', 'andy', 'nick']; console.log(document.getElementById('demo').offsetHeight); //0DOM 还没有更新 this.$nextTick(function () { console.log(document.getElementById('demo').offsetHeight); // DOM 更新了 }) },

四:this作用域指向问题
错误示例:
data () { return { msg: 'Welcome to Your Vue.js App', itemList: [1, 2, 3, 4], newList: [] } }, methods:{ updateList(){ this.itemList.forEach(function (val) { if(val >=2){ this.newList.push(val); // undefined } }) }, }

方法一:_this赋值
updateList(){ let _this = this; _this.itemList.forEach(function (val) { if(val >=2){ _this.newList.push(val); } }) },

方法二:箭头函数
updateList(){ this.itemList.forEach( (val) => { if(val >=2){ this.newList.push(val); } }); },





    推荐阅读