用户浏览时的代码拆分/预加载内容?

时间:2016-08-29 21:28:00

标签: javascript webpack code-splitting

使用像Webpack这样的工具,我们只能启用代码分割 在需要时异步加载我们的应用程序代码。

使用react-router的反应应用程序的上下文中的示例。

images

Webpack一直等到需要代码才能发起请求。

我的问题是,一旦基础应用程序代码加载,我们是否可以开始加载其余代码,甚至在用户启动向新路由的转换之前?

我的观点是阻止用户等待webpack块下载。

[Array[3], Object, Object, Object]
0:Array[4]
1:Object
2:Object
3:Object

我希望这是有道理的

1 个答案:

答案 0 :(得分:3)

是的,您可以实现此目标。我将展示一种可能的解决方案。

首先让我们创建backgroundLoader以排队所需的块:

const queue = [];
const delay = 1000;

let isWaiting = false;

function requestLoad() {
    if (isWaiting) {
      return;
    }
    if (!queue.length) {
      return;
    }
    const loader = queue.pop();
    isWaiting = true;
    loader(() => {
      setTimeout(() => {
        isWaiting = false;
        requestLoad();
      }, delay)
    });
}

export default (loader) => {
  queue.push(loader);
  requestLoad();
}

此函数将在后台加载你的块,延迟时间为1秒(你可以调整它 - 例如在启动弹出队列后,例如5秒或随机数组的块)。

接下来,您必须在排队功能require.ensure中注册backgroundLoader

import render from './render'; // not relevant in this example
import backgroundLoader from './backgroundLoader';

let lightTheme = (cb) => {
  require.ensure([], () => {
    cb(require('./themeA.css'));
  }, 'light');
}

let darkTheme = (cb) => {
  require.ensure([], () => {
    cb(require('./themeB.css'));
  }, 'dark');
}

let pinkTheme = (cb) => {
  require.ensure([], () => {
    cb(require('./themeC.css'));
  }, 'pink');
}
backgroundLoader(lightTheme);
backgroundLoader(darkTheme);
backgroundLoader(pinkTheme);

export default (themeName) => { // router simulation
  switch(themeName) {
    case 'light':
      lightTheme(render);
      break;
    case 'dark':
      darkTheme(render);
      break;
    case 'pink':
      pinkTheme(render);
      break;
  }
};

switch语句中需要块后,您将传递包含resolve函数的render函数。在backgroundLoader中,此功能将为空,只会将加载块加载到您应用的head

您可以在WebpackBin上看到此示例的完整代码(您可以查看网络以了解如何在后台加载块)