懒加载

本指南的继承自代码分离。如果你尚未阅读该指南,请先行阅读。

懒加载或者按需加载,是一种很好的优化网页或应用的方式。这种方式实际上是先把你的代码在一些逻辑断点处分离开,然后在一些代码块中完成某些操作后,立即引用或即将引用另外一些新的代码块。这样加快了应用的初始加载速度,减轻了它的总体体积,因为某些代码块可能永远不会被加载。

示例

我们在代码分离中的例子基础上,进一步做些调整来说明这个概念。那里的代码确实会在脚本运行的时候产生一个分离的代码块 lodash.bundle.js ,在技术概念上“懒加载”它。问题是加载这个包并不需要用户的交互 — 意思是每次加载页面的时候都会请求它。这样做并没有对我们有很多帮助,还会对性能产生负面影响。

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

project

  1. webpack-demo
  2. |- package.json
  3. |- webpack.config.js
  4. |- /dist
  5. |- /src
  6. |- index.js
  7. + |- print.js
  8. |- /node_modules

src/print.js

  1. console.log('The print.js module has loaded! See the network tab in dev tools...');
  2. export default () => {
  3. console.log('Button Clicked: Here\'s "some text"!');
  4. };

src/index.js

  1. + import _ from 'lodash';
  2. +
  3. - async function getComponent() {
  4. + function component() {
  5. var element = document.createElement('div');
  6. - const _ = await import(/* webpackChunkName: "lodash" */ 'lodash');
  7. + var button = document.createElement('button');
  8. + var br = document.createElement('br');
  9. + button.innerHTML = 'Click me and look at the console!';
  10. element.innerHTML = _.join(['Hello', 'webpack'], ' ');
  11. + element.appendChild(br);
  12. + element.appendChild(button);
  13. +
  14. + // Note that because a network request is involved, some indication
  15. + // of loading would need to be shown in a production-level site/app.
  16. + button.onclick = e => import(/* webpackChunkName: "print" */ './print').then(module => {
  17. + var print = module.default;
  18. +
  19. + print();
  20. + });
  21. return element;
  22. }
  23. - getComponent().then(component => {
  24. - document.body.appendChild(component);
  25. - });
  26. + document.body.appendChild(component());

注意当调用 ES6 模块的 import() 方法(引入模块)时,必须指向模块的 .default 值,因为它才是 promise 被处理后返回的实际的 module 对象。

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

  1. ...
  2. Asset Size Chunks Chunk Names
  3. print.bundle.js 417 bytes 0 [emitted] print
  4. index.bundle.js 548 kB 1 [emitted] [big] index
  5. index.html 189 bytes [emitted]
  6. ...

框架

许多框架和类库对于如何用它们自己的方式来实现(懒加载)都有自己的建议。这里有一些例子:


进一步阅读


贡献人员

EugeneHlushko EugeneHlushko byzyk byzyk chrisVillanueva chrisVillanueva iammerrick iammerrick skipjack skipjack