------------------------------------------ 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天生轻量、曲线平滑,被很多同学青睐。开发中常见的问题也比较多。
一:首屏渲染
老生常谈首屏渲染是单页面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); //0 DOM 还没有更新
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);
}
});
},