Mobile performance nightmares

Don’t turn your page load in mobile networks into a nightmare — some tips about what not to miss in terms of performance in your next responsive website project.


Recently at Itelios we developed an e-commerce website for a major worldwide brand (I’m not sure if I’m allowed to tell the name of the brand, so let’s keep it a secret for now) using Demandware technology. The project was executed in a very tight schedule and we’ve had success delivering a great solution for the brand.

But right after the website was launched, we faced a problem: The site is really image-heavy and loading in mobile networks was a nightmare.

Big brands can’t lose sales because the consumer is tired of waiting for the page to load in his slow 3G connection.

Big part of the problem was created by brand’s content team: They had contributed totally non-optimized images. But we’ve had to to admit: We missed some really obvious points, due to the rush and small communication failures. Mea culpa.

In this post I’ll share the points we’re working on to make this website’s pages load faster. I know some things might sound obvious, but maybe it could help other people struggling with this problem. ☺


Images


Lossless optimizing contributed images

All contributed images need to pass a lossless image optimizer like https://kraken.io/ or http://thumbor.org/ (my personal favorite, since it can serve .webp images to supporting browsers, making it really lighter in size). Thumbor needs to be installed and integrated as a webservice in our server, while Kraken can be used manually on the web freely or integrated with Demandware as a paid web service).

Lossy compression for photos

We have some contributed images in desktop with 150, 250 and even 591kb in size each (591kb is the maximum and It’s just ridiculous). In mobile, there are some some “mobile-sized” images and still they have 196kb.

For desktop images, we need to balance the visual quality with the size and that’s something only the brand’s content team can guarantee. So, we need to train them in this subject.

For mobile images, default recommendation is: save images with double the size (retina screen friendly) but .jpg quality around 20 in Photoshop. This usually does the trick, since the image will be resized to half the size and the flaws of the low-quality photo won’t appear.

Every photo should have the mobile version contributed

I’ve seen a lot of places in the website where we are using the same image for desktop and mobile, even though the front-end team has integrated responsive images using Scott Jehl’s Picturefill. Usually mobile will have a smaller picture, in dimensions and file size. We should check the whole site to see where we are really using responsive images and where we aren’t, map this and do the needed modifications in code to make everything available to be contributed for mobile.

Lossless optimizing layout images

As we should do some lossless optimization in contributed images, we should do in our layout images (even though they already have a fair amount of optimization). We can’t do this in our source images because sometimes, after the lossless compression, the images can’t be further edited in Photoshop/Fireworks. So, ideally we’d have the same script that optimized contributed images to do the optimization on our layout images, but only on production environment.


Minify and Concatenate


Minification

We should minify all CSS and JS in the production website. This is something that made me cry when I saw we weren’t doing, because it’s pretty basic and also, right at the begginning of the project, I asked some of the back-end developers and they told me that it would be automatically done in production environment. Turns out it wasn’t. ☹

Concatenation

Right now all the css and js files are being served on it’s own. That means lots of requests. I think in every page, we could have only two css and two js (maybe four, if the page needs some scripts files at the top of the page and some at the bottom). One for all the css and js that are loaded on the “masterpage”, concatenated, and one for the css and js that are loaded in the navigation/script and navigation/css, concatenated. This way we’ll save some requests at each page load.


Lazy Load


In an image-heavy website as this one is, images should only be loaded as we see them in the viewport. Implementing some kind of lazy loading will greatly improve loading time of the rest of the page.


Scripts at the bottom of the page

Right now, only some of the scripts are in the bottom of the page, right before closing </body>. We need to analyze which scripts that are loading at the <head> can be transfered to the end of the page, so content is visible first.


Watch duplicate assets


Duplication during contribution

I saw that in the home page we are loading the files from font-face one time from the website (css) and another time from the CDN. This was generated by the brand during html content contribution. We need to train them into analysing our code and finding what is already there.

Different scripts doing the same thing

The main banner in the home page (contributed by brand’s front-end team) uses a different plugin from the one we already use for other sliders in the page. It’s perfectly possible to achieve the same result using the plugin that is already in the page. We just need to teach them how to. ☺


Asychronous javascript load

Defer scripts and load them asynchronously whenever possible (don’t forget to check crossbrowser compatibility for those items and issue the problems)

Defer: script is executed when the page has finished parsing.
Defer + Async = The script is executed asynchronously with the rest of the page (the script will be executed while the page continues the parsing)


Set cache in HTTP headers

Basically we only need to change cache rules for the .svg files in our domain. Apparently this is out of Demandware’s default cacheing rules.


And last, but not leastAnalyze our “common” js

Do all of this code really needs to be loaded in every single page of this website? D: