PRPL on Rails Part 1: Code Splitting
This is the first of a three-part series on speeding up your Rails application load time using techniques from the PRPL pattern.
According to a Google study, the average website takes 19 seconds to load on a mobile phone over 3G, and more than half of mobile website visits are abandoned if the site doesn't load within three seconds.
No one wants to wait for your website to load.
It's easy for you and me, with our nice development machines and good connections, to believe our websites are performing well for our users. But our users are increasingly accessing the web from mobile devices. More than half of page views worldwide are on mobile. And on mobile those page views are mostly as slow as molasses.
Paint it PRPL
Don't despair: we can make our sites faster and our users happier. The PRPL Pattern points the way. The PRPL pattern is an architectural pattern, created by Google's Polymer team, that consolidates many of the best practices for optimizing web performance. PRPL stands for Push, Render, Pre-cache, and Lazy-load.
- Push critical resources for the initial URL route.
- Render initial route.
- Pre-cache remaining routes.
- Lazy-load and create remaining routes on demand.
Addy Osmani, The PRPL Pattern
In "PRPL on Rails Part 2" we will talk about rendering and in "Part 3" we will cover pre-caching and lazy-loading. This part will focus on Push, on getting our critical resources for our initial route to the browser as quickly as possible.
TLDR; Ship Less Code
The direction to "push critical resources for the initial URL route" needs some unpacking. What are "critical resources" and what does it mean to "push them for the initial URL route"?
If you are going ship only your critical resources on initial load, you can't bundle all your code into a single package. Bundling everything together reduces roundtrips to the server, but means you will need to download and parse large files before users can interact with your app. To make your interactive quicker, you can split your code by route and load only what is needed for a particular page.
Webpack and Webpacker
Webpack and Webpacker are tools that assist with code splitting (among other things). Webpack is a popular build tool that bundles, optimizes, and minifies front-end resources so that they can be downloaded fast. Webpacker is a Rails wrapper that makes it easy to use webpack in Rails.
In your Rails app, you can create different "packs" (called "bundles" in the world of Webpack) by adding files to the
You can load the packs on the appropriate pages like so:
Time to see this all in action. We have prepared a sample app and an exercise that will demonstrate how you can improve load time by splitting code by route, so that currently unneeded code can be lazy loaded later. (This is part of a workshop that we offered at RailsConf last week.) To download the sample app go bw.cm/prpl and click on "Setup." Then find the "Exercises" page and click on "Part 1: Code Splitting." In the exercise, you'll first run a Lighthouse audit in Chrome's developer tools, then split some code, then re-run the audit to see the difference it makes.
Enjoy! And don't hesitate to get in touch with your thoughts or questions.
- Can You Afford It?: Real-world Web Performance Budgets, by Alex Russell
- The PRPL Pattern
- PRPL with Custom Elements and Firebase
- Primer on Web Performance, by Ilya Grigorik
- Web Performance Optimization with webpack