50+Vue经典面试题源码级详解(25)

·  阅读 5600
50+Vue经典面试题源码级详解(25)

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第2天,点击查看活动详情

前言

小伙伴们好,这是村长《Vue经典面试题源码级详解》系列文章第25题,前面已完成题目合集在此: 历时一个月,2.6W字!50+Vue经典面试题源码级详解,你值得收藏!

学习群

我组织了一个面试学习群,关注村长公众号村长学前端,回复“加群”,大家一起卷~

相关学习资源

本系列有配套视频思维导图开源项目,大家学习同时千万不要忘了三连 + 关注 + 分享,有道是喝水不忘挖井人~

你了解哪些Vue性能优化方法?

分析

这是一道综合实践题目,写过一定数量的代码之后小伙伴们自然会开始关注一些优化方法,答得越多肯定实践经验也越丰富,是很好的题目。

答题思路:

根据题目描述,这里主要探讨Vue代码层面的优化

回答范例

  • 我这里主要从Vue代码编写层面说一些优化手段,例如:代码分割、服务端渲染、组件缓存、长列表优化等
  • 最常见的路由懒加载:有效拆分App尺寸,访问时才异步加载

    const router = createRouter({
      routes: [
        // 借助webpack的import()实现异步组件
        { path: '/foo', component: () => import('./Foo.vue') }
      ]
    })
    复制代码
  • keep-alive缓存页面:避免重复创建组件实例,且能保留缓存组件状态

    <router-view v-slot="{ Component }">
      <keep-alive>
        <component :is="Component"></component>
      </keep-alive>
    </router-view>
    复制代码
  • 使用v-show复用DOM:避免重复创建组件

    <template>
      <div class="cell">
        <!-- 这种情况用v-show复用DOM,比v-if效果好 -->
        <div v-show="value" class="on">
          <Heavy :n="10000"/>
        </div>
        <section v-show="!value" class="off">
          <Heavy :n="10000"/>
        </section>
      </div>
    </template>
    复制代码
  • v-for 遍历避免同时使用 v-if:实际上在Vue3中已经是个错误写法

    <template>
        <ul>
          <li
            v-for="user in activeUsers"
            <!-- 避免同时使用,vue3中会报错 -->
            <!-- v-if="user.isActive" -->
            :key="user.id">
            {{ user.name }}
          </li>
        </ul>
    </template>
    <script>
      export default {
        computed: {
          activeUsers: function () {
            return this.users.filter(user => user.isActive)
          }
        }
      }
    </script>
    复制代码
  • v-once和v-memo:不再变化的数据使用v-once

    <!-- single element -->
    <span v-once>This will never change: {{msg}}</span>
    <!-- the element have children -->
    <div v-once>
      <h1>comment</h1>
      <p>{{msg}}</p>
    </div>
    <!-- component -->
    <my-component v-once :comment="msg"></my-component>
    <!-- `v-for` directive -->
    <ul>
      <li v-for="i in list" v-once>{{i}}</li>
    </ul>
    复制代码

    按条件跳过更新时使用v-momo:下面这个列表只会更新选中状态变化项

    <div v-for="item in list" :key="item.id" v-memo="[item.id === selected]">
      <p>ID: {{ item.id }} - selected: {{ item.id === selected }}</p>
      <p>...more child nodes</p>
    </div>
    复制代码

    vuejs.org/api/built-i…

  • 长列表性能优化:如果是大数据长列表,可采用虚拟滚动,只渲染少部分区域的内容

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

    一些开源库:

  • 事件的销毁:Vue 组件销毁时,会自动解绑它的全部指令及事件监听器,但是仅限于组件本身的事件。

    export default {
      created() {
        this.timer = setInterval(this.refresh, 2000)
      },
      beforeUnmount() {
        clearInterval(this.timer)
      }
    }
    复制代码
  • 图片懒加载

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

    <img v-lazy="/static/img/1.png">
    复制代码

    参考项目:vue-lazyload

  • 第三方插件按需引入

    element-plus这样的第三方组件库可以按需引入避免体积太大。

    import { createApp } from 'vue';
    import { Button, Select } from 'element-plus';
    ​
    const app = createApp()
    app.use(Button)
    app.use(Select)
    复制代码
  • 子组件分割策略:较重的状态组件适合拆分

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

    但同时也不宜过度拆分组件,尤其是为了所谓组件抽象将一些不需要渲染的组件特意抽出来,组件实例消耗远大于纯dom节点。参考:vuejs.org/guide/best-…

  • 服务端渲染/静态网站生成:SSR/SSG

    如果SPA应用有首屏渲染慢的问题,可以考虑SSR、SSG方案优化。参考SSR Guide

时间有限,如有考虑不周欢迎小伙伴们留言补充!

分类:
前端
收藏成功!
已添加到「」, 点击更改