HTML picture tag in practice — PNG and WEBP formats

Radek Anuszewski
Frontend Weekly
Published in
7 min readSep 16, 2018

It is a known problem how to include an image in different sizes — fortunately, almost all browser supports <picture> tag. It works especially well with modern image formats, like webp, which gives us nice and easy solution to reduce page size and improve user experience.

Less is more, especially when it comes to size. Photo credits: MockupEditor.com

Important note

I have created a GH page for repository for this post:

So you can try it live. For example, open DevTools and switch between mobile, tablet, or orientations and see in Network tab when it loads proper image.

Prerequisites

HTML picture tag

<picture> tag allows us to load different images for different requirements. It may contain zero or more <source> elements and one <img> tag as a fallback for older browsers.
Support is quite wide today:

If you have to support old browser like IE 11 or Safari on iOS 9.2.x, you can use picture polyfill:

Google’s WEBP image format

WEBP format was introduced by Google, they provide some interesting case studies which provide results proving how effective it is:

But what about browsers support? As we can find on CanIUse, it is supported only on Chromium-based browsers:

Is it a problem? I don’t think so. Webp support is being discussed on Mozilla forums, so it’s a possibility that sooner or later it will be supported:

Also, WEBP is under consideration in Microsoft Edge browser:

You can “speed up” WEBP support in Edge by voting for this idea on this page: WebP image format support. Every vote is important for the faster Web!

Implementation

I’ve created a Github repo related to this article:

Where you can find how end result looks like.
I want to divide implementation section to 5 subsections:

  1. Very large 4k screens, 1921px and wider
  2. Regular desktop/laptop screens, from 1281px to1920px width
  3. Tablet landscape, from 461px to 1280px width
  4. Tablet portrait, from 461px to 1280px width
  5. Mobile screens, to 460px width

And each sub-section will have 2 versions — regular PNG image and WEBP image. As an example I want to use vargazs’s photo from Pixabay:

Which is available for free download with many interesting resolutions.

Implementation

Starting point

The starting point looks like this:

There is no <source> defined, so fallback with <img> tag is used.
What is the size of used image? Let’s see:

Starting point — no optimisation

And now we can start to add images designed for particular size.

How to create WEBP image?

There is many online converters, but I want to use fastest way in my opinion, converting from Intellij IDEA:

Convertion from PNG to WEBP directly from IDE

Quite big drawback of this solution is that Intellij overrides base image, so I have to make a copy and make convertion in different folder.

Quick note:
Below the same image with different sizes is used, but it’s common to use different images for different screens, for example image for mobile has less details than for 4K screen

Very large screens

I’ve created folder named very-large and placed here image 4000×1591 size. I’ve added a source tag˛with proper PNG image type (it’s very important) and media query needed for large screens: media=”(min-width: 1921px)”.
Now code looks like this:

Because my screen is 1366px I have to fake large resolution with Chrome Developer Tools:

Large resolution faked with DevTools

How it looks like in Network panel?

Large PNG image

Proper image was loaded, but can’t we make it smaller? 2.9 MB could be way too much on slower network.
Let’s use WEBP lossless compressed version and add it to code:

2 things are very important:

  1. I’ve added type=”image/webp” which is used by browser to decide whether this type of image is supported or not.
  2. WEBP image has to be above regular version, because browser takes first source which meets criteria defined in media.

What is the size of new image?

Much smaller WEBP image

WEBP image is 3 times smaller than original image! It makes a huge difference, especially when many images are used on the site. But what if we don’t need image with such a large size?

Regular desktop/laptop screens

From vargazs’s Pixabay site I have downloaded PNG image with 1920×763 size and named it bike-regular.png. With IDE I have created WEBP version. I’ve also added 2 new sources with media=”(min-width: 1281px) and (max-width: 1920px)”, to load proper image:

What is the size difference? Let’s compare PNG size (for test, WEBP image was removed with HTML comment) and WEBP image:

Regular PNG size
Regular WEBP size

WEBP image is 200 KB smaller than PNG version. The result isn’t as significant as with previous example, but remember — lossless compresion is used, lossy compresion could provide much smaller WEBP image.

Regular desktop/laptop screens with 75% encoding quality WEBP

You have to see that:

Unbelievable! 10x smaller

As you can see, 75% encoded image is 10 times smaller than lossless WEBP and 15 times smaller than PNG! I’m not a UX guy so it’s hard to me to see quality decrease, for me images are the same. The best solution is to always try to experiment with encoding quality — results could be amazing. Of course, it should be confirmed by UX person that quality losses are unnoticeable.

Important note!
Because many laptops have 1366px screen, it may be a good practice to dividemedia=”(min-width: 1281px) and (max-width: 1920px)” breakpoint to 2 breakpoints: media=”(min-width: 1367px) and (max-width: 1920px)” and media=”(min-width: 1281px) and (max-width: 1366px)” and provide separated images with 1920px and 1366px width.By this way, every screen get more accurate image which allows to further reduce the size of the page.

Tablet landscape, tablet portrait

For the sake of simplicity, for both directions I have used the same image with 1280×509 size, but named bike-tablet-landscape for horizontal and bike-tablet-portrait for vertical view. It could be switched in Chrome Developer Tools.

Let’s see code changes:

Media queries were extended with (orientation: portrait) and (orientation: landscape) to differ between directions.
Let’s see image sizes:

PNG tablet landscape
WEBP tablet landscape

Again, size descrease is noticeable but not astonishing. However, 75% WEBP encoding quality does its job well:

Lossy WEBP is 8x smaller than loseless

Mobile screens

For the last example I’ve used 640×254 image. This image is displayed with media=”(max-width: 460px)” rule.

So, let’s see results:

PNG mobile
WEBP mobile
WEBP mobile 75% quality

There’s no suprise, lossless WEBP is smaller than PNG, but 75% endocing quality still does the best job

Conclusion

It’s worth to use WEBP images — Chrome has over 50% of the market, so many users will load much smaller pages. Alsom it’s worth to experiment with lossy compression when quality loss is unnoticeable, it may save megabytes when page has many images.
P.S. Don’t forget to vote to make Web better for Edge users! :)

--

--

Radek Anuszewski
Frontend Weekly

Software developer, frontend developer in AltConnect.pl, mostly playing with ReactJS, AngularJS and, recently, BackboneJS / MarionetteJS.