We love creating responsive e-commerce stores, and embrace the design and technical challenges that arise manipulating layout, typography and user interface. A constant thorn in our high-performance paw, however, remains to be an easy-to-use, no-nonsense implementation for the conditional loading of image assets at a resolution appropriate for a users screen. The concept is a no-brainer, until you dive in and realize the whole situation can get convoluted very quickly.
Traditionally, we've shied away from most conditional asset implementations; quite frankly because we never found one we were thrilled about. This technique aims to be as simple as possible, with the least amount of modification needed to deploy to a new or existing Shopify theme. No fancy JS or Liquid programming is required. And while this isn't a plug-and-play tutorial that will instantly work in any theme, the concept itself is capable of being implemented in almost any Shopify store built in HTML5.
There's no shortage of conditional asset loading techniques out there, and which one to use is highly subjective. The proposed picture element aims to solve this problem and is working its way into the spec, but universal support for browsers is still a long ways away. There's also talk of a new responsive image format altogether, which is exciting to think about... but we're interested in something that is fast and efficient that works today.
When it comes to Shopify, we have a huge leg-up because a series of image sizes are automatically generated when a product image is uploaded. Right out of the gate, we don't need to rely on additional server-side technology or the tedious manual creation of additional sizes for each asset. Booya! Thanks Shopify!
With multiple asset sizes at the ready, all we need to do is somehow get their value into the attribute at the correct time and place. CSS can do an OK job in some areas of your site by switching background-images with media queries, but that has some accessibility issues and isn't recommended for product images. So that leaves us with the 'clown car' technique, developing a custom JS solution or implementing one of the many scripts out there, preferably using HTML5 data-attributes for valid and clear markup.
Enter Intention.js. Developed internally at Dow Jones and recently released as open source, Intention has so far proven to be extremely effective at solving many common problems in responsive design in a very clear and logical way. At its core, Intention.js is awesome at using data- attributes to manipulate HTML based on a given context ( think of 'context' as being your breakpoint, in this case screen width ). By storing various image urls in data-attributes, we can be assured that they do not download until they are promoted to the actual attribute, which helps keep Shopify's servers happy. Also, since its all valid HTML, we can set our standard src attribute to a sensible default which still works if JS is disabled.
The first thing we need to do is head over to Gitub and download the latest version of Intention.js. Intention comes with a helper context.js file we'll want to use, and also has two dependencies; Underscore.js and jQuery. jQuery is quite popular and helps power thousands of Shopify stores, so there's a good chance you already have it. Underscore, and I quote; 'Is the tie to go along with jQuery's tux'. It provides a lot of very useful low-level functions and definitely warrants a closer look if you're not familiar with it.
Next, we need to include jQuery, underscore.js intention.js and context.js ( in that order ) into our Shopify theme. Upload them to your theme's asset folder, then link them in your theme.liquid using liquid's script tag. Using a build script to concatenate and minify is recommended, but not required; and the extra overhead of these small additional files is far outweighed by their benefits, especially in a mobile vs desktop context.
Now for the good stuff. Once all the aforementioned libraries/scripts are added, there is no more JavaScript or Liquid to worry about. As long as Intention is loaded, it will take care of the rest! We just need to update our product thumbnail's HTML <img > tag with the appropriate data-attributes. It looks a little something like this:
An initial data-intent is added to the image tag we want to manipulate, which let's intention.js know to act on it. Then we populate the data-in-[context]-[attribute] values using Liquid's product_img_url filter along with the image size we want for each context.
And that's it! Include a few files, add some data-attributes and you're done! Mobile users will see your _small images quickly while your desktop users will see the higher-resolution versions in all their glory. Given the range of sizes available and considering their respective file sizes, this method can exponentially speed up your pages for mobile, while alleviating any hesitation to show off those high-resolution images for your desktop viewers. Plus, it can be used on any asset where Shopify auto-generates sizes for you, which includes images uploaded to the files area. If you want to use this with images in your assets folder, all good - you just need to create the size variations yourself and set the data-attributes to the asset_url accordingly.
We're trying to be a bit more active with our writing, so please follow us @radiatorstudios if you found this article helpful. More to come on the topics of E-Commerce, Design, and Shopify!