Meteor 1.5. helps to reduce the initial bundle size. But its not that easy to decide where to split and how to handle the defered loading of a module. So i played around with it a little.
a good idea is to do this spliting on the routes.
One way to do it is to use react-mounter
:
FlowRouter.route('/', {
name: 'home',
action() {
mount(MainLayout, {
content: () => (<p>Loading</p>),
});
import('/imports/modules/core/components/home').then(({ default: Home }) => {
mount(MainLayout, {
content: () => (<Home />),
});
}
);
},
});
this will mount a loading component when the module is not ready yet. It will start loading as soon as the route is called.
Another, more flexible approach is to use react-komposer
to create a “lazy” HOC:
import _ from 'lodash';
import React from 'react';
import { compose } from 'mantra-core';
const callOrReturn = funcOrValue => (_.isFunction(funcOrValue) ? funcOrValue() : funcOrValue);
export default componentPromise => (
compose(
(props, onData) => {
callOrReturn(componentPromise).then(
({ default: Component }) => onData(null, { Component })
);
}
)(
({ Component, ...props }) => <Component {...props} />
)
);
this can be used like this:
// this will not bundle home, but load it as soon as this import is called
// this might help reduce the bundle size, but the data is still loaded as soon as the app loads
const Home = lazy(import('/imports/modules/core/components/home'));
// you can pass a function to lazy that returns the import promise
// now, AdminHome is loaded when the component is mounted!
const AdminHome = lazy(() => import('/imports/modules/admin/components/admin_home'));
FlowRouter.route('/', {
name: 'home',
action() {
mount(MainLayout, {
content: () => <Home />
});
);
},
});
FlowRouter.route('/admin', {
name: 'admin',
action() {
mount(MainLayout, {
content: () => <AdminHome />
});
);
},
});
have fun!