Code Splitting / Preloading Content while user is browsing?

Using tools like Webpack we can enable code splitting and only load our application code asynchronously when required.

Example in the context of a react application with react-router.

Load initial page.

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

Webpack waits until the code is required in order to initiate the request.

My question is, once the base application code load, can we start loading the rest of the code, even before the user initiates the transition to the new route?

My view is that will prevent the user from waiting for the webpack chunk to download.

-> 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)

I hope this makes sense


Yes you can achieve this . I will show one of the possible solutions.

Firstly let's create backgroundLoader for queuing required chunks:

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();
}

This function will load your chunks in background with 1 second delay (you can tweak it - for example start popping queue after for example 5 second or shuffle array of chunks).

Next you must register your require.ensure in queuing function 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;
  }
};

Once you require your chunk in switch statement you pass render function containing resolve function. In backgroundLoader this function will be empty resulting only loading chunk to head of your app.

Full code for this example you can see on WebpackBin (you can check network to see how chunks are loaded in background)

链接地址: http://www.djcxy.com/p/36044.html

上一篇: 在Silverstripe中删除“复制此页面和子页面”的功能

下一篇: 代码分割/预加载内容,而用户正在浏览?