懒加载(按需加载)的自我总结

981 阅读5分钟

懒加载(按需加载)

官方解释: 当打包构建应用时,JavaScript 包会变得非常大,影响页面加载。如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就更加高效了。

对比理解:假设在项目中使用了五十个组件,首页只用了其中一个,在不使用懒加载的情况下,我们发现打包后的js文件只有一个,它包含了这五十个组件的相关代码;如果五十个组件49个使用了懒加载的情况,打包后的js文件就有五十个;当我们加载首页的时候,是加载“五十合一”的情况快还是五十个文件的情况呢?结果显而易见。

懒加载(按需加载)实现原理的概括

  • 将需要进行懒加载的子模块打包成独立的文件(children chunk);

  • 借助函数来实现延迟执行子模块的加载代码;利用import()将懒加载的子模块打包成独立的文件

    实现过程中,存在下面问题:

    1. 怎么保证相同的文件只加载一次?
    2. 怎么判断文件加载完成?
    3. 文件加载完成后,怎么通知所有引入文件的地方?

Vue路由懒加载

  • vue异步加载技术:

      1:vue-router配置路由,使用vue的异步组件技术,可以实现懒加载,此时一个组件会生成一个js文件。
      2:component: resolve => require(['放入需要加载的路由地址'], resolve)
     ​
     //{
     //      path: '/problem',
     //      name: 'problem',
     //      component: resolve => require(['../pages/home/problemList'], resolve)
     //}
    
  • webpack提供的require.ensure()实现懒加载:

    1. vue-router配置路由,使用webpack的require.ensure技术,也可以实现按需加载。

    2. 这种情况下,多个路由指定相同的chunkName,会合并打包成一个js文件。

    3. require.ensure可实现按需加载资源,包括js,css等。他会给里面require的文件单独打包,不会和主文件打包在一起。

      • 第一个参数是数组,表明第二个参数里需要依赖的模块,这些会提前加载。
      • 第二个是回调函数,在回调函数里面require的文件会被单独打包成一个chunk,不会和主文件打包在一起,这样就生成了两个chunk,首次加载时只加载主文件。
      • 第三个参数单独打包的chunk的文件名。
     // vue.js
     import Vue from 'vue';
     import Router from 'vue-router';
     ​
     const HelloWorld = r => require.ensure(
       ['@/components/HelloWorld'],
       () => {
         r(require('@/components/HelloWorld'))
       },
       "HelloChunk"
     )
     ​
     Vue.use('Router')
     export default new Router({
       routes: [
         {
           path: './',
           name: 'HelloWorld',
           component: HelloWorld
         }
       ]
     })
    

    import和require的比较

    • import 是解构过程并且是编译时执行
    • require 是赋值过程并且是运行时才执行,也就是异步加载
    • require的性能相对于import稍低,因为require是在运行时才引入模块并且还赋值给某个变量

组件懒加载

优先加载可见组件,其余不可见模块懒加载,待可见或即将可见时加载.

路由懒加载和组件懒加载一起更好。

组件库懒加载

团队拥有一套支撑公司业务系统的UI组件库,经过多次迭代后,组件库体积非常庞大。组件库依赖在npm上管理,组件库以项目根目录的 index.js 作为出口导出,文件中导入了项目中所有的组件。本质上是把一个组件库的不同组件拆分成不同文件,按照需要引用对应的文件,而该文件暴露一个install方法,供Vue.use使用.

组件库按需加载主要目的就是为了减少项目构建打包产物的大小,提高项目线上首屏渲染速度,减少白屏时间,减少流量消耗

webpack和组件库两者的差别主要在于:

  1. 两者执行时机不同,组件库按需加载是在源码编写阶段或者 babel 编译 js 阶段,而 webpack 懒加载则是在构建生成打包产物时,组件库按需加载在前,webpack 懒加载在后;
  2. 两者原理不同,组件库按需加载是在源码阶段就去掉了无关代码,而 webpack 懒加载则是将经过 tree-shaking 优化过后的大文件包进行拆分在适当的运行时进行按需加载。

总结

  • JavaScript 懒加载

    无论使用函数声明还是函数表达式创建函数,函数被创建后并不会立即执行函数内部的代码,只有等到函数被调用之后,才执行内部的代码。

    这其实就是懒加载的原理:

    只要将需要进行懒加载的子模块文件(children chunk)的引入语句(本文特指import())放到一个函数内部。然后再需要加载的时候执行该函数。这样就可以实现懒加载(按需加载)。这也就是是懒加载(按需加载)的原理了

  • webpack懒加载

    webpack 中,import() 语法可用作代码拆分。import() 的模块以及它引用的所有子模块,会分离到一个单独的 chunk

  • 路由懒加载

  • 组件懒加载

  • 组件库懒加载

    组件库以组件为基本单位产出 js、css、less 文件,借助插件或者部分引入的写法,使得项目代码或 babel 编译后的代码中只包含使用到的组件的 js、css、less 等。


最后一句

学习心得!若有不正,还望斧正。希望掘友们不要吝啬对我的建议。