Ever had heavy Javascript assets that were taking a while to download? Sprockets::Preload allows you to preload it using only the directives of Sprockets.
Show your users nice loading bar instead of just white loading screen!
Imagine that you are riding on Rails and have the following application.js
where jquery
, jquery-ui
and front
(MVC front-end application) take around 500kb compressed altogether:
//= include helpers
//= include jquery
//= include jquery-ui
//= include front
$(function(){
// Starting application
Front.start();
});
Let's make user experience smooth:
-
Add
sprockets-preload
to yourGemfile
and runbundle install
-
Change
//= include
to//= preload
for the assets you want to detach://= include helpers //= preload jquery //= preload jquery-ui //= preload front $(function(){ // Starting application Front.start(); });
-
Delay initialization to the moment when detached assets are loaded:
//= include helpers //= preload jquery //= preload jquery-ui //= preload front SprocketsPreload.success = function() { // Starting application Front.start(); }
-
Track loading and show progress to user
//= include helpers //= preload jquery //= preload jquery-ui //= preload front SprocketsPreload.success = function() { // Starting application Front.start(); } SprocketsPreload.progress = function(percent) { // User isn't going to see percents at console // but that's just an example after all console.log(percent); }
-
IMPORTANT: Rails development environment uses stub to ease debugging. Thus while things keep working, assets don't really get detached. To force production-grade loading (just to make sure things work fine) add
//= preload!
to your manifest://= preload! //= include helpers //= preload jquery //= preload jquery-ui //= preload front SprocketsPreload.success = function() { // Starting application Front.start(); } SprocketsPreload.progress = function(percent) { // User isn't going to see percents at console // but that's just an example after all console.log(percent); }
Make sure to remove
//= preload!
when your tests are done.
By the way, there's also //= preload_tree
directive that works similar to //= require_tree
.
To make loading progress tracking smooth and cache manually controllable, Sprockets::Preload uses localStorage
to cache assets (it falls back to default browser cache automatically). Sprockets provides digests and logic-aware dependency system that work much better and much more predictable than more common default HTTP caching.
That's said – you really want to keep localStorage
strategy in the vast majority of cases. If however for some reason you still want to make it use default browser cache, set SprocketsPreload.localStorage
to false
like this:
//= preload!
//= include helpers
//= preload jquery
//= preload jquery-ui
//= preload front
SprocketsPreload.localStorage = false;
SprocketsPreload.success = function() {
// Starting application
Front.start();
}
SprocketsPreload.progress = function(percent) {
// User isn't going to see percents at console
// but that's just an example after all
console.log(percent);
}
Note that default caching strategy will still try to emulate loading progress tracking but it works MUCH worse.
Sprockets::Preload does not depend on Rails. However it has proper rail-ties and is fully-functional on Rails out of box. If you want to use it outside of Rails with clean Sprockets – see lib/sprockets/preload/engine.rb
for required initialization settings.
Sprockets::Preload is a mutated fork of Joosy 1.x preloaders. For Node.js-based applications please refer to Loada.
- Boris Staal, @inossidabile
It is free software, and may be redistributed under the terms of MIT license.