vue优化性能的方法,vue提高性能
一般来说,你不需要太在意vue的运行时性能。它运行速度很快,但代价是初始化相对较慢。下面这篇文章主要介绍Vue开发中的十二个性能优化小技巧,有需要的朋友可以参考一下。
目录
前言1。长列表性能优化1。没有回应2。虚拟滚动2。v-for遍历,避免同时使用v-if3。使用唯一键的列表4。用v-show 5复用DOM5。使用功能组件的无状态组件。子组件划分7。变量本地化8。按需引入的第三方插件9。路由延迟加载10。保持活力。
前言
性能优化是每个开发者都会遇到的问题,尤其是在越来越强调体验,竞争越来越激烈的环境下。对于我们开发者来说,仅仅完成迭代,做好功能是远远不够的。最重要的是把产品做好,让更多人愿意用,让用户更好用。这不也是我们开发者价值和能力的体现吗?
关注性能问题,优化产品体验,比修复几个无关痛痒的bug要有价值得多。
这篇文章记录了我在Vue项目日常开发中的一些小技巧。事不宜迟,我们开始吧。
1. 长列表性能优化
1. 不做响应式
比如会员名单,商品清单等。都只是单纯的数据展示。当不会有动态变化时,不需要响应数据,可以大大提高渲染速度。
比如用Object.freeze()来冻结一个对象,MDN的描述是用这个方法冻结的对象是不能修改的;也就是不能给这个对象添加新的属性,不能删除现有的属性,不能修改这个对象现有属性的可枚举性、可配置性、可写性,不能修改现有属性的值,不能修改这个对象的原型。
导出默认值{
数据:()=({
用户列表:[]
}),
异步创建的(){
const users=await axios . get(/API/users );
this.userList=Object.freeze(用户);
}
};
vue 2:src/core/observer/index . js-144行的响应源地址是这样的
导出函数defineReactive(.){
const property=object . getownpropertydescriptor(obj,key)
if(property property . configurable===false){
返回
}
.
}
可以看出,从一开始就判断为假的直接退货并没有以响应的方式进行处理。
可配置值为false表示该属性不能修改,而冻结对象的可配置值为false。
在Vue3中,增加了响应标志来标记目标对象类型。
2. 虚拟滚动
如果是一个很长的大数据列表,如果全部渲染的话,一次创建太多的DOM会非常困难。这时可以使用虚拟滚动,只渲染一小部分内容(包括可视区域),然后在滚动时不断替换可视区域的内容,模拟滚动效果。
循环滚动器
class=items
:items=items
:item-size=24
模板v-slot=“{ item }”
FetchItemView
:item=item
@vote=voteItem(item)
/
/模板
/recycle-滚动条
参见vue虚拟滚动,vue虚拟滚动列表。
原理是监控滚动事件,动态更新需要显示的DOM,计算视图中的位移,这也意味着滚动过程需要实时计算,有一定的开销,所以如果数据量不是很大,就用普通滚动。
2. v-for 遍历避免同时使用 v-if
为什么避免同时使用v-for和v-if?
在Vue2中,v-for的优先级更高,所以在编译过程中会遍历所有列表元素生成虚拟DOM,然后由v-if渲染合格的,这样会造成性能的浪费,因为我们希望不要生成不合格的虚拟DOM。
在Vue3中,v-if的优先级更高,也就是说当判断条件是v-for遍历的列表中的属性时,v-if是无法获取的。
所以在一些需要同时使用的场景中,可以通过计算属性来过滤列表,如下所示
模板
保险商实验所
Li v-for= active list中的项目:key=item.id
{{ item.title }}
/李
/ul
/模板
脚本
//Vue2.x
导出默认值{
计算值:{
activeList() {
返回this.list.filter( item={
返回item.isActive
})
}
}
}
//Vue3
从“vue”导入{ computed };
const activeList=computed(()={
返回list.filter( item={
返回item.isActive
})
})
/脚本
3. 列表使用唯一 key
例如,如果你有一个列表,我们需要在中间插入一个元素。不使用key或者index作为key会怎么样?先看一张图。
图中所示的Li1和li2不会重新渲染,这一点没有争议。并且li3、li4和li5将被重新渲染。
因为当列表的key或者index不作为key时,每个元素对应的位置关系都是index,上图中的结果直接导致插入的元素和所有后续元素对应位置关系的变化,所以在补丁过程中会全部更新,然后重新渲染。
这不是我们想要的。我们要的是渲染添加的元素,其他四个元素不应该不做任何改动就重新渲染。
在使用唯一键的情况下,对应于每个元素的位置关系是关键。让我们看一下使用唯一键值的情况。
这样图中的li3和li4就不会重新渲染了,因为元素的内容没有变,对应的位置关系也没有变。
这也是为什么v-for一定要写key,开发中不建议使用数组的index作为key。
4. 使用 v-show 复用 DOM
V-show:渲染组件,然后将组件的显示改为block或none v-if:渲染或不渲染组件。
所以对于条件可以频繁变化的场景,用v-show来节省性能,尤其是DOM结构越复杂,好处越大。
但是它也有一个缺点,就是在v-show开始的时候会渲染分支内部的所有组件,执行相应的生命周期钩子函数,而v-if只会加载判断条件命中的组件,所以需要根据不同的场景使用合适的指令。
比如下面用v-show复用DOM就比v-if/v-else好。
模板
差异
div v-show=status class=on
我的-组件/
/div
第五节-show=!状态 class=off
我的组件
/部分
/div
/模板
原理是当条件改变时,使用v-if来触发diff更新。如果发现新旧vnode不一致,就把整个旧VNODe去掉,然后重新创建一个新的VNODe,再创建一个新的my-components组件,要经历组件初始化、渲染、打补丁等过程。当条件发生变化时,新老VNODes是一致的,因此不会执行删除和创建等一系列过程。
5. 无状态的组件用函数式组件
对于一些没有响应数据、状态管理和生命周期钩子功能的纯显示组件,我们可以将其设置为功能组件来提高渲染性能,因为它们会被当作一个函数来处理,所以开销很低。
原理是补丁过程中功能组件渲染生成的虚拟DOM不会有递归子组件初始化的过程,所以渲染开销会低很多。
它可以接受props,但是因为它不会创建实例,所以它不能在内部使用this.xx来获取组件属性,编写如下
模板功能
差异
div class= content“{ value } }/div
/div
/模板
脚本
导出默认值{
道具:[值]
}
/脚本
//或者
Vue.component(我的组件,{
Functional: true,//表示该组件是一个功能组件。
道具:{.},//可选
//第二个参数是上下文,没有这个
render: function (createElement,context) {
//.
}
})
6. 子组件分割
我们先来看一个例子。
模板
div:style= { opacity:number/100 }
div{{ someThing() }}/div
/div
/模板
脚本
导出默认值{
道具:[数字],
方法:{
SomeThing () {/*耗时的任务*/}
}
}
/脚本
在上面的代码中,每次父组件传递的数字发生变化,都会重新渲染一次,某件事的耗时任务也会重新执行一次。
因此,优化的一个方法是使用计算属性,因为计算属性本身具有缓存计算结果的特性。
第二个被分割成子组件,因为Vue的更新是组件粒度的。虽然每次数据变化都会导致父组件的重新渲染,但是子组件不会重新渲染,因为其内部没有变化,耗时的任务自然不会重新执行,所以性能更好。优化代码如下
模板
差异
我的孩子/
/div
/模板
脚本
导出默认值{
组件:{
我的孩子:{
方法:{
SomeThing () {/*耗时的任务*/}
},
渲染(h) {
返回h(div ,this.someThing())
}
}
}
}
/脚本
7. 变量本地化
简单来说就是保存会被多次引用的变量,因为每次访问this.xx时,因为是响应式对象,所以每次都会触发getter,然后执行dependency收集的相关代码。变量用的次数多了,性能自然就差了。
从需求的角度来说,一次收集一个函数中变量的依赖关系就足够了。但是很多人在大量的项目中习惯性的写this.xx,而忽略了this.xx背后做了什么,这样就会导致性能问题。
例如下面例子。
模板
div:style= { opacity:number/100 } { { result
} }/分区
/模板
脚本
从“@/utils”导入{ someThing }
导出默认值{
道具:[数字],
计算值:{
base () { return 100 },
结果(){
设base=this.base,number=this.number //
省省吧。
for(设I=0;i 1000i ) {
Number=someThing(base) //避免频繁引用
this.xx
}
退货数量
}
}
}
/脚本
8. 第三方插件按需引入
比如可以按需引入Element-UI这样的第三方组件库,避免过于庞大,尤其是项目不大的时候,没有必要完全引入组件库。
//main.js
从“plugins/element3”导入element 3;
Vue.use(元素3)
//element3.js
//完整介绍
从“element3”导入element 3;
导入“element 3/lib/theme-chalk/index . CSS”;
//按需引入
//导入“element 3/lib/theme-chalk/button . CSS”;
//.
//导入{
//ElButton,
//ElRow,
//ElCol,
//ElMain,
//.
//}来自“element 3”;
导出默认功能(应用程序){
//完整介绍
app.use(元素3)
//按需引入
//app . use(El button);
}
9. 路由懒加载
我们知道Vue是单页应用,所以如果不使用懒加载,会导致进入首页时加载的内容太多。时间过长会出现长时间的白屏,不利于用户体验,SEO也不友好。
所以你可以用懒加载来划分页面,只在需要的时候加载相应的页面,这样可以分担首页的加载压力,减少首页的加载时间。
未加载路由延迟:
从“@/components/Home”导入个人主页
const router=new VueRouter({
路线:[
{路径:“/home”,组件:Home }
]
})
加载了惰性路由:
const router=new VueRouter({
路线:[
{ path:“/home”,组件:()=
导入( @/components/Home) },
{路径:“/login”,组件:
需要( @/components/Home )。默认}
]
})
当你进入这个路径的时候,你会取相应的组件,然后运行import编译加载组件,可以理解为Promise的resolve机制。
导入:Es6语法规范,编译时调用,解构过程,不支持变量函数等。要求:AMD规范,运行时调用,赋值过程,支持变量计算函数等。关于前端模块化的更多信息,请参考我的另一篇文章,前端模块化规范的详细概述。
10. keep-alive缓存页面
比如表单输入页面进入下一步后,返回上一步到表单页面时需要保留表单输入内容,比如在列表页详情页来回跳转的场景。
我们可以通过内置的组件keep-alive/keep-alive来缓存组件,在组件切换时不卸载,这样当再次返回时,可以从缓存中快速渲染而不是重新渲染,从而节省性能。
您只需要包装想要缓存的组件。
模板
div id=应用程序
点火电极
路由器-视图/
/保持活力
/div
/模板
还可以使用include/exclude来缓存/不缓存指定的组件。当前组件状态可以通过两个生命周期获得:激活/停用。
11. 事件的销毁
某视频剪辑软件组件销毁时,会自动解绑它的全部指令及事件监听器,但是仅限于组件本身的事件
而对于定时器、addEventListener注册的监听器等,就需要在组件销毁的生命周期钩子中手动销毁或解绑,以避免内存泄露
脚本
导出默认值{
已创建(){
这个。timer=setInterval(这个。刷新,2000年)
addEventListener(touchmove ,
this.touchmove,false)
},
销毁前(){
clearInterval(this.timer)
this.timer=null
removeEventListener(touchmove ,
this.touchmove,false)
}
}
/脚本
12. 图片懒加载
图片懒加载就是对于有很多图片的页面,为了提高页面加载速度,只加载可视区域内的图片,可视区域外的等到滚动到可视区域后再去加载
这个功能一些用户界面框架都有自带的,如果没有呢?
推荐一个第三方插件懒惰负载
npm i vue-lazyload -S
//main.js
从“vue-lazy加载”导入VueLazyload
Vue.use(VueLazyload)
//接着就可以在页面中使用懒惰懒加载图片了
img v-lazy=/static/images/1。巴布亚新几内亚
或者自己造轮子,手动封装一个自定义指令,这里封装好了一个兼容各浏览器的版本的,主要是判断浏览器支不支持IntersectionObserverAPI,支持就用它实现懒加载,不支持就用监听卷起事件节流的方式实现
const LazyLoad={
//安装方法
安装(Vue,选项){
常量默认值Src=选项.默认值
Vue.directive(lazy ,{
bind(el,binding) {
LazyLoad.init(el,binding.value,defaultSrc)
},
已插入(el) {
if(相交观察点){
懒蛋,观察
}否则{
LazyLoad.listenerScroll
}
},
})
},
//初始化
init(el,val,def) {
el.setAttribute(data-src ,val)
el.setAttribute(src ,def)
},
//利用交叉观测器监听埃尔
观察(el) {
var io=new IntersectionObserver((条目)={
const realSrc=el.dataset.src
如果(条目[0]。正在交叉
if (realSrc) {
el.src=realSrc
el.removeAttribute(data-src )
}
}
})
io。观察(el)
},
//监听卷起事件
listenerScroll(el) {
常量处理程序=
懒惰负载。节流阀(300)
LazyLoad.load
窗户。addevent侦听器( scroll ,()={
处理器(el)
})
},
//加载真实图片
负载(el) {
常量窗口高度=
文档。文档元素。客户身高
const El top=El。getboundingclientrect().顶端
const elBtm=
el.getBoundingClientRect().底部
const realSrc=el.dataset.src
if (elTop - windowHeight 0 elBtm 0) {
if (realSrc) {
el.src=realSrc
el.removeAttribute(data-src )
}
}
},
//节流
节气门(fn,延迟){
让计时器
让时光倒流
返回函数(.args) {
const currTime=Date.now()
常量上下文=这个
如果(!prevTime) prevTime=currTime
清除超时(定时器)
如果(当前时间-前一时间延迟){
prevTime=currTime
应用(上下文,参数)
清除超时(定时器)
返回
}
timer=setTimeout(function () {
prevTime=Date.now()
计时器=空
应用(上下文,参数)
},延迟)
}
},
}
导出默认延迟加载
使用上是这样的,用v-LazyLoad代替科学研究委员会
img v-LazyLoad=xxx.jpg /
总结
到此这篇关于某视频剪辑软件开发中性能优化小技巧的文章就介绍到这了,更多相关某视频剪辑软件开发性能优化小技巧内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。