Lazy Loading your Riotjs SPA

I have been playing with riotjs for quite sometime now and have been hugely impressed with the super easy and minimal API and minimal size of their.

I built quite a lot of production apps with riotjs and have practically shipped some of them in sub 70k size (css+js+shell), I personally felt it was pretty darn amazing. It loaded fast and everything, and since it was loading pretty fast I never kinda felt the need to chunk the code or split the app into smaller apps. And also if you can load all routes, assets and everything pretty fast on a sub average connection, in my opinion you should not over engineer your stack.

Quoting Alex Russell

But then came three other things in light which changed my perspective

  1. Page loading in 3 seconds is not all, it has to be interactive really quicker than that.
  2. You are making the browser parse all of your routes even if the user doesn’t visit all of them. (e.g. imagine this, your browser parses javascript for a ‘terms and conditions/contact us’ page every time he lands on home ahhh sad).
  3. ES6 transpiling at this point of time does increase your bundle size and hence add more parsing time to your client side components.

Exactly due to these I decided to find a way to chunk my code and lazy load its pieces.

Enters webpack! Now webpack has quite some robust support to do code splitting (read this). I threw in babel and tag-loader and some code to make it work.

So now to play code chunking for my client side app in riotjs, I took the polymer shop project and decided to implement a mini version of it using riotjs. This project will have homepage in one bundle and browse and product page in another. Both of these will be lazy loaded(why both? read P.S. section).

The main bundle will only contain riot and header file, and then depending on the route the chunk will be loaded.

NOTE: A super quick interact-able header ready super quick(perceived perf).

1st my webpack config

This webpack config, looks for index.js and processes .tag files required in it and packs it into a bundle. Now in index.js we only require header.tag, and we put two function to do require.ensure our files into two groups.

  1. The home page
  2. Browse page and product page
require.ensure is the function that hints webpack to pack files into different bundles and tells it that these files will be required later and need not to be bundled in the default bundle. Whenever your code at a later point calls require.ensure it loads the bundle on fly and then tags/components can be individually loaded and used by the router.

my index.js file:

Now lets suppose that user lands on the home page we only load the default bundle(header) and the 1st bundle(homepage) and not the browse and product bundle

and as soon as we try to move to browse or product page a different call loads the required scripts

and thus user loads only the component required to render the current set of pages quickest. :)

Demo

Made with ❤ for riotjs

Thanks for assets polymer shop.

P.S: Use http2 to server push the bundle required for the current page along with the response and the result should be something like…

Thanks for reading.