Разделение кода / предварительная загрузка содержимого во время просмотра пользователем?

используя такие инструменты, как Webpack, мы можем включить разделение кода и только при необходимости загружайте код приложения асинхронно.

пример в контексте приложения react с react-router.

Load initial page.

-> go to new route
---> webpack loads in the component file required asynchronous.

Webpack ожидает, пока код не потребуется для инициирования запроса.

мой вопрос в том, что после загрузки базового кода приложения мы можем начать загрузку остальной части кода, даже до того, как пользователь инициирует переход на новый маршрут?

мое мнение заключается в том, что пользователь не будет ждать загрузки куска webpack.

-> Load initial page
--> user sitting idle or browsing on home page
----> Start loading application code for rest of the application
---> user goes to new route (faster UX because code has already download in the background)

Я надеюсь, что это имеет смысл

1 ответов


Да, вы можете добиться этого. Я покажу одно из возможных решений.

сначала давайте создадим 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 заявление передать render функция, содержащая функцию разрешения. В backgroundLoader эта функция будет пустой, в результате чего только загрузка куска в head приложения.

полный код для этого примера вы можете увидеть на WebpackBin (вы можете проверить сеть, чтобы увидеть, как куски загружаются в фоновом режиме)