关于项目性能优化的小细节,总结
1-背景
言归正传,下面开始今天的日常分享,对于前端的性能优化,面试时会遇到,如果遇见大型项目和复杂逻辑时候,性能优化也是不可避免的,对于我接手的石山一样的前端代码,把这个加载时候的loading发挥的淋漓尽致!不封装不优化,对用户也是极其不友好的,真是加载一上午,显示一个数据,感到非常的无语,包括后端代码同样遇到了这个问题,虽然与我无关哈哈哈。考虑到这些,我就进行了一些小小的改动和优化。
10个代码层面技巧
v-if和v-show 区分使用场景
v-if是真正的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当的被销毁和重建;也是惰性的;如果在初始渲染时
条件为假,则什么也不做,直到条件第一次变成真时,才会开始渲染条件块。
v-show:就简单很多,不管初始条件是什么,元素总会被渲染,并且只是简单的基于css的display属性进行切换。
**总结:** v-if适用于在运行时很少改变条件,不需要频繁切换条件的场景; v-show则适用于需要非常频繁切换条件的场景。
computed和watch区分使用场景
computed: 计算属性,依赖其他属性值,并且computed的值有缓存,只有它依赖的属性值发生改变,下一次获取computed的值时,才会重新计算computed的值。
watch: 更多的是观察作用,类似于某些数据的监听回调,每当监听的数据变化时都会执行回调进行后续的操作;
适用场景:
1-当我们需要进行数值计算,并且依赖于其他数据时,应该使用computed,因为可以利用computed的缓存特性,避免每次获取值时,都需要重新计算l
2- 当我们需要在数据变化时执行异步或开销较大的操作时,应该使用watch,使用watch选项允许我们执行异步操作(访问一个API),限制我们执行改操作的频率,并在我们得到最终的结果前,设置中间状态。这些都是计算属性无法做到的。
v-for遍历必须为item添加key,且避免同时使用v-if
1 v-for遍历必须为item添加key
在列表吧数据进行遍历渲染时,需要为每一项item设置唯一key值,方便vue.js内部机制精准找到该条列表数据,当state更新时,新的状态值和旧的状态值对比,较快的定位到diff
2 v-for 遍历避免同时使用v-if
v-for比v-if优先级高,既前者优于后者,如果每一次都需要遍历整个数组,将会影响速度,尤其是当之需要渲染很小一部分的时候,必要情况下应该替换computed属性。
正确使用方式:
<ul>
<li
v-for="user in active"
:key="user.id">
{{user.name}}
</li>
</ul>
computed:{
active:function(){
return this.users.filter(function(user){
return user.isActive
})
}
},
不推荐写法:
<ul>
<li
v-for="user in active"
:key="user.id"
v-if="user.isActive"
>
{{user.name}}
</li>
</ul>
长列表性能优化
Vue会通过Object.defineProperty对数据进行劫持,来实现视图响应数据的变化,然而有些时候我们的组建就是纯粹的数据展示,不会有任何改变,我们就不需要vue来劫持我们的数据,在大量的数据展示的情况下,这能够很明显的减少组建初始化的时间,那如何禁止vue劫持我们的数据对象呢?可以通过Object.freeze方法来冻结一个对象,一旦被冻结,对象就再也不能被修改了。
export default{
data:() => ({
users:{}
}),
async created(){
const users = await axios.get('/api/users')
this.users = Object.freeze(users);
}
}
事件的销毁
vue组件销毁时,会自动清理他与其他实例的连接,解绑它的全部指令以及事件监听器,但仅限于组件本身的事件,如果在js内使用,addEventListener等方式是不会自动销毁的,我们需要在组件销毁时手动移除这些事件的监听,以免造成内存泄露。
created(){
addEventListenner(‘click’, this.click, false)
},
beforeDestory(){
removeEventListener('click',this.click,false)
}
图片资源懒加载
对于图片过多的页面,为了加速页面加载速度,所以很多时候我们需要将页面内未出现在可视区域内的图片先不加载,等到滚动到可视区域后再加载,这样对于页面加载性能上会有很大的提升,也提高了用户体验。我们在项目中使用Vue的vue-lazyload插件。
1--安装插件
npm install vue-lazyload --save-dev
2 在入口文件main.js中引入并使用
import Vuelazy from ‘vue-lazyload’
然后在vue中直接使用
Vue.use(VueLazyload)
3 在vue文件中,将img标签的src属性直接改为v-lazy,从而将图片显示方式改为懒加载显示
<img v-lazy='/static/img/1.png'>
以上为vue-lazyload插件的简单使用,其他需求另行参考git或其他 Vue是单页面应用,可能会有很多的路由引入,这样使用webpack打包后的文件很大每当进入首页的时候,加载的资源过多,页面会出现白屏的情况,不利于用户体验,如果我们能把不同的路由对应的组件分割成不同的代码块,然后当路由被访问的时候,才加载对应的组件,这样就更加高效了,这样会大大提高首屏显示的速度,但是可能其他的页面的速度会降下来
路由懒加载:
const foo = () => import{
'./foo.vue'
}
const router = new Router({
routers:[
{
path:"/foo",
component:foo
}
]
})
第三方插件的按需引入
我们在项目中经常需要引入第三方插件,如果我们之间引入整个插件,会导致项目体积太大,我们可以借助babel-plugin-component,然后可以只引入需要的组件,以达到减小项目体积的目的,以下为项目中引入element-ui为例
1-首先安装babel-plugin-component
npm install babel-plugin-component -D
2-然后将.babelrc修改为:
{
"presets":[["es2015",{
"modules":false
}]]
"plugins":[
"component",
{
"libraryName":"element-ui",
"styleLibraryName":"theme-chalk"
}
]
}
3 在main.js中引入部分组件
import Vue from 'vue'
import {Button , Select} from 'element-ui'
Vue.use(Button)
Vue.use(Select)
优化无线列表性能
如果你的应用存在非常长或者无限滚动的列表,那么需要采用窗口化的技术来优化性能,只需要渲染少部分区域的内容,减少重新渲染组件和创建dom节点的时间。可以参考以下开源项目vue-virtual-scroll-list和vue-virtual-scroller来优化这种无限列表的场景
服务端渲染SSR或预渲染
服务端渲染是指Vue在客户端将标签渲染成的整个html片段的工作在服务端完成,服务端形成的html片段直接返回给客户端这个过程就叫做服务端渲染
1-服务端渲染的优点:
1-更好的seo:因为SPA页面的内容是通过ajax获取,而搜索引擎爬取工具并不会等待ajax异步完成后再抓取页面内容,所以在SPA中是抓取不到页面通过ajax获取到的内容,而ssr是直接由服务端返回已经渲染好的页面(数据包含在页面中),所以搜索引擎爬取工具可以抓取渲染好的页面;
2-更快的内容到达时间(首屏加载更快):SPA会等待所有Vue编译后的js文件都下载完成后,才开始进行页面的渲染,文件下载等需要一定的时间等,所以首屏渲染需要一定的时间:SSR直接由服务端渲染好页面直接返回显示,无需等待下载js文件及再去渲染等,所以SSR有更快的内容到达时间。
2-服务端渲染的缺点:
1-更多的开发条件限制:例如服务端渲染只支持beforeCreate和created俩个钩子函数,这会导致一些外部扩展库需要特殊处理,才能在服务端渲染应用程序中运行;并且与可以部署在任何静态文件服务器上的完全静态单页面应用程序SPA不同,服务端渲染应用程序,需要处于Node.js server运行环境;
2-更多的服务器负载:在node.js中渲染完整的应用程序,显然会比仅仅提供静态文件的server更加大量占用CPU资源,因此如果你预料在高流量环境下使用,请准备相应的服务器负载,并明智的采用缓存策略。