Prime (progressive/responsive image enabler) is a JavaScript script I wrote, that allows for progressive & responsive image loading, potentially improving page speed by up to 96%.

This means that initially a small, low quality image is loaded on the page, and this is then replaced (after load) by a higher quality version, but only if required (if the element is actually in view of the user). That’s the ‘progressive’ part. If the user scrolls, rotates or resizes the page, this process is repeated for all visible elements, either adjusting them up or down. This is the ‘responsive’ part.

Prime is an evolution of prImages and it was written with cimage in mind as an image-generating backend, but can easily be adapted to either pre-rendered images, or another resizing/thumbnail library.

Prime’s image fitting works by matching the actual dimensions of an element upwards to common responsive width breakpoints (160, 320, 480, 768, 1024, 1224, 1824, 1920 pixels, so a width of 600px would be matched to 768px, and so forth) as opposed to what width would be available. This prevents a plethora of image sizes to be generated, by effectively limiting them to 8 versions per image (9 if you include the original). Pixel ratio of the browsing device is also taken into account; image sizes are doubled when pixelratio is higher than 1.

Prime - Basic workings
Prime – Basic workings (animated)

Advantages

  • Speed

    As an example (based on a desktop browser, at 1920×1080); If all images on the demo-page would be loaded in the old-fashioned, regular way, the page would consist of 16.3 MB worth of html and (33 high-quality, 16.2 MB) images, taking at around 1.1 minute(!) to fully load on a 2.0MB/s connection, or 5.65 seconds on a 30MB/s connection.

    With Prime, that page now weighs in at a total of 810 KB, including 33 (low-quality) images, of which only 2 are loaded in HQ immediately (the top logo and the first image, which is in view), making a total of 35 images, taking up 572 KB. To fully load the page, this takes on average around 2.26 seconds on a 2.0MB/s connection, or 489 ms on a 30MB/s connection.

    This means the pageload, without any user interaction, is 96.5% smaller and around 91.3% to 96.5% faster, depending on connection type (!).

    Prime speed/size comparison for initial pageloadPrime speed/size comparison for initial pageload
    Prime speed/size comparison for initial pageload
    Furthermore, if users don’t scroll the page, they never require the remaining 15.7 MB, potentially saving heaps of bandwidth on a busy website.

    Even after scrolling through the whole page, data transfer is still only 8.2 MB (8,0 MB images) as opposed to 16.3 MB, because of better image fitting (see below), saving a total of 51% on data transferred.

  • Reduced content-shift

    When a webpage loads, it displays as soon as text and css are loaded, and requested for all other resources are made. This means that a page will show without waiting for images to finish loading. This produces (if no dimensions were set on the <img> elements) content-shift, which can be highly annoying.

    The progressive aspect of Prime enables you to initially set small, low quality placeholders while we wait for Prime to finish loading the high quality images. As these placeholders are (a lot) smaller than their HQ counterparts, they load much, much faster as well, limiting content-shift to an absolute minimum.

    That said, I would still recommend taking other precautions, such as setting intrinsic ratio for all images.

  • Better image fitting

    With responsive websites, the width of container elements varies a great deal, depending on the user’s resolution. To determine the best size image to load, we need to resort to JavaScript, as most serverside scripts really have no idea what resolution the user is in. This means that, on responsive websites, there is really no easy way to specify the best possible images to load in your HTML.

    Prime circumvents this by checking the container size, and matching that to its breakpoints, producing an image that fits the current resolution/dimensions, without loading the highest quality image, per se. Say an element is 460px wide in the current user’s viewport, and the original image is 1024px wide, Prime will match that 460px to its breakpoints, resulting in a width of 480px, and then lets the browser load this image. This produces an image that weighs less than the original and looks perfect.

    Ofcourse, if you set a fixed size for the image element, Prime will not exceed that limit.

Demo

I use the script on throughout this website. For a more detailed view, check out this gallery, which is a demonstration of prime with both div and img elements and debug-info on changes and dimensions. Resize, scroll and reload the page to see it in action.

Features

Prime’s main features and advantages are:

  • Progressive – low quality images load by default, prime preloads (‘lazy’ loads) HQ variants in background only if needed (eg images are ‘in view’ for the user) and replaces low quality images when done
  • Responsive – on each resize, scroll or orientationchange event, prime checks if images have changed in size (and require a larger or smaller image), preloads and replaces if needed
  • Smooth – allows for use of a ‘phantom’ image, which is an overlay image that is invisible on page load, and fades in the HQ version once loaded (Google image search uses this technique)
  • Fire and forget – prime instantiates itself on script load, enumerates and sets up images as soon as the document is done drawing and handles all future events
  • Pure JavaScript – requires no library/framework (like jQuery, etc)
  • Can be loaded asynchronously
  • Small (just 9.4KB minified)

Download