Replies: 4 comments 8 replies
-
+1! Some questions:
|
Beta Was this translation helpful? Give feedback.
-
I think the people want placeholders and preloading before layouts but I think layouts would be a hit Would there be a way to influence how many responsive images get created by each layout? Could densities remain as a layout? |
Beta Was this translation helpful? Give feedback.
-
I like the added defaults! A question for |
Beta Was this translation helpful? Give feedback.
-
This has been accepted for stage 2. Please continue discussion on the stage 2 issue: #1042 |
Beta Was this translation helpful? Give feedback.
-
Summary
The current Astro image component offers a lot of flexibility for displaying images. It supports
densities
andwidths
props to help generate the correctimg
attributes, and the default image service supports modern formats such as AVIF and WebP. While this gives users the tools to create performant and responsive images, it does not give guidance in how to use them - and requires that they are set on all images. This proposal is for a more opinionated image component. It would offer all of the tools from the current component, and also introduce new props and config options that follow best practices by default.Background & Motivation
Displaying images on the web is difficult, even for the most experienced developers. Users suffer slower page loads, and poor experience as the page layout jumps around. Meanwhile sites experience poor core web vitals scores for performance, cumulative layout shift (CLS) and largest contentful paint (LCP).
The most common
img
tag attributes are well known:src
,alt
,width
andheight
, there are several lesser-known attributes that are needed if an image is to have the best performance. All of these are optional according to the spec, but best practices require most of them. The most important aresrcset
,sizes
,loading
,decoding
andfetchpriority
.These are a lot of attributes to remember and understand, though the final three have values that are usually safe to think of as dependent on just whether the image is onscreen when the page loads. Astro Image already sets
loading
anddecoding
tolazy
andasync
by default. Howeversrcset
andsizes
have no simple rules, and can be very hard to do correctly. Images also need to be styled correctly if they are to be responsive and avoid CLS.This proposal is inspired by the attributes generated by
@unpic/astro
, which I created, but with some changes to make it closer to the existing component behavior, and less focussed on image CDNs.Goals
Details
In order to automatically generate the correct attributes for an image, we need to know how it should behave when resized. I propose introducing a
layout
property to define this. When set, this will enable the new mode, and set defaults for all required attributes.<img>
attributesThe most important attributes to set for best practices are shown below. These will all have appropriate values set, according to the specified layout. These can be overridden, but should not need to be in most cases.
srcset
: the most important extra attribute, and the one that is most likely for developers to know about, this tells the browser which image sources are available to download. There should be several entries, the sizes of which depend on the layout and image size.sizes
: a browser uses this attribute as a hint to help it choose which source to download. It is a set of media conditions, which normally contains viewport sizes for responsive images. This would be set automatically based on the layout and image size.loading
: by default, all images are loaded as soon as they are encountered in the HTML. This is not needed for images that are offscreen when the page loads, so should be set tolazy
for these. Currently set to lazy by default.decoding
: a browser needs to decode an image file before displaying it onscreen. This attribute is a hint as to whether this should happen while the page is rendering (sync
), or wait until the DOM is complete (async
). As withloading
, offscreen images should be decoded asynchronously for best performance. Currently set to async by default.fetchpriority
: this tells the browser what the priority should be for network requests for this image. The priority of the main images on your page can make a significant difference to your LCP, so should behigh
for these. Similarly, setting offscreen images tolow
means that the network is used for more important images that are visible onscreen when the page loads.New
<Image>
propertiesThere would be new properties added to the
Image
component. The existingdensities
property would not be supported when using the new image handling.widths
would be supported, but not recommended as it is better to allow it to be set automatically when usinglayout
.layout
By default the images will have a class added that handles basic layout, as described below. These will be set at low specificity so they can be overriden by component and page styles. By default
object-fit: cover
is set for all layouts unless overridden by thefit
prop. Layouts that preserve aspect ratio will haveaspect-ratio
set as an inline style.I propose the following layouts, but I am open to discussion:
height
is supplied then the height is fixed at that size when the width is resized, otherwise the aspect ratio is maintained. Ifwidth
is supplied, that will be the maximum width. Best for hero images that are displayed at the full width of the screen.priority
By default, images will be lazy loaded setting
loading="lazy"
,decoding="async"
andfetchpriority="low"
. The boolean propertypriority
enables the opposite. This should be used for the LCP image, and other important images above the fold.fit
Sets the
object-fit
value. By default the value iscover
, which means image is resized to fill the container, while retaining the aspect ratio. This may mean that some edges are cut off if the aspect ratio is different. This can be changed to any other supported value, but the most useful is likely to becontain
, which resizes it to fit inside the specified size, while mainaining aspect ratio. This may leave space around the image if the aspect ratio does not match.position
When cropping or padding an image where the aspect ratio does not match, the default behavior is to centre the image. Setting this will change the position. Some image services may support advanced values here that attempt to focus on a face or other point of interest. This will be documented by each service.
unstyled
If set, no style or class would be applied to the image. The developer would be responsible for setting the appropriate style for the image.
New config options
This adds a
layout
option to theimage
config. When set, this will set all images to default to that layout. This can be overridden on each image.Crop support in image services
While most of these features could be supported with CSS alone, they would be more efficient if image services supported cropping. This would need an additional RFC, and an expanded API for image services to allow them to handle this. Not all image services can support this (most importantly Vercel and Contentful), so this should be handled gracefully.
Example
Future plans
These plans are currently out of the scope of this RFC, but may be defined in a future RFC:
picture
tags for formats. Later could support art direction if an API with good DX can be worked out.References
These served as inspiration, and/or are useful for understanding best practices:
Beta Was this translation helpful? Give feedback.
All reactions