Code splitting always was a thing. From the times, when you were adding tons of different script tags, till RequireJS was emerged. Code splitting always was here, were supported, used, and let’s skip the question about “how” it was supported and used. Anyway — bringing the code from overseas and performing a customs clearance — that is discussable. Importing components…. So, let’s skip the history lesson and warp directly to the start of an action. Webpack 2 comes out and gives an import. Code splitting become a thing (yet again) and we got bunch of “React-loaders” next week. And the first question you better ask is simple Why do I need “loader”? So, you should be ok with having npm package or React component just for . Why don’t to have a special component for a loader? everything The simplest code for such component is short and simple. What else? This component is actually does some state handling, and provision your application with code splitting. You can use it as is. Just add some error handling, ability to retry loading, precaching, testing, displaying something while you load the stuff, or fail to do it – and you will get a real react component. The thing you should probably write once, or even better don’t spend your time and use existing solution — some library from an open source. Ok then. How to pick that library? If you will go to github and search for a library – you will found a few of them, and them will have to pick the one you gonna to use. What’s the difference? How to choose? First of all — ignore the stars count, commits, activity and so on. “Loader” is not a rocket, as we just found – this is . 22 lines of a sparse code The Second — look on API. You are going to use it, and API should “fit” you. Actually there is 2 “forms” of API. 1. loadable(() => import('./Home'))2. loadable({ loader: () => import('./Home') }) You can found the first one in , and , while the second one — and . react-imported-component react-universal-component loadable-components react-loadable react-async-component There is also a slight difference in “extra” options, you can pass into the loader Loadable-components — you can specify what to display while loading Loading, in case of Error, or how to display a Component. const Home = loadable(() => import('./Home'), {LoadingComponent: Loading,ErrorComponent: ErrorDisplay,render: ({ Component, loading, ownProps }) => {...})}); Loadable-components also proposes to handle delays and timeouts with third party tools. _loadable-components - React code splitting made easy ✂️✨_github.com smooth-code/loadable-components 2. React-imported-component has actually the same API, just introduces additional onError property. It is better to refer to Loadable-components readme to undestand how to handle React-imported-component. _react-imported-component - Bundler-independent solution for any deferred component for better SSR, Code-splitting, and…_github.com theKashey/react-imported-component 3. React-async-component yet again is the same. With a lot of interesting information asked and answered in issues. _react-async-component - Resolve components asynchronously, with support for code splitting and advanced server side…_github.com ctrlplusb/react-async-component 4. React-loadable is slightly different, first accepting more that just “import” function, to be resolved by final component(ie it could handle “Maps”), mixing LoadingComponent and ErrorComponent in one, and having build in “delay” to reduce flashing of loading “spinners”. Loadable({loader: () => import('./WillFailToLoad'), // oh no!loading: (props) => {if (props.error) {return <div>Error!</div>;} else {return <div>Loading...</div>;}}}); _react-loadable - ⏳ A higher order component for loading components with promises._github.com jamiebuilds/react-loadable 5. React-universal-component also not differs a lot from all others. The only one with real dynamic dynamic imports. const Component = universal(props => import(`./${props.page}`)) PS: this approach may have great side effects, be aware. _react-universal-component - 🚀 The final answer to a React Universal Component: simultaneous SSR + Code Splitting_github.com faceyspacey/react-universal-component They all do their job well, and if you want to learn more about codesplitting itself — refer to the articles about these loaders. _Whatup Reactlandia!_medium.com React Universal Component 2.0 & babel-plugin-universal-import _Component-centric code splitting and loading in React "The Beach House (Mndsgn Remix)" - Benny Sings When you have a…_jamie.build Introducing React Loadable _A library to solve React code splitting client-side and server-side._medium.com Introducing loadable-components ✂️✨ PS: actually those articles are mostly about the “import” thing. And feel free to can pick “Loader”, or even use your own one, if you are building pure front-end SPA, just cos…. Client side code splitting AND server side rendering On face value they all have similarities, especially when dealing with client side only. However, I personally find that the real distinction between each solution becomes apparent when you are trying to execute server side rendering. — , issue #37 react-async-loader The client side code splitting is . The “good” client side code splitting in much more complex thing…. But you still can write everything you need in an hour, or two. And the result could be even better then all the libraries above. Yeah, writing “loader” for client side is easy. a super easy thing Server side and code splitting? Huh? No one actually solved the problem. The problem You are rendering your application on , and sending the html to the . Next, Client the code, replacing dead html by React representation, making it alive. Easy code splitting. Server Whole Client rehydrates without The problem #1 is — due to code splitting client ALL required to fully rehydrate server-rendered response. And the page, which were just ok-ish a second ago, got replaced by spinners, and seconds after it yet again ok-ish. It it will render as much it could, load the deferred parts, and re-render the rest. Thats how things works! does not have code You have fucked up all the work you done on SSR, made a customer angry, or even caused seizures due to blinking content and spinning loaders. Rule #1 — first load all “spare” parts. Only next rehydrate content to make rehydration invisible to the customer. The problem #2 is — server side React rendering is . “Code-splitted” component are “async”hronous. If you will render them on server — you will render nothing, or “LoadingComponent”, but not the React Component you have to render. It is async, and will be ready to be rendered . Bingo! First price! synchronous just after you send result to the client Rule #2 — async on client. Sync on server. Don’t mix. Those problems are entangled — you have to know what you “will” load during the rendering, “did” load it, and let the client side know how to repeat. Maybe Lyft’s is the one. They are using “string-replace-loader” to replace “import” by their stuff making it literally sync on server, next extracting the “used” scripts from webpack stats. 50 lines of code for everything. universal-async-component cheatest are doing almost the same, but using babel plugin to “transfer” information about used imports, and providing the sync requires next to async imports. React-lodable went the similar and the different way. They doing “the same” passing down the “decrypted” information via babel-plugin-universal-import, but they are passing down that information “within” the “import”. Universal-component And All the libraries listed above next will access the webpack stat information, to figure out which extra scripts user have to load prior of main context. Pros: They do the job. Cons: webpack only, will synchronously import extra scripts before the main. Could be affected by some optimizations webpack could introduce in a future. are super different — they literraly “ ” on the server side, to provision the “async-rendered” stuff to the final result. This does not require any webpack or babel plugin, but could affect the performance of a page rendering. You have to perform a client side rendering on the client side, re-rendering everything a few times. Loadable and async components renders the react tree Next they do almost the same on front end. But there is a problem — you could import only one “level” of imports at once. If you have a async Page, which loads the async Widget — they will have first load Page, and only after it they will be to load the Widget, and get to code to do it. able PS: Loadable-components has a babel plugin to mitigate(a bit) this problem. Pros: Could work with any bundler, even without extra configuration Cons: Slow async SSR, slow “wave affected” front-end rendering. is something in between. It is still always async, but making SSR rendering synchronous by simple executing imports and memoizing the results before the first user could generate the page. Just a simple assumptions, that Promise will got executed before all that socket stuff, needed to accept the first client request to renderer something. React-imported-component Next, it will track the usage of imports, and try to replay them before the client-side rehydration. Pros: Did it’s job Cons: not webpack only, not wave affected, not slow, and not gonna break in a future. Wat? There is one thing, I forgot to mention — HOW these loaders making “sync” requests, and understands what client have to load prior to rehydration. They use babel, to find the “import” and use the string inside the import as a “mark”, and as a filename to the real file. Like require const LoadableComponent = Loadable({loader: () => import('./my-component'),loading: Loading,}); But! If you will just move import off that function const loader = () => import('./my-component');const LoadableComponent = Loadable({loader,loading: Loading,}); And this is issue. And this is issue only for SSR. It will break the stuff. known If you want to have loader as a part of UI library or UI kit, I mean — standard site wide “Loading” or “Error”, analytics, monitoring — you will be unable to wrap “the Loader” by helper function or convert into HOC. It will , as long it will lose the track of used components. stop properly SSR Actually this is not the “common” issue: react-universal-component by , enchanted by sync and async “versions” of an import. replaces import universalImport react-imported-component do almost the same, replacing by “findable” wrapper. universal-async-component also replaces by their wrapper. import So — they all will be able to understand whats happening and use “indirect” imports. “The issues” is “the issue” only for react-loadable and loadable-components. And webpack v4 support for files them both due the current realisation. mjs could break The second important thing — if you want to load module “A” — webpack may load “B”, ”C” and “D”. Due to CommonChunk, AsyncChunk, Webpack v4 AutoMagicChunking, or anything else they will invent in a future. It is not easy to undestand (and predict) all the magic from the webpack stat file, thats why due to “unexpected” ConcatenationPlugin universal-async-component might be already broken. changes this. A bit. This is not good and not final solution, but may work just here just now for everyone. React-imported-component It casts the “import function” you provided to string, and RegExping imports inside it. So you can pass “import” from anywhere, but you still can not use complex function, as long everything except the loader function body will be invisible to imported component.The difference from react-universal-component and universal-async-component, which also “hacks” the import is simple — imported component does not execute the “import function” each time. Only one during the startup, keeping it async, and letting you put ANY logic inside (like a bunch of imports, awaits, resulting a new component at the end). It searches for imports across your codebase, resulting a single “lookup” file, with each and every in your project. Next it could use it to import something by “mark”(import name) to reduce “loading waves”. import And that loading will be . And loaded AFTER the main bundle. Is there any difference between “when” to load stuff — synchroniusly before the “main” or asynchroniusly after it? Sure the second variant will be faster, ${numberOfExtraScripts} times faster. async Pros: Could work with any bundler. Cons: Require separate step to “extract” imports from code base. And babel. There is a lot of loaders, so give it a try to this new one. Actually it is not new, as long it was born as a “react-hot-component-loader” for React-Hot-Loader almost a year ago. And also feel free to try all the other libraries I’ve listed above. Just because they are all different, and each of them could be a better fit for you. And all of them will get better and evolve. PS: As react-imported-components just did (this is version 4 already) And what about code splitting itself? Just do it! Not much. Mostly on logical, not component layers. The key idea — load “splitted” code in the parallel with “data”. Or you will have first to load the code, which will start loading the data. experience, not for code splitting itself. We are fighting for the customer Wanna more? _React code splitting become a thing a year ago. Since then we are keeping finding new ways to codesplit and defer…_medium.com React Server Side Code Splitting Made.. Again