暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Vue 性能优化方法

Geeker工作坊 2021-02-28
541

1 路由懒加载

    const router = new VueRouter({
    routes:[
    {path:'/homg', components:()=>import('./Home.vue')}
    ]
    })

    2 keep-alive 页面缓存

      <template>
      <keep-alive>
      <router-view></router-view>
      <keep-alive>
      </template>

      3 使用v-show复用DOM (v-show与v-if的区别)

      Heavy
      是一个逻辑比较重的组件。这个地方注意到v-show 与 v-if 的区别,v-show时隐藏组件显示,并没有从DOM中删除,这样就能DOM复用,从而减少渲染时间。

        <template>
        <div class="cell">
        <div v-show="value" class="on">
        <Heavy :on="1000"></Heavy>
        </div>
        <section v-show="!value" class="off">
        <Heavy :on="10000"></Heavy>
        </section>
        </div>
        </template>

        4 v-for遍历避免同时使用 v-if

        使用v-for遍历渲染时不要嵌套使用v-if控制显示,应使用过滤后的数组。

          <template>
          <ul>
          <li v-for="user in activeUsers" :key="user.id">{{user.name}}</li>
          </ul>
          </template>
          <script>
          export default {
          computed:{
          activeUsers:function(){
          return this.users.filter(item=>item.isActive)
          }
          }
          }
          </script>

          5 长列表性能优化

          • 如果列表是纯粹的数据展示,不会有任何变化,就不需要做响应式

            export default {
            data(){
            return {
            users:[]
            }
            },
            async created(){
            const users = axios.get('/api/users');
            this.users = Object.freeze(users)
            }
            }
            • 如果是大数据长列表,可采用虚拟滚动,只渲染少部分区域的内容

              <recycle-scroller
              class="items"
              :item="items"
              :item-size="24"
              >
              <template v-slot={item}>
              <FetchItemView :item="item" @vote="voteItem(item)"></FetchItemView>
              </template>
              </recycle-scroller>

              参考:vue-virtual-scroller、vue-virtual-scroll-list

              6 事件的销毁

              Vue 组件销毁式,会自动解绑他的全部指令以及事件监听器,但是仅局限于组件本身的事件。自己注册的事件一定要组件销毁前清除掉,避免引起内存泄漏。

                created(){
                this.timer = setInterval(this.refresh,200)
                }
                beforeDestory(){
                clearInterval(this.timer)
                }

                7 图片懒加载

                对于图片请求过多的页面,为了加速页面加载速度,所以很多时候需要将页面内未出现在可视区域的图片先不做加载,等到滚动到可视区域后再去加载。

                <img v-lazy="/static/img/1.png">

                参考项目 vue-lazyload

                8 第三方插件按需引入

                ElementUI
                这样的第三方组件库可以按需引入,避免体积过大。

                import Vue from 'vue';
                import {Button, Select} from 'element-ui';
                Vue.use(Button);
                Vue.use(Select);

                9 无状态组件标记为函数式组件

                <template functional>
                <div class="cell">
                   <div v-if="props.value" class="on"></div>
                   <section v-else class="off"></section>  
                 </div>
                </template>
                <script>
                export default {
                 props:['value']
                }
                </script>

                10 子组件分割

                <template>
                <div>
                   <ChildCom></ChildCom>
                 </div>
                </template>
                <script>
                export default {
                components:{
                  childCom:{
                    methods:{
                      heavy(){/*耗时任务*/}
                    },
                    render(h){
                      return h{'div',this.heavy()}
                    }
                  }
                }
                }
                </script>

                11 变量本地化(不要频繁调用响应式数据)

                <template>
                <div :style={opacity:star/300}>{{result}}</div>
                </template>
                <script>
                import {heavy} from 'utils';
                export default {
                 computed:{
                   base(){return 42},
                   result(){
                     const bast = this.base; //不要频繁引用this.base
                     let result = this.start;
                     for(let i=0;i<1000;i++){
                       retule + heavy(base);
                    }
                     return result
                  }
                }
                }
                </script>


                文章转载自Geeker工作坊,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

                评论