前端页面性能优化

前端Vue工程的性能优化笔记。

Vue页面优化

v-for优化

不在同一级使用v-for、v-if

当v-if与v-for一起使用时,v-for具有比v-if更高的优先级,这意味着v-if将分别重复运行于每个v-for循环中

要避免出现这种情况,则在外层嵌套template,在这一层进行v-if判断,然后在内部进行v-for循环,如果条件出现在循环内部,可通过计算属性提前过滤掉那些不需要显示的项。

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<!DOCTYPE html> 
<html>
<head>
   <title>Vue事件处理</title>
</head>
<body>
   <div id="demo">
       <h1>v-for和v-if谁的优先级高?应该如何正确使用避免性能问题?</h1>
<!-- <p v-for="child in children" v-if="isFolder">{{child.title}}</p> -->
       <template v-if="isFolder">
           <p v-for="child in children">{{child.title}}</p>
       </template>
   </div>
   <script src="../../dist/vue.js"></script>
   <script>
       // 创建实例
       const app = new Vue({
el: '#demo',
           data() {
               return {
                   children: [
                      {title:'foo'},
                      {title:'bar'},
                  ]
              }
          },
           computed: {
               isFolder() {
                   return this.children && this.children.length > 0              
}
          },
      });
       console.log(app.$options.render);
   </script>
</body>
</html>

两者同级时,渲染函数如下:

1
2
3
4
5
6
7
8
9
10
(function anonymous(
) {
with (this) {
return _c('div', { attrs: { "id": "demo" } }, [_c('h1', [_v("v-for和v-if谁的优先 级高?应该如何正确使用避免性能问题?")]), _v(" "),
_l((children), function (child) {
return (isFolder) ? _c('p',
[_v(_s(child.title))]) : _e()
})], 2)
}
})

两者不同级时,渲染函数如下:

1
2
3
4
5
6
7
8
9
10
(function anonymous(
) {
with (this) {
return _c('div', { attrs: { "id": "demo" } }, [_c('h1', [_v("v-for和v-if谁的优先 级高?应该如何正确使用避免性能问题?")]), _v(" "),
(isFolder) ? _l((children), function (child) {
return _c('p',
[_v(_s(child.title))])
}) : _e()], 2)
}
})

v-for的key值

Vue 的 v-for 为什么要加 key

注意:不建议使用index作为key值

示例:

1
2
3
4
5
         下标
1. 前天 0
2. 昨天 1
3. 今天 2
4. 明天 3

假设我们删除了List中下标为1的数据:

1
2
3
4
         下标
1. 前天 0
2. 今天 1
3. 明天 2

我们可以发现,除了第一个数据以外,其余数据的下标均发生了变化。以前的数据和重新渲染后的数据随着key值的变化从而没法建立关联关系,这就失去了key值存在的意义。

长列表性能优化

当你把一个普通的JavaScript对象传给Vue实例的data选项,Vue将遍历此对象所有的属性,并使用Object.defineProperty把这些属性全部转为getter/setter,这些getter/setter对用户来说是不可见的,但是在内部它们让Vue追踪依赖,在属性被访问和修改时通知变化。

然而有些时候我们的组件就是纯粹的数据展示,不会有任何改变,我们就不需要Vue来劫持我们的数据,在大量数据展示的情况下,这能够很明显的减少组件初始化的时间,那如何禁止Vue劫持我们的数据呢?可以通过Object.freeze方法来冻结一个对象,一旦被冻结的对象就再也不能被修改了。

示例:

1
2
3
4
5
6
7
8
9
export default {
data: () => ({
users: {}
}),
async created() {
const users = await axios.get("/api/users");
this.users = Object.freeze(users);
}
};

Object.freeze()可以冻结一个对象。一个被冻结的对象再也不能被修改;不能向这个对象添加新的属性,不能删除已有属性,不能修改该对象已有属性的可枚举性、可配置性、可写性,以及不能修改已有属性的值。此外,冻结一个对象后该对象的原型也不能被修改。

未完待续…

参考


----------- 本文结束啦感谢您阅读 -----------

赞赏一杯咖啡

欢迎关注我的其它发布渠道