Cats, dogs and all sorts of memes, the Internet as we know it today is dominated by images. You can open almost any web page and you'll surely find images on the page.
The more interactive our web browsing experience becomes, the more images we tend to use. So, it is tremendously important to ensure that the images we use are optimized and loaded as fast as possible. We should also make sure that we choose the correct image type.
In this article by Dewald Els, author of the book Responsive Design High Performance,we will talk about, why image formats are important, conditional loading, visibility for DOM elements, specifying sizes, media queries, introducing sprite sheets, and caching.
Let's talk basics.
(For more resources related to this topic, see here.)
Deciding what image format to use is usually the first step you take when you start your website. Take a look at this table for an overview and comparison of
the available image formats:
Format |
Features |
GIF |
256 colors Support for animation Transparency |
PNG |
256 colors True colors Transparency |
JPEG/JPG |
256 colors True colors |
From the preceding listed formats, you can conclude that, if you had a complex image that was 1000 x 1000 pixels, the image in the JPEG format would be the smallest in file size. This also means that it would load the fastest.
The smallest image is not always the best choice though. If you need to have images with transparent parts, you'll have to use the PNG or GIF formats and if you need an animation, you are stuck with using a GIF format or the lesser know APNG format.
Optimizing your image can have a huge impact on your overall website performance.
There are some great applications to help you with image optimization and compression. TinyPNG is a great example of a site that helps you to compress you PNG's images online for free. They also have a Photoshop plugin that is available for download at https://tinypng.com/.
Another great application to help you with JPG compression is JPEGMini. Head over to http://www.jpegmini.com/ to get a copy for either Windows or Mac OS X.
Another application that is worth considering is Radical Image Optimization Tool (RIOT). It is a free program and can be found at http://luci.criosweb.ro/riot/. RIOT is a Windows application.
Viewing as JPEG is not the only image format that we use in the Web; you can also look at a Mac OS X application called ImageOptim (http://www.imageoptim.com) It is also a free application and compresses both JPEG and PNG images.
If you are not on Mac OS X, you can head over to https://tinypng.com/. This handy little site allows you to upload your image to the site, where it is then compressed. The optimized images are then linked to the site as downloadable files.
As JPEG image formats make up the majority of most web pages, with some exceptions, lets take a look at how to make your images load faster.
Most advanced image editors such as Photoshop and GIMP give you the option to encode your JPEG images using either baseline or progressive.
If you Save For Web using Photoshop, you will see this section at the top of the dialog box:
In most cases, for use on web pages, I would advise you to use the Progressive encoding type. When you save an image using baseline, the full image data of every pixel block is written to the file one after the other. Baseline images load gradually from the top-left corner.
If you save an image using the Progressive option, then it saves only a part of each of these blocks to the file and then another part and so on, until the entire image's information is captured in the file. When you render a progressive image, you will see a very grainy image display and this will gradually become sharper as it loads. Progressive images are also smaller than baseline images for various technical reasons. This means that they load faster. In addition, they appear to load faster when something is displayed on the screen.
Here is a typical example of the visual difference between loading a progressive and a baseline JPEG image:
Here, you can clearly see how the two encodings load in a browser. On the left, the progressive image is already displayed whereas the baseline image is still loading from the top.
Alright, that was some really basic stuff, but it was extremely important nonetheless. Let's move on to conditional loading.
Adaptive images are an adaptation of Filament Group's context-aware image
sizing experiment.
What does it do? Well, this is what the guys say about themselves:
"Adaptive images detects your visitor's screen size and automatically creates, caches, and delivers device appropriate re-scaled versions of your web page's embedded HTML images. No mark-up changes needed. It is intended for use
with Responsive Designs and to be combined with Fluid Images techniques."
It certainly trumps the experiment in the simplicity of implementation.
So, how does it work?
It's quite simple. There is no need to change any of your current code. Head over
to http://adaptive-images.com/download.htm and get the latest version of adaptive images.
You can place the adaptive-images.php file in the root of your site. Make sure to add the content of the .htaccess file to your own as well. Head over to the index file of your site and add this in the <head> tags:
<script>document.cookie='resolution='+Math.max(screen.width,screen.height)+'; path=/';</script>
Note that it is has to be in the <head> tag of your site.
Open the adaptive-images.php file and add you media query values into the $resolutions variable.
Here is a snippet of code that is pretty self-explanatory:
$resolutions = array(1382, 992, 768, 480);
$cache_path = "ai-cache";
$jpg_quality = 80;
$sharpen = TRUE;
$watch_cache = TRUE;
$browser_cache = 60*60*24*7;
The $resolution variable accepts the break-points that you use for your website. You can simply add the value of the screen width in pixels. So, in the the preceding example, it would read 1382 pixels as the first break-point, 992 pixels as the second one, and so on.
The cache path tells adaptive images where to store the generated resized images. It's a relative path from your document root. So, in this case, your folder structure would read as document_root/a-cache/{images stored here}.
The next variable, $jpg_quality, sets the quality of any generated JPGs images on a scale of 0 to 100.
Shrinking images could cause blurred details. Set $sharpen to TRUE to perform a sharpening process on rescaled images.
When you set $watch_cache to TRUE, you force adaptive images to check that
the adapted image isn't stale; that is, it ensures that the updated source images
are recached.
Lastly, $browser_cache sets how long the browser cache should last for. The values are seconds, minutes, hours, days (7 days by default). You can change the last digit to modify the days. So, if you want images to be cached for two days, simply change the last value to 2.
Then,… oh wait, that's all? It is indeed!
Adaptive images will work with your existing website and they don't require any markup changes. They are also device-agnostic and follow a mobile-first philosophy.
Responsive designs combine three main techniques, which are as follows:
The technique that I want to focus on in this section is media queries. In most cases, developers use media queries to change the layout, width height, padding, font size and so on, depending on conditions related to the viewport.
Let's see how we can achieve conditional image loading using CSS3's image-set function:
.my-background-img {
background-image: image-set(
url(icon1x.jpg) 1x,
url(icon2x.jpg) 2x
);
}
You can see in the preceding piece of CSS3 code that the image is loaded conditionally based on its display type. The second statement url(icon2x.jpg) 2x would load the hi-resolution image or retina image. This reduces the number of CSS rules we have to create. Maintaining a site with a lot of background images can become quite a chore if a separate rule exists for each one.
Here is a simple media query example:
@media screen and (max-width: 480px) {
.container {
width: 320px;
}
}
As I'm sure you already know, this snippet tells the browser that, for any device with a viewport of fewer than 480 pixels, any element with the class container has to be 320 pixels wide.
When you use media queries, always make sure to include the viewport <meta> tag in the head of your HTML document, as follows:
<meta name="viewport" content="width=device-width, initial-scale=1">
I've included this template here as I'd like to start with this. It really makes it very easy to get started with new responsive projects:
/* MOBILE */
@media screen and (max-width: 480px) {
.container {
width: 320px;
}
}
/* TABLETS */
@media screen and (min-width: 481px) and (max-width: 720px) {
.container {
width: 480px;
}
}
/* SMALL DESKTOP OR LARGE TABLETS */
@media screen and (min-width: 721px) and (max-width: 960px) {
.container {
width: 720px;
}
}
/* STANDARD DESKTOP */
@media screen and (min-width: 961px) and (max-width: 1200px) {
.container {
width: 960px;
}
}
/* LARGE DESKTOP */
@media screen and (min-width: 1201px) and (max-width: 1600px) {
.container {
width: 1200px;
}
}
/* EXTRA LARGE DESKTOP */
@media screen and (min-width: 1601px) {
.container {
width: 1600px;
}
}
When you view a website on a desktop, it's quite a common thing to have a left and a right column. Generally, the left column contains information that requires more focus and the right column contains content with a bit less importance. In some cases, you might even have three columns. Take the social website Facebook as an example.
At the time of writing this article, Facebook used a three-column layout, which is as follows:
When you view a web page on a mobile device, you won't be able to fit all three columns into the smaller viewport. So, you'd probably want to hide some of the columns and not request the data that is usually displayed in the columns that
are hidden.
Alright, we've done some talking. Well, you've done some reading. Now, let's get into our code!
Our goal in this section is to learn about conditional development, with the focus on images. I've constructed a little website with a two-column layout. The left column houses the content and the right column is used to populate a little news feed. I made
a simple PHP script that returns a JSON object with the news items. Here is a preview of the different screens that we will work on:
These two views are a result of the queries that are shown in the following style sheet code:
/* MOBILE */
@media screen and (max-width: 480px) {
}
/* TABLETS */
@media screen and (min-width: 481px) and (max-width: 720px) {
}
Managing images is no small feat in a website. Almost all modern websites rely heavily on images to present content to the users. In this article we looked at which image formats to use and when. We also looked at how to optimize your images for websites. We discussed the difference between progressive and optimized images as well. Conditional loading can greatly help you to load your site faster. In this article, we briefly discussed how to use conditional loading to improve your site's performance.
Further resources on this subject: