Blade component for responsive images
Webcu • January 27, 2021blade responsive html frontend
After I published my last article, the result of Lighthouse dropped significatively, overall on mobile devices. Looking to the Lighthouse recommendations, one of the problem was that I was serving an image bigger than needed. It recommended to Serve Responsive Images. I didn't have idea about responsive images and how difficult and interesting is that topic.
An over-simplify definition is:
Different images in HTML that work well on devices with widely differing screen sizes, and resolutions.
How to render responsive images in HTML?
HTML provides two main elements to render images:
According to this article: Responsive images, if you're just changing resolutions use srcset,
if we are just changing resolutions, the best is to use the srcset
attribute of the
"Optimal" dimension of the responsive images
Initially I tried to figure out what are the "optimal" dimensions of the responsive images, but there is not a perfect answer for that. After reading the articles: Responsive images 101 Part 9 Image breakpoints and Applying srcset, choosing the right sizes for responsive images at different breakpoints, I found that we should have more breakpoint at larger sizes. I have created these breakpoints for the moment:
Which width and height should we use?
After having the images for the different breakpoints, I still needed to solve the problem of show an explicit
height to avoid the Cumulative Layout Shift (CLS) issue. This part was tricky. This article of Addy Osmani:
helped me a lot. Initially, I played with a 1.3 relation between the width and the height, but after read the previous
article I learned that it's very important all the images shared the same ratio. This site calculates the ratios:
Aspect Ratio Calculator. After have the images with the same ratio, I
needed to have a fix
height of that ratio, but even after doing it, the browser always showed me the
images with the dimensions I set. The problem was that I needed to make the dimension dynamic using CSS!
This is the code of the
<img src="assets/img/originals/webcu-lighthouse.png" srcset="assets/img/320x180/webcu-lighthouse.webp 320w, assets/img/640x360/webcu-lighthouse.webp 640w, assets/img/880x495/webcu-lighthouse.webp 880w, assets/img/1024x576/webcu-lighthouse.webp 1024w, assets/img/1200x675/webcu-lighthouse.webp 1200w, assets/img/1760x990/webcu-lighthouse.webp 1760w" alt="Lighthouse results" class="mb-2 w-full" width="320" height="180" >
height attributes specified have the same ratio that the images, and the TailwindCSS class
makes sure the image expand to all the space available to it.
Resume: In order to add an explicit width and height to responsive images, we need to declare those attributes in the image with the same ratio that the images and adjust the width dynamically with CSS!
This article was very interesting as well: Setting height and width to images is important again. It's about the importance of declaring images with an explicit width and height.
Extracting the responsive images to a Blade component
Like we saw previously, the code of the
img element is large, tedious, and prone to error. Then I decided to extract
it to a Blade component:
We can use it now in any of our templates like this:
... // Passing a variable to the component <x-responsive-images :imageName="$page->cover_image_name" :imageExt="$page->cover_image_ext" :altText="$page->cover_image_alt" /> /** * Passing hardcode values to the component * Notice the '' inside of the "". It's not a typo :) */ <x-responsive-images :imageName="'Name-Image'" :imageExt="'png'" :altText="'Hello World of responsive images'" />
The attributes of a Blade component are directly accessible inside a php block
@props(['imageName', 'imageExt', 'altText']) ... @php ... $imageSet = ... $imageName . '.webp ' . $dimension . 'w' ... @endphp
The DIMENSIONS constant could be declared outside of the component.
I ordered my images like:
but it can be any other structure.
Extra bonus: Resize Image script
The resize process can be done in many ways, with a Lambda function in AWS for example. I have decided for the moment, given the actual requirements of the blog, to do it manually. To do it I'm using the library Sharp. It really has surprised me. Here is a copy of the script I'm using actually:
- Serve Responsive Images
- MDN Responsive Images
- Responsive images done right guide picture srcset
- Responsive images 101 Part 9 Image breakpoints
- Applying srcset, choosing the right sizes for responsive images at different breakpoints
- Optimize CLS
- Aspect Ratio Calculator
- Setting height and width to images is important again