-
Notifications
You must be signed in to change notification settings - Fork 10.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(gatsby-image): Responsive Art Direction #26119
feat(gatsby-image): Responsive Art Direction #26119
Conversation
Dependent PR has been merged, ready to rebase this. Headsup that I probably won't get around to take a look until later today or tomorrow. Additionally, I'd expect @wardpeet to also hope for e2e coverage for this PR. Especially if none of the tests need to change for that (but perhaps you're waiting to rebase before changing those). |
9b9edca
to
e31abde
Compare
I'd need some guidance on how to approach that. I don't know if there is currently any high-latency network tests or any tests that track CSS transition or caching behaviour? They're generally assuming that if X and Y inputs are provided, Z output is expected, these kind of tests would be more nuanced.. If desirable, I can share some clips of what's being fixed, before/after of this PR under network throttled "Slow 3G"?
The tests only broke and required the proper Jest The existing Art Direction tests ensure the image source changes accordingly to meet it's media condition, but that's it. |
packages/gatsby-image/src/index.js
Outdated
if (mql.addEventListener) { | ||
mql.addEventListener(`change`, this.handleVariantChange) | ||
} else { | ||
// Deprecated 'MediaQueryList' API, <Safari 14, IE, <Edge 16 | ||
mql.addListener(this.handleVariantChange) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We probably want to clean it up with componentWillUnmount
. Besides that this looks great! Thank you!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm happy to take over as you've been waiting long on this feedback.
Presently, a render is triggered from `onload` event calling `handleImageLoaded()` and state such as fluid type `aspectRatio` or fixed type `width` & `height` values for CSS are only updated then. Placeholder lazy loading state is also not reset as the component isn't aware of when loading a new variant begins, if the variant is cached, there is still a delay in `onload` event until the image request has returned a response from the server, noticeable delay on high latency connections, breaking layout(as content/component has not updated to fit the new breakpoint as soon as it should). `matchMedia()` resolves that. We can then detect if the image has been cached internally and then trigger a render which might leverage browser cache detection, otherwise reset the lazy load placeholder behavior.
…andleImageVariant()`, we don't have to rely on `imgLoaded` state (with no change from `true`) in `handleImageLoaded()` to render an update. Instead we can ensure that it only sets `imgLoaded` to `true` as it's intended for, only when the state is actually `false`.
Unclear if this should be supported for image variants, but now enables supporting this feature when the image variant changes too, instead of just the first time(`componentDidMount()` or for Intersection Observer in `handleRef()`).
e31abde
to
058184f
Compare
Rebased onto master. @wardpeet good catch there, sorry about missing that! Handing this PR over to you to wrap up thanks. |
@polarathene Thank you, I'm grateful that you're taking the time to finish it. Awesome work so far! 👍 👏 |
Sorry, we have a misunderstanding. You said earlier you'd be happy to take over the PR, and I thank you for that. I need to prioritize my time on other tasks that get me closer towards earning a living and landing my first job as a web developer. I've only been handling the other related PR that doesn't seem like it'll be merged, as expecting users to spend time investigating |
OH yeah my bad "Handing this PR over to you to wrap up thanks." I'll take it over :)
I know, that's why we are in desperate need to create a new gatsby-image that properly tell the user what it can do and what you need to do yourself. |
Thanks!
Wasn't that meant to be solved with the refactor to hooks? I had inquired about that to you in an issue/PR back around May-June, asking if it was being worked on publicly or if the core team had a private refactoring going on. Offered to collaborate on that, but never heard back. I'm not currently in a position to have spare time for a hooks refactor anymore, but if my situation improves within the next 6 months, I might be able to give it a shot if there's still no progress. Originally I wanted to get these June PRs discussed with the team, iterated on and merged, then tackle the hooks refactor in advance for Gatsby consider when ready. |
I have something to share in a few days :) Here is a sneak peek, I've only started on it a few weeks ago and mostly was an exploration on how to fix LCP web-vitals. Of course through graphql you can just use a fragment and do
|
Users expressed concern about the additional render triggered from this state update when unnecessary.
With changes to the related complimentary Art Direction PR, the `isBrowser` conditional can be removed and added to `isArtDirected` as a guard instead.
Minor update to accommodate the request here to avoid |
Closing, this is fixed in our new gatsby-plugin-image component. Thank you for your contribution! <3 |
Description
Presently, a render is triggered from an
onload
event callinghandleImageLoaded()
and fluid typeaspectRatio
or fixed typewidth
&height
state values for CSS are only updated to the new variant after it's loaded.Placeholder lazy loading state is also not reset as the component isn't aware of when loading a new variant begins. If the image variant is cached, there is still a delay with the
onload
event until the image request has returned a response from the server; a noticeable delay on high latency connections - breaking layout (as the content/component has not been updated yet to fit the new breakpoint).matchMedia()
resolves that. We can then detect if the image has been cached internally and then trigger a render which might leverage browser cache detection, otherwise reset the lazy load placeholder behavior.See individual commits for more logical grouping and further details related to those additions.
May need to rebase after the following PRs are merged:
jest-matchmedia-mock
to replace DIY mock #26118 to pass tests.My "deprecated" comment for
MediaQueryListListener
(note, modern browsers alias this for now) is not quite correct, MDN encourages using the newer standard event mechanism, the older non-standard API is kept by browsers for backward compatibility. A newer version of Safari that's to be released this year will also support the newer API. MDN browser compatibilityRelated Issues
Originally implemented in this PR, which has been split out into several smaller ones.