Skip to content
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

Update image dimensions inside of a timeout to ensure image replacement is rendered on screen before measuring #48

Closed
wants to merge 5 commits into from

Conversation

goldenapples
Copy link
Contributor

@goldenapples goldenapples commented Sep 16, 2019

The dimension calculations were calculating image dimensions before the image is rendered on the page, which gives incorrect element dimensions, leading to a misproportioned image.

This PR attempts to fix that issue by setting a 200ms timeout after setting an image src, in order to better calculate the space the element takes up in the document.

The dimension calculations were calculating image dimensions before the
image is rendered on the page, which gives incorrect element dimensions,
leading to a misproportioned image.

This PR attempts to fix that issue by recalculating dimensions on a
Mutation event, when the src is first replaced, rather than immediately
on setup, to better calculate the space the <img> element takes up in
the document. (I'm torn between this approach and just doing it in a
timeout... I think the timeout would be better performance, but at the
risk of not being as accurate.)
@goldenapples goldenapples changed the title Use MutationObserver to update image dimensions when it renders Update image dimensions inside of a timeout to ensure image replacement is rendered on screen before measuring Oct 3, 2019
Copy link
Contributor

@roborourke roborourke left a comment

Choose a reason for hiding this comment

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

Some minor code style consistency. Also wondering if there's anything that could be done to avoid the timeout as it still feels like it might be error prone.

assets/gaussholder.js Outdated Show resolved Hide resolved
assets/gaussholder.js Outdated Show resolved Hide resolved
render(canvas, element.dataset.gaussholder.split(','), final, function () {
// Load in as our background image
element.style.backgroundImage = 'url("' + canvas.toDataURL() + '")';
element.style.backgroundRepeat = 'no-repeat';
setTimeout( function() { calculateDimensionStyle( element ); }, 200 );
Copy link
Contributor

Choose a reason for hiding this comment

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

Could we use the image element load event perhaps? This still seems like it could be brittle

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is already happening in the image's onload event handler. The timeout here is just trying to work around some issues where the dimensions weren't calculated properly, because apparently the "onload" event fires when the file load is complete, but before the DOM rendering is necessarily complete.

I could probably remove the 200ms timeout and just leave it in a timeout or a requestAnimationFrame to make sure the image renders on screen before measuring it. You're right, this does feel brittle - I'll clean it up and see what I can do to make the callback happen as soon as possible.

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah ok, so if this is really just adding a small extra buffer right now before the blurred image is getting swapped out then I think it's ok. I'll test it out on local and see what happens to see if I have any other ideas.

@goldenapples
Copy link
Contributor Author

Some minor code style consistency.

I'll run eslint --fix over the whole file to clean up style inconsistencies separately. I originally thought not to do that because it would break history... but there's not too much history in these files yet 👍.

I'd also love to have someone with a front-end focus (pinging @joeleenk to get it on your radar possibly?) to follow this up with some tweaks to the timing of the whole image replacement and blur process to make this feel as slick as we can get it - I think the lazyloading here is a really nice touch to offer as a platform feature but it feels a little slow and uneven right now.

Brings this file more in line with our coding standards.

Note that I had to turn off the "no-var" rule to avoid conflicts with
grunt uglify, which for some reason doesn't support let and consts yet.
@roborourke
Copy link
Contributor

Just a note here - there are some updates along with WP 5.5 that might mean we don't need to do this. I actually fully removed the image dimensions stuff in #55 - WP 5.5 adds width and height attributes to all images now and in smart media we prevent Tachyon from removing the image dimensions as well. Lastly in #55 this moves towards relying on the browser's loading="lazy" handling so we never actually swap out the image srcorsrcset`.

@igmoweb
Copy link
Contributor

igmoweb commented Oct 15, 2020

@roborourke @goldenapples I think this same issue is happening in Orgvue site: https://github.com/humanmade/concentra/issues/950. I've disabled it in production but kept the Gaussholder enabled in development.

The problem seems to be appearing exclusively in Safari, not Chrome or Firefox so you should see the images in Chrome but not in Safari because their heights have been set to 0.7px. When trying to debug, this problem doesn't appear as it seems to be a timing issue.

Copy link
Contributor

@roborourke roborourke left a comment

Choose a reason for hiding this comment

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

I think this is good, sorry for the long delay.

This was referenced Nov 17, 2020
@igmoweb
Copy link
Contributor

igmoweb commented Nov 17, 2020

There's a new fix in here: #57 that avoids timeouts and also use the IntersectionObserver API to detect images in the viewport. It includes several other improvements like webpack bundling. I think we can close this one.

@igmoweb igmoweb closed this Nov 30, 2020
@igmoweb igmoweb deleted the mutation-observer branch April 14, 2021 08:41
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.

3 participants