Yoav's blog thing

Mastodon   RSS   Twitter   GitHub  

Who Is Sizer Soze?

# For the impatient

Sizer-Soze is a utility that enables you to evaluate how much you could save by properly resizing your images to match their display size on various viewports.

Basically it shows you how much image data you could save if you deployed an ideal responsive images solution. If you already have a responsive images solution in place, it enables you to see how far it is from that ideal, and improve it accordingly.

# How it started

One Saturday morning a few weeks back, I read a blog post by Jason Grigsby that pissed me off inspired me, like his posts often do :)

He wrote about responsive images and how we should calculate their breakpoints according to our performance budget. (If you haven't read it yet, you probably should).

He also wrote that this approach would be difficult to use with proposed viewport-based responsive image solutions such as <picture>and srcset. This is the part where we disagree.

I believe that for most cases, a simple build step can be used to make the translation from layout to viewport based breakpoints easy for Web developers. Since the alternative to viewport-based solutions are layout-based solutions, which have inherent performance issues, I think this is our best way forward with responsive images.

The discussion of a "Responsive images performance budget" got me thinking that we lack tools that can calculate the size difference between the images we serve our users and their actual display size in responsive designs, tools that can be used as part of a build system.

Currently, we have no clue how much image data we are sending for nothing! You cannot handle a budget if you don't know how much you're spending.

A couple of hours later, I had an initial version of Sizer-Soze up and running.

# How it works

Sizer-Soze is comprised of several scripts. It started with mostly bash scripts, but I've completely re-written it in Python a few days back, since I found that I've reached the limits of the previous architecture, and needed more speed, parallelism and stability.

I'll try to describe the roles of the various scripts, without going into specifics that may change in the future.

# getImageDimensions

This is a PhantomJS script, that gets a single Web page URL as its input, and well as the viewport dimensions it needs to examine.

It then outputs the various image resources that it picked up from the Web page and the display dimensions of each. Since PhantomJS is a real headless browser, it picks up both the images that are defined directly in the HTML, and the images that are added dynamically using scripts.

The script detects only content images (i.e. CSS background images are not detected). It may also miss images that are added later on in the Web page's lifecycle, such as lazy loaded images the are added following a user scroll, or another user action. Data URIs are also ignored for the time being.

When "display: none" images are present in the page, the script can take quite a while to run (up to 25 seconds), since it waits to see if these images are a part of a carousel (and are displayed eventually) or simply hidden for this particular breakpoint.

# downlodr

Downloads the page's image resources in a parallel fashion.

# resizeBenefits

Performs lossless optimization on the image resources (using image_optim), and resizes them to their displayed size (using ImageMagick followed by image_optim). It then outputs the optimization savings for each image, as well as the resize savings.

The results are written (by the sizer script we'll discuss later) to the output directory (set in the settings file) under a directory with the site's slugified name as results_<VIEWPORT>.txt (e.g. /tmp/http-microsoft-com/results_360.txt)

# sizer

Binds the above mentioned scripts together, by iterating over them for various predefined viewports, and outputting the summary of their results (i.e. how much can be saved for each viewport by optimization and by resizing) to standard output, so to the screen by default.

# bulkSizer

This script simply takes in a text file full of URLs and runs sizer on these URLs in a multi-process manner, that makes sure that the long time each one of these runs take doesn't accumulate, and makes sure running the script on a bulk of Web sites doesn't take forever.

# How can it be used?

Well, Tim Kadlec wrote a post recently about his findings using Sizer-Soze to evaluate how much image data is wasted in responsive designs from the mediaqueri.es collection. He came up with staggering 72% image data savings for small viewports and 41% savings for relatively large viewports.

I have ran a similar test on a list of responsive Web sites from the RWD twitter stream, and came up with similar results for small viewports, and even worse results for 1260px wide viewports. (53% image data savings can be acheived by resizing).

If the authors of these sites would have run these same tests before shipping them, I'm guessing the situation would've been significantly different.

While using Sizer-Soze to test other people's sites can be fun, you should probably use Sizer-Soze to check the responsive sites you're building, and how well the images you're serving your users fit their displayed size.

For that purpose, you can integrate Sizer-Soze into your build scripts and use its output to trigger alerts (or fail the build) if your performance budget is exceeded.

One more thing — the RICG have started a repo called Sizer-Soze-frontend. For now the project is in its very early stages, but hopefully it will soon become something developers can rely on, and use for occasional testing, to see if their sites are kept in check without installing anything on their local machine.

# The future

I'm planning to keep evolving this utility to make it faster, more maintainable and easier to use. Better build process integration is a high priority for me. I also intend to improve it, and make sure that it covers all content images.

You guys can help by using it, finding bugs & possible improvements, filing issues, and sending pull-requests :)

Both the back-end and the front-end projects can use some more helping hands. If you want to contribute, feel free to hop on the #sizer-soze channel on Freenode's IRC server.

# Why Sizer-Soze????

I named the initial script sizer as a temporary name. It was all downhill from there.

← Home