• Webpack-CodeSplit(按需加载)


    Webpack-CodeSplit(动态文件篇)

    在静态文件处理代码切割时,我们提到了如何处理vendor以及manifest的分离,那么抛开这两点,如果在业务逻辑中,我们如何做到代码最小加载,让浏览器加载效率提速呢,这里我们就利用了webpack codesplit的另一个特性,代码按需加载打包实践方案,webpack真的是太牛逼了,推荐各位看看原码,看看打包思路以及代码实现方式。

    常规实践

    import foo from './foo';
    import bar from './bar';

    我们要使用foo,或者bar时候。我们通常按照上述方式引用,构建的效果(没有manifest)

    (window["webpackJsonp"] = window["webpackJsonp"] || []).push([
      ["app"],
      {
        /*foo*/ CKuZ: function (module, __webpack_exports__, __webpack_require__) {
          "use strict";
          __webpack_require__.r(__webpack_exports__);
          __webpack_exports__["default"] = {
            test: "111",
          };
        },
        /*入口文件*/ fhko: function (module, __webpack_exports__, __webpack_require__) {
          "use strict";
          __webpack_require__.r(__webpack_exports__);
          var _foo__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("CKuZ");
          var _bar__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("tRux");
        },
        /*bar*/ tRux: function (module, __webpack_exports__, __webpack_require__) {
          "use strict";
          __webpack_require__.r(__webpack_exports__);
          __webpack_exports__["default"] = function () {
            console.log("this is bar");
          };
        },
      },
      [["fhko", "manifest"]],
    ]);

    三个文件分配了三个名称,入口文件以webpack规则"webpack_require_"模块加载bar跟foo,从bundle中很清晰的看到三个文件彼此的规则,至于怎么调用的,就看manifest输出文件吧,简单来讲,就是遍历 window["webpackJsonp"] ,然后挨个记录到modules中,并执行。重点来了,我们不一定非要引入foo,跟bar呢,按需求引入呢,比如一个button触发的回调函数,比如路由的正则匹配路径渲染呢。还需要浏览器一并加载吗?并不是,写法如下。

    import("./foo")
      .then((res) => {
        console.log(res);
      })
      .catch((e) => {
        console.log(e);
      });
    
    setTimeout(function () {
      import("./bar")
        .then((res) => {
          console.log(res);
        })
        .catch((e) => {
          console.log(e);
        });
    }, 3000);

    采用动态加载的方式,按需引入目标组件。我们看下效果

     三秒之后出现

    达到了我们的目的。这样做可以减少浏览器加载js的体积,从而提升页面效率。

    bundle.js

    (window["webpackJsonp"] = window["webpackJsonp"] || []).push([["app"],{
     "fhko": (function(module, exports, __webpack_require__) {
    __webpack_require__.e(/*! import() */ 1).then(__webpack_require__.bind(null, /*! ./foo */ "CKuZ"))
      .then((res) => {
        console.log(res);
      })
      .catch((e) => {
        console.log(e);
      });
    setTimeout(function () {
      __webpack_require__.e(/*! import() */ 0).then(__webpack_require__.bind(null, /*! ./bar */ "tRux"))
        .then((res) => {
          console.log(res);
        })
        .catch((e) => {
          console.log(e);
        });
    }, 3000);
    /***/ })
    },[["fhko","manifest"]]]);

    通过webpackRequire加载动态文件。

    webpackRequire实现方式,这里做了一个简化版

    __webpack_require__.e = function requireEnsure(chunkId) {
        var promises = [];
        var promise = new Promise(function (resolve, reject) {
          installedChunkData = installedChunks[chunkId] = [resolve, reject];
        });
        promises.push((installedChunkData[2] = promise));
        var script = document.createElement("script");
        var onScriptComplete;
    
        script.charset = "utf-8";
        script.timeout = 120;
        if (__webpack_require__.nc) {
          script.setAttribute("nonce", __webpack_require__.nc);
        }
        script.src = jsonpScriptSrc(chunkId);
        document.head.appendChild(script);
        return Promise.all(promises);
      }; 

    加载的目标文件写入head,浏览器引入目标文件,然后返回promise数组。还是很容易理解的。

    webpack输出文件列表

     看上去有点迷~如何改进下,至少让我们知道哪个文件是哪个啊,不能阿拉伯数字啊,改进如下

    import(/* webpackChunkName: "foo" */ "./foo")
      .then((res) => {
        console.log(res);
      })
      .catch((e) => {
        console.log(e);
      });
    
    setTimeout(function () {
      import(/* webpackChunkName: "bar" */ "./bar")
        .then((res) => {
          console.log(res);
        })
        .catch((e) => {
          console.log(e);
        });
    }, 3000);

    输入文件列表

    这回清晰了很多。

    除了import可以实现动态加载,常用的方式还有require.ensure方式。有兴趣的可以自己实践一下。

    此特性好处

    按需加载,提高浏览器加载脚本文件速度,减少一次性加载的体积。

    此特性优化场景

    • 微前端架构设计,工程级别懒加载

    • 模块路由按需加载

    • 页面业务需求按需加载

    好处还是大大滴,希望有性趣的可以自己实践一下,毕竟优化才是王道啊。

     

     

     

  • 相关阅读:
    pyhton 线程锁
    python 守护线程
    python 线程
    python 判断文件的字符编码
    python 进程管道
    python 进程池
    webpack学习(一)起步安装
    最近特别喜欢的一首歌
    你真的了解回流和重绘吗?
    你了解SEO中的时效性吗?
  • 原文地址:https://www.cnblogs.com/moran1992/p/12882623.html
Copyright © 2020-2023  润新知