Skip to content

Conversation

@benjaminsehl
Copy link
Member

@benjaminsehl benjaminsehl commented Mar 6, 2023

WHY are these changes introduced?

Improve developer ergonomics for working with the Image component and ensure greater performance across devices and screen sizes by making responsive images a default and accounting for common lighthouse warnings.

WHAT is this pull request doing?

<Image /> now supports all unit types, and a more natural set of APIs (better aligned with standard HTML) for both for responsive and fixed with images.

Example markup:

<Image 
  src={image.url}
  alt={image.altText}
  aspectRatio="1/1"
  sizes="100vw"
/>

Would result in:

<img 
  srcset="https://cdn.shopify.com/s/files/1/0551/4566/0472/products/Main.jpg?width=300&height=300&crop=center 300w, … more sizes … https://cdn.shopify.com/s/files/1/0551/4566/0472/products/Main.jpg?width=3000&height=3000&crop=center 3000w"
  src="https://cdn.shopify.com/s/files/1/0551/4566/0472/products/Main.jpg?width=100&height=100" 
  alt="alt text" 
  sizes="100vw" 
  loading="lazy" 
  style="width: 100%; height: auto; aspect-ratio: 1 / 1;">

Sometimes you will just want a fixed sized image — we still generate srcset for this, however, as different devices have different pixel densities. We also account for the compound property common on all our other components, data so you can simply pass the response from the Storefront API and set the width.

So this:

<Image data={image} width="5rem" />

Would result in:

<img 
  srcset="https://cdn.shopify.com/s/files/1/0551/4566/0472/products/Main.jpg?width=80&height=80&crop=center 1x, https://cdn.shopify.com/s/files/1/0551/4566/0472/products/Main.jpg?width=160&height=160&crop=center 2x, https://cdn.shopify.com/s/files/1/0551/4566/0472/products/Main.jpg?width=240&height=240&crop=center 3x" 
  src="https://cdn.shopify.com/s/files/1/0551/4566/0472/products/Main.jpg?width=80&height=80" 
  alt="alt text" 
  loading="lazy" 
  style="width: 5rem; height: auto; aspect-ratio: 3908 / 3908;">

Notice that even though we didn't pass in an aspectRatio prop, we were still able to generate a correct style property, by using data.width and data.height.

Todo:

  • Write tests
  • Write guide/docs

Picture Element

In the future, this Image component would be able to be composed within a Picture component, which would look something like:

 <Picture
  width="100%"
  {...props}>
  <Image 
      src={data.src} 
      aspectRatio="4/5" 
      sizes="100vw" 
      media="(min-width: 30em)" />        
  <Image 
      src={data.src} 
      aspectRatio="2/3" 
      sizes="100vw" 
      media="(min-width: 45em)" />
  <Image 
      src={data.src} 
      aspectRatio="1/1" 
      sizes="100vw" />
</Picture>

When inside the component Image should render a source element, with the last Image component rendering a img element as the fallback. Ideally we'd somehow do that automatically — looking at the nodes of children, and then setting the as prop for you. Alternatively, our component could re-export the Image component but as a <Source /> component — which would be in keeping with HTML semantics.

HOW to test your changes?

Post-merge steps

Checklist

  • I've read the Contributing Guidelines
  • I've considered possible cross-platform impacts (Mac, Linux, Windows)
  • I've added a changeset if this PR contains user-facing or noteworthy changes
  • I've added tests to cover my changes
  • I've added or updated the documentation

@github-actions

This comment has been minimized.

@benjaminsehl
Copy link
Member Author

I've moved this over from the old hydrogen-react repo: Shopify/hydrogen-react#114, and fixed some things with types.

@github-actions github-actions bot had a problem deploying to preview March 7, 2023 06:12 Failure
Copy link
Contributor

@cartogram cartogram left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of going from Image to Image and ImageLegacy, I think it makes more sense to go from Image to Image and AlphaImage first.

So rollout would happen in 3 stages

  1. add the new Image as AlphaImage (in non-breaking release)
  2. rename the Image to LegacyImage and rename AlphaImage to Image (in next major release)
  3. remove LegacyImage (following major release)

@benjaminsehl what do you think?

@cartogram cartogram self-assigned this Mar 7, 2023
@cartogram
Copy link
Contributor

cartogram commented Mar 7, 2023

Taking this over from @benjaminsehl, I have some basic tests in and the build is passing, but going to give everything a second look and add a lot more tests as I go.

@github-actions github-actions bot had a problem deploying to preview April 6, 2023 13:58 Failure
@github-actions github-actions bot had a problem deploying to preview April 6, 2023 14:29 Failure
Copy link
Contributor

@lordofthecactus lordofthecactus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new component seems to break the demo-store.
image

Couple of questions:

  1. I see the style attribute is used which has quite a strong specificity. The demo store broke so I'm thinking there might be a strong assumption here that these styles can apply broadly. How as it decided that this was to be included by default?
  2. I see it generates a large srcset. Is this the best practice when using cdn? how was this decided and are there any implications?

@github-actions github-actions bot had a problem deploying to preview April 12, 2023 13:22 Failure
@github-actions github-actions bot had a problem deploying to preview April 12, 2023 15:37 Failure
@github-actions github-actions bot had a problem deploying to preview April 12, 2023 15:41 Failure
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants