vue组件代码分块和懒加载讲解

 更新时间:2022年4月11日 15:57  点击:223 作者:刘文壮

前端开发中,随着业务和页面增加,以组件为基本单位的结构下,组件数量会增长极快,为了优化我们会很显然地想要进行一些工作:

  • 代码分块
  • 懒加载非必要资源文件

非必要资源,指的首次渲染出某页面所不必要的资源,如因为用户操作才出现的图片、弹窗等。

代码分块和懒加载在页面层面具有极大的优化作用,用户很可能只是浏览dashboard页面,可能根本就不会去看详情等页面,那我们就不必将详情页面的代码和dashboard页面代码混在一起,用户看某个页面时只加载那个页面对应的资源即可,可以较大地提升用户体验。本文就在Vue工程下如何在组件层面配置代码分块和懒加载进行讲解。

本文在@vue/cli 3以上版本。

懒加载组件

一般来说,Vue中使用某组件过程大致如下:

<script>
// Home.vue
import HelloWorld from '@/components/HelloWorld.vue'
export default {
  components: {
    HelloWorld,
  },
}
</script>

这是我们最熟悉的方式了,我们在访问Home.vue时,Webpack为我们保证了HelloWorld.vue一定是存在的,这是由依赖关系决定的(Home.vue依赖于HelloWorld.vue)。

这很正常对吧,但是如果HelloWorld.vue是非必要资源呢,比如需要用户点击一个按钮才会出现的弹窗或者是默认隐藏的内容,只当某些条件触发时才出现的页面区域呢?如果是上述情况,当我们访问Home.vue时显然没必要马上就将HelloWorld.vue请求过来,而且配置方法也及其简单:

<template>
  <div class="home">
    <button @click="() => showHello = true">Hello</button>
    <HelloWorld v-if="showHello" />
  </div>
</template>

<script>
// Home.vue
export default {
  components: {
    HelloWorld: () => import('@/components/HelloWorld.vue'),  // A
  },
  data() {
    return {
      showHello: false,
    }
  },
}
</script>

只需像A行一样简单处理一下即可一举两得:HelloWorld.vue会被打包成独立为单独的js文件,而且只有当我们点击按钮时,这个独立的js文件才会被请求,这样能够减小主代码块的体积。

简单分析一下:import()会返回一个组件Promise,现在基本上所有的打包工具都理解此语法,而且还会触发Webpack的代码分块(Webpack 2之后)。

注意:Vue不会在意某个组件,直到它要被渲染出来。以上例来说,只有当我们触发了按钮,HelloWorld.vue才有了意义。

即使所有组件都可以配置懒加载,但是别滥用,大部分情况下只对非必要资源配置懒加载即可,像上例如果HelloWorld.vue是Home.vue中是一直存在的,那样配置懒加载可能会适得其反,加载了Home.vue对应的js文件后会马上请求HelloWorld.vue对应的js文件,如果HelloWorld.vue对应的js文件比较小,那得到的收益可能不足以抵消一次http请求带来的消耗。

问题与解决方案

组件懒加载虽然好处极多,但仍有缺陷,如上例点击按钮后需等待HelloWorld.vue对应的js文件被请求执行后页面才会做出相应变化,这就涉及到加载状态和错误状态的处理(虽然一般情况下不会有问题,因为都是些小文件,加载极快,但也有例外),所幸Vue也为我们考虑到了这些:

加载中组件

<script>
// Home.vue
import LoadingComponent from '@/components/Loading'
export default {
  components: {
    HelloWorld: () => ({
      component: import('@/components/HelloWorld.vue'),
      loading: LoadingComponent,  // 加载HelloWorld.vue对应js文件中展示
      delay: 300,                 // loading的延迟生效时间
    }),
  },
  data() {
    return {
      showHello: false,
    }
  },
}
</script>

从用户体验方面来说,般来说500ms内的响应时间还不至于失去用户的注意力,所以可以为loading配置一个延迟时间,默认200ms内加载完成不会出现loading,当然也可以像上面一样手动设置一下delay,单位ms。

错误处理组件

<script>
// Home.vue
import ErrorComponent from '@/components/Error'
export default {
  components: {
    HelloWorld: () => ({
      component: import('@/components/HelloWorld.vue'),
      error: ErrorComponent,  // 加载HelloWorld.vue对应js文件失败时展示,如文件不存在
      timeout: 2000,          // 文件加载的超时时间,超出时间未加载完成,会触发ErrorComponent
    }),
  },
  data() {
    return {
      showHello: false,
    }
  },
}
</script>

出现错误的情形主要有以下几点:

  • 网络连接不通 / 服务器错误
  • 文件不存在(特别注意重新部署后之前版本的文件被删除,而用户还未刷新页面)
  • 加载超时(默认是没有超时时间的,不过可以像上面一样通过timeout属性配置,单位ms)

preload 和 prefetch

Vue还为资源文件配置了预加载策略,即使用<link rel="prefetch">和<link rel="preload">策略,在build后的index.html文件中或者开发模式下浏览器的Network面板里可以具体查看。关于两者的具体用法这里就不赘述了,这里说一下两者差异之处:preload的优先级比prefetch的高,一般来说当前页面的必要资源可以使用preload策略,当前页面的非必要资源和其他页面的资源使用prefetch策略。

通过配置资源预加载,浏览器为我们预先预先加载资源,在用户用到某些资源时可以及时响应,可以在提升首次加载性能的同时为用户后续的操作提供良好的体验。

prefetch在Safari中暂时还不支持,所以懒加载在Safari中表现地相对较差。

总结

Vue中使用懒加载和代码分块对产品进行优化,简单实用,但是这其中存在着权衡,如果项目较小,打包文件并不大,则可能不需要进行代码分块和懒加载,毕竟http请求也是挺贵的。

当项目较大时,使用懒加载和代码分块就可以显著地提升性能,但是同样注意那需要由后来的请求弥补的,但所幸目前大部分浏览器都支持资源预加载策略,搭配使用效果更佳。

  • 异步组件
  • preload
  • Safari prefetch
  • Safari preload

以上为个人经验,希望能给大家一个参考,也希望大家多多支持猪先飞。

原文出处:https://blog.csdn.net/u010730126/article/details/103703940

[!--infotagslink--]

相关文章

  • vue中activated的用法

    这篇文章主要介绍了vue中activated的用法,帮助大家更好的理解和使用vue框架,感兴趣的朋友可以了解下...2021-01-03
  • 基于vue-simple-uploader封装文件分片上传、秒传及断点续传的全局上传插件功能

    这篇文章主要介绍了基于vue-simple-uploader封装文件分片上传、秒传及断点续传的全局上传插件,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-02-23
  • Antd-vue Table组件添加Click事件,实现点击某行数据教程

    这篇文章主要介绍了Antd-vue Table组件添加Click事件,实现点击某行数据教程,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-11-17
  • vue 实现动态路由的方法

    这篇文章主要介绍了vue 实现动态路由的方法,文中示例代码非常详细,帮助大家更好的理解和学习,感兴趣的朋友可以了解下...2020-07-06
  • vue 监听 Treeselect 选择项的改变操作

    这篇文章主要介绍了vue 监听 Treeselect 选择项的改变操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-09-01
  • Vue基于localStorage存储信息代码实例

    这篇文章主要介绍了Vue基于localStorage存储信息代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-11-16
  • Vue组件跨层级获取组件操作

    这篇文章主要介绍了Vue组件跨层级获取组件操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-07-28
  • vue 获取到数据但却渲染不到页面上的解决方法

    这篇文章主要介绍了vue 获取到数据但却渲染不到页面上的解决方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-11-19
  • antdesign-vue结合sortablejs实现两个table相互拖拽排序功能

    这篇文章主要介绍了antdesign-vue结合sortablejs实现两个table相互拖拽排序功能,本文通过实例图文相结合给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-01-09
  • vuejs element table 表格添加行,修改,单独删除行,批量删除行操作

    这篇文章主要介绍了vuejs element table 表格添加行,修改,单独删除行,批量删除行操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-07-18
  • vue项目多环境配置(.env)的实现

    最常见的多环境配置,就是开发环境配置,和生产环境配置,本文主要介绍了vue项目多环境配置的实现,感兴趣的可以了解一下...2021-07-20
  • vue项目页面嵌入代码块vue-prism-editor的实现

    这篇文章主要介绍了vue项目页面嵌入代码块vue-prism-editor的实现,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2020-10-30
  • Vue中slot-scope的深入理解(适合初学者)

    这篇文章主要给大家介绍了关于Vue中slot-scope的深入理解,这个教程非常适合初学者,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-04-17
  • vue treeselect获取当前选中项的label实例

    这篇文章主要介绍了vue treeselect获取当前选中项的label实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-09-01
  • Vue 3.0中jsx语法的使用

    这篇文章主要介绍了Vue 3.0 中 jsx 语法使用,帮助大家更好的理解和使用vue框架,感兴趣的朋友可以了解下...2020-11-13
  • 解决vue的router组件component在import时不能使用变量问题

    这篇文章主要介绍了解决vue的router组件component在import时不能使用变量问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-07-27
  • vue实现同时设置多个倒计时

    这篇文章主要为大家详细介绍了vue实现同时设置多个倒计时,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-05-20
  • vue Treeselect下拉树只能选择第N级元素实现代码

    这篇文章主要介绍了vue Treeselect下拉树只能选择第N级元素实现代码,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-09-01
  • vue实现div单选多选功能

    这篇文章主要为大家详细介绍了vue实现div单选多选功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-07-16
  • Ant design vue table 单击行选中 勾选checkbox教程

    这篇文章主要介绍了Ant design vue table 单击行选中 勾选checkbox教程,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-10-25