What I always found odd: For many years, mobile users had @2x displays and desktop users @1x. If you just decorate an article that as roughly a width of 800px, a crisp article image was bigger in file size for mobile users (@2x) vs. desktop users.
So assuming that mobile users had lower bandwidth, you could simply serve the same picture for both users.
Many articles on image optimization seem to assume that desktop = bigger dimensions.
"Use this size image when the img is being rendered at x size/width/height", size could depend on css, width/height properties, or just imposed by a parent element.
Choosing an image size based on the size of the entire screen is a hack that we've just accepted because we don't have a more precise tool.
Yes, you can technically achieve it with JS, but that's a crutch, and less helpful for page load.
There is a proposed feature in CSS called "container queries" that does exactly this - media queries on the parent container of an element. There are performance concerns and syntax concerns, but they probably will appear in stable versions of browsers in the nearish future.
In the meantime you can enable a version of them in Chrome using a Chrome flag.
Ugh yes. The element containing the image is literally the only thing that matters, tying the image to the screen size is pointless and often infuriating.
For those who don’t see this, imagine this scenario- You have a fluid 3 column layout. The layout has multiple break points. Inside one of those columns you have a grid of images which itself is fluid and has breakpoints, these breakpoints differ from the layout breakpoints. Now what should the srcset be on the individual images in the grid at a 1000px screen size? The answer is why the hell am I being forced to figure this out? The browser knows how wide the container will be around the individuals images, help us out here and use this value to determine what image should be selected in the srcset.
> The answer is why the hell am I being forced to figure this out?
Because the decision is made before CSS loads and is parsed, so the browser doesn’t know any of this.
Don’t get me wrong, this frustrates me endlessly as well, but the reasons for it are clear. Delaying until CSS has been parsed would slow down image loading.
If we can lazy-load the image until the image is in view, we can lazy-load until its container width has been determined. I get there’s reasoning for how things behave as they do, my point is really we’re in this position due to lack of foresight by WHATWG/W3C.
@container queries have been discussed/proposed before, but I've never really experienced a time where I wished they were a thing.
For different screen resolutions and orientations, you have media queries, and I find if you build for mobile first and expand the UI for tablet and desktop with min-width media queries, it's generally pretty straightforward. It may seem like an ugly hack but generally speaking the main question is what device is being used. Most users don't resize their windows on desktop all that much like we do.
With image sizing for containers that may change size, you can abuse background-image and background-size: cover for a quick solution, and for a long term solution you can use an image element and a parent element.
.img-responsive-cell {
/*
this is a div or something
parent element to the img.
you would size this
according to a grid
system containing
element for width and
you could sort the
height out with
%padding or something
else depending on what
you're making
*/
position: relative;
overflow: hidden;
/*
overflow hidden will
make sense in a moment
*/
}
.img-responsive {
/*
the img element
*/
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
min-width: 100%;
min-height: 100%;
width: auto;
height: auto;
\*
or more recently you
can do ->
width: 100%;
height: 100%;
object-fit: cover;
*\
}
This lets the image grow to fill the containing element, maintain aspect ratio so it will essentially be zoomed, centered with left/top and transform, and this also makes for easy hover effects, like so:
Now yes, this isn't attractive and it doesn't give you fine control over what image you're loading, but CSS is ugly anyway and it's a way to achieve a one-size-fits-all solution for the sake of getting something working responsively early in the lifespan. Optimise the hell out of the images and it'll be ok for a minimum viable product.
----
I think the problem with container queries as a concept is that JavaScript is a naturally better tool for the job when it comes to loading media dynamically -- after all you probably want to lazy load images anyway, especially below the fold or if you have a lot of dynamic views.
As someone who has tried to browse the internet on public transport in the UK, I'm a big advocate of lazy loading.
If your website lazy loads images, it's pretty simple to build in a little extra logic to load particular images for particular container element size-ranges.
----
Also, bit off topic but related: in the absence of container queries, we use media queries and srcset, but maybe background-image + media queries might seem like a good plan?
However if I recall correctly as soon as the stylesheet is loaded it downloads all the images referenced in it, so it doesn't achieve much except to reduce strain on painting I guess.
That's why I just keep things simple to begin with.
FYI, a container queries implementation is in the Chrome testing browser.
> Most users don't resize their windows on desktop all that much like we do.
No, but their windows do start out at wildly different sizes. It's not like everyone who's not a web dev leaves their browser maximized all the time.
Container queries are for making micro layouts. Sometimes a layout alternative can benefit from loading different media but that's not the primary purpose.
> maybe background-image + media queries might seem like a good plan?
If an image is content and not purely decorative, it belongs in the document, the HTML, where it has an 'alt' attribute for a text alternative.
So often one key point that is missed - use the right format for the right image type. In general, for photographs use JPEG, for illustrations use PNG or SVG.
One thing we found really helpful for optimizing our images was building our own internal image CDN service.
Our image URLs look like this: imgsvc.example.com/url/size(64),fit(cover)/{url}/image.png where url is the source image. This ends up being the image src URL used in production. We have a domain whitelist so it can’t be too badly abused. We can change any number of parameters. You can see here I’m setting the fit and size and image format (.png). There’s even an option to fit the image to a bytes budget. It’s invaluable not having to think about source image sizes, we just drop whatever image we have into an Azure bucket and drop the URL into that service.
You can make sure it's not abused at all if you sign the URL. In terms of performance it's a free feature because once the image is generated, you no longer have to check the signature (you only check it first time to generate).
I'm fairly sure this is not true. I've seen webpages take >1 sec to load because of a single unoptimized image that weighs around 300mb or more. Yeah, idk how they get that big either
That sentence is phrased a bit odd, but if you're trying to say media size is even same order of magnitude as JS/CSS size in practice, then... no. Not even close.
Anyone have good tips on how to monitor web vitals in an ongoing basis? I've found CI solutions to be lacking since they don't easily run in a production-like environment that includes realistic content and third-party stuff (especially ads).
Google webmaster tools has a basic chart that shows web vitals, likely as seen from google bots.
You can setup your own lighthouse setup, and measure the production sites from any number of vantage points, ideally from where you have most users coming from.
What I always found odd: For many years, mobile users had @2x displays and desktop users @1x. If you just decorate an article that as roughly a width of 800px, a crisp article image was bigger in file size for mobile users (@2x) vs. desktop users.
So assuming that mobile users had lower bandwidth, you could simply serve the same picture for both users.
Many articles on image optimization seem to assume that desktop = bigger dimensions.