懒加载
本指南的继承自代码分离。如果你尚未阅读该指南,请先行阅读。
懒加载或者按需加载,是一种很好的优化网页或应用的方式。这种方式实际上是先把你的代码在一些逻辑断点处分离开,然后在一些代码块中完成某些操作后,立即引用或即将引用另外一些新的代码块。这样加快了应用的初始加载速度,减轻了它的总体体积,因为某些代码块可能永远不会被加载。
示例
我们在代码分离中的例子基础上,进一步做些调整来说明这个概念。那里的代码确实会在脚本运行的时候产生一个分离的代码块 lodash.bundle.js ,在技术概念上“懒加载”它。问题是加载这个包并不需要用户的交互 -- 意思是每次加载页面的时候都会请求它。这样做并没有对我们有很多帮助,还会对性能产生负面影响。

我们试试不同的做法。我们增加一个交互,当用户点击按钮的时候用 console 打印一些文字。但是会等到第一次交互的时候再加载那个代码块(print.js)。为此,我们返回到代码分离的例子中,把 lodash 放到主代码块中,重新运行代码分离中的代码 final Dynamic Imports example。

project

src/print.js文件代码:

console.log('The print.js module has loaded! See the network tab in dev tools...');
export default () => {
console.log('Button Clicked: Here's "some text"!');
}
src/index.js文件代码:

+ import _ from 'lodash';
- async function getComponent() {
+ function component() {
    var element = document.createElement('div');
-   const _ = await import(/* webpackChunkName: "lodash" */ 'lodash');
+   var button = document.createElement('button');
+   var br = document.createElement('br');
+   button.innerHTML = 'Click me and look at the console!';
    element.innerHTML = _.join(['Hello', 'webpack'], ' ');
+   element.appendChild(br);
+   element.appendChild(button);
+   // Note that because a network request is involved, some indication
+   // of loading would need to be shown in a production-level site/app.
+   button.onclick = e => import(/* webpackChunkName: "print" */ './print').then(module => {
+     var print = module.default;
+     print();
+   });
    return element;
  }
- getComponent().then(component => {
-   document.body.appendChild(component);
- });
+ document.body.appendChild(component());
注意当调用 ES6 模块的 import() 方法(引入模块)时,必须指向模块的 .default 值,因为它才是 promise 被处理后返回的实际的 module 对象。

现在运行 webpack 来验证一下我们的懒加载功能:

Administrator@PC-20190222QKVD MINGW64 /d/webpack-demo
$ npm run build
> webpack-demo@1.0.0 build D:webpack-demo
> webpack
Hash: 7843f161d852aefc1c91
Version: webpack 4.30.0
Time: 6032ms
Built at: 2019-04-30 21:15:36
          Asset       Size  Chunks             Chunk Names
  app.bundle.js   71.6 KiB       0  [emitted]  app
     index.html  189 bytes          [emitted]
print.bundle.js  252 bytes       1  [emitted]  print
Entrypoint app = app.bundle.js
[1] ./src/index.js 575 bytes {0} [built]
[2] (webpack)/buildin/global.js 472 bytes {0} [built]
[3] (webpack)/buildin/module.js 497 bytes {0} [built]
[4] ./src/print.js 165 bytes {1} [built]
    + 1 hidden module
WARNING in configuration
The 'mode' option has not been set, webpack will fallback to 'production' for this value. Set 'mode' option to 'development' or 'production' to enable defaults for each environment.
You can also set it to 'none' to disable any default behavior. Learn more: https://webpack.js.org/concepts/mode/
Child html-webpack-plugin for "index.html":
     1 asset
    Entrypoint undefined = index.html
    [2] (webpack)/buildin/global.js 472 bytes {0} [built]
    [3] (webpack)/buildin/module.js 497 bytes {0} [built]
        + 2 hidden modules
Administrator@PC-20190222QKVD MINGW64 /d/webpack-demo
$


测试点击,控制台输出如下:


框架
许多框架和类库对于如何用它们自己的方式来实现(懒加载)都有自己的建议。这里有一些例子:
React: Code Splitting and Lazy Loading
Vue: Lazy Load in Vue using Webpack's code splitting
AngularJS: AngularJS + Webpack = lazyLoad by @var_bincom

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论

微信小程序

微信扫一扫体验

立即
投稿

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部