This article was originally posted on EnmaScript.com, go there for a better reading experience.
In the last Chrome Dev Summit they have shown some really amazing things, one of the things that caught my attention was to see how things we give for granted can improve the performance of a website on a big scale.
Let's take the case of Twitter and Facebook, when you upload a gif animation to these platforms, we assume that they automatically optimize the images in order to give us the best/most optimized experience (and they do) but maybe not in the way we expected... did you know that they transform the animated gif images into a video to make the site more performant?, wait, what? really? yes, they transform gif images into video format because the compression algorithm of the videos is more sophisticated and applies intraframe compression which ends up in videos with smaller sizes, check it out:
See how the videos even have a label saying "GIF" when they actually are videos? this of course with the end of letting users know that originally the user shared a gif. Now the fun part, let's see those numbers, I took the freedom of measuring how good is the impact on performance when having a gif image in your site vs an MP4 video and the results are great.
I recently posted an article using a gif to show an example and I recently changed it as well to be an MP4 video, check this:
The gif optimized version of the image is around 1.5mb (yes, that is optimized) and it took the browser ~11 seconds to download the full image (with fast 3g).
Now, let's transform our gif to MPEG-4 by using ffmpeg to do it, I will just run the command
ffmpeg -i image.gif image.mp4 and it'll automatically convert my gif to a mp4 video, then to make the video look like a gif I'll use the
<video> tag with the next attributes:
<video autoplay loop muted playsinline></video>
Check out the results:
BOOM! just like that the video weights ~350kb, that's around 23.3% of the original gif size, 76.7% less than the original gif and it took the browser around 2.8 seconds to download it, no more words needed, if you use animated gifs in your site, you have a mission. Also as a plus, if you think this is great now, imagine in the near future when all browsers start to support AV1 compressed video format, it's around 30% better than WebM, and about 50% better than MPEG-4, you can learn more about it here.
After generating your images dynamically you can then decide when to show them by leveraging the
srcset attribute from HTML5:
<img srcset="img.jpg 480w, img-medium.jpg 768w, img-large.jpg 1080w" size="50vw" src="img-large.jpg" alt="A great image" />
In this way, we're letting the browser know which images to use and when. To learn more about how to use this technique check MDN Responsive Images.
Use WebP Images with the picture tag to use better-compressed images and get compatibility between browsers
WebP format has been around for a while now, it's not fully supported by old browsers but it already has some decent support and if we use the
<picture> tag with it we can extend the browser support even further.
Why should we even bother to use WebP Images at all? the answer to this question is very simple, WebP Images are 25-35% lighter than PNG and JPEG images, and sometimes transforming a PNG image to WebP could reduce its size close to 45%, if you want to know more check this study made by Google. Ok, now let's analyze the following implementation:
<picture> <source type="image/webp" srcset="image.webp"> <source type="image/png" srcset="image.png"> <img src="image.png"> </picture>
<picture> tag kind of works like the
<video> tag but for images, inside of it you specify the images that you wish to load by using
source tags and you add a
srcset attribute. Now, why is it good to use this tag alongside with WebP? good question, when the browser reads the sources inside the pictue tag, it will only fetch the first supported image format found which means that if WebP is used in the first
<source> tag and it's not supported you can just specify a PNG or JPEG fallback and it'll work just fine, also as an extra security step you can specify an image using the
<img> tag for old browsers that don't support the
<img data-sizes="auto" data-src="image2.jpg" data-srcset="image1.jpg 300w, image2.jpg 600w, image3.jpg 900w" class="lazyload" />
You just have to add the
data- prefixed attributes as well as the
lazyload class and that's it, also this technique is applicable not only for images but for iframes, videos...
Advice: If you're going to use a different module or you're thinking about building your own lazy loading script, make sure that the script uses Intersection Observer API for this instead of scroll events, this will avoid performance issues and will provide a smoother experience.
Compress your images with Lossy Compression, an ideal starting point is between 80-85% of the original image quality, this keeps most of the details and drops the file size between 30% and 40%, but this is not something that will work for all cases, many times you can compress images even further depending on the type and priority of the given image in your site. A module to help you with this task is imagemin, it has plugins for lossy and lossless compression, it's always recommended to use lossy compression but depending on your case you might find lossless compression more adequate.
Ok guys I think that's it for this article, if you enjoyed it be sure to leave a comment and share it with your friends, remember that you can find me on twitter @duranenmanuel or just write me an email at firstname.lastname@example.org.
See you in the next one.