About Prime

Prime (progressive/responsive image enabler) is a JavaScript script (still in development), created by hnldesign, that allows for progressive and responsive image loading.

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 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.

Fore more info and implementation, see: http://www.hnldesign.nl/work/code/prime/

Advantages

  • Speed

    As an example (based on a desktop browser, at 1920×1080); If all images on this 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 (!).

    Furthermore, if the user does not 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

This page is a demonstration of Prime, with both div and img elements and debug-info (click to disable) on changes and dimensions. Resize, scroll and reload the page to see it in action.

click here to emulate no-JavaScript behaviour (this makes the page only show - and load - HQ versions of the images on the page), so you can do a speed and size comparison.

  • An arrow indicates whether the image was last scaled up (to a higher resolution) or down.
  • Green indicates a successful load, orange a cached* load and red a failed one.

Disable cache to see the progressive part on each refresh.

*Cached meaning Prime has already generated an URL for that image, so it was presumably already loaded by the browser

Features

  • Progressive - low quality images load by default, Prime preloads HQ variants in background and replaces low quality images
  • 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 document is done drawing and handles all future events
  • Pure JavaScript - requires no library/framework (like jQuery, etc)
  • Can be loaded asynchronously
  • Small (9.2KB minified)