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

feat(gatsby-remark-images): make images blur up #7800

Merged
merged 26 commits into from
Nov 21, 2018

Conversation

jamesadarich
Copy link
Contributor

Hey guys,

This is a proposal for adding functionality to mimic the blur up effect in gatsby-image for gatsby-remark-images. This could be nicer I think but I can't see an obvious way to do that without a great deal of refactoring around how the remark plugins are integrating (but hopefully you guys can guide to an awesome solution :) )

The pros and cons of this solution, I believe, are as follow;

Pros

  • in keeping with current code (should be minimal impact change)
  • works for images with transparencies
  • no need to calculate ratio

Cons

  • inline script - not great for CSP but I've had some thoughts about resolutions for this in general (but this is a separate piece)
  • reliant on class names staying the same (but I did a minor refactor to help avoid this being a problem)
  • not really testable (I have tested against a local gatsby solution and it seems to work cross browser :) )

Let me know what you guys think about the solution and any ideas you guys have

@KyleAMathews
Copy link
Contributor

Looks promising!

Instead of inlining the code however (which would cause a lot of code duplication), you can add the code using gatsby-ssr.js to the <head> using onRenderBody https://next.gatsbyjs.org/docs/ssr-apis/#onRenderBody

@jamesadarich
Copy link
Contributor Author

@KyleAMathews I've given this a go but under tests it would seem that gatsby hasn't loaded the markdown at the point onRenderBody adds the script so this is proving problematic. From reading the other available API docs doesn't seem to be anything that would cover this situation unless you've got any ideas? :)

@KyleAMathews
Copy link
Contributor

This is for server rendering. Check out some of the other components that use this?

Another option is to use https://www.gatsbyjs.org/docs/browser-apis/#onRouteUpdate

@jamesadarich
Copy link
Contributor Author

Newest update moves script to gatsby-browser.js as expected. Behaviour still remains the same except for internet explorer which seems to fail as the javascript isn't compiled to es5 in the bundle. Need to investigate this one a bit more though.

@KyleAMathews
Copy link
Contributor

Oh nice! Yeah, you need to change the package's babelrc to be like this so the browser code is transpiled https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-image/.babelrc

@jamesadarich
Copy link
Contributor Author

Spot on 👍 all up to date now ready for another review round :)

@jamesadarich jamesadarich changed the title [WIP] Make gatsby-remark-images blur up Make gatsby-remark-images blur up Sep 4, 2018
@jamesadarich
Copy link
Contributor Author

@KyleAMathews I've removed the [WIP] tag as I think we've gotten to a good point now.

Final improvements:

  • if image loads form cache the effect does not show as we already have the image ready for the user
  • if for whatever reason the script fails there is some defensive code in there to only set the opacity of unloaded images to 0 after we know we can implement the effect

I've updated the snapshot in line with the changes so we should be ready to go barring any feedback you guys have :) let me know if you want any tweaks.

As a side note I found when using a for of loop, babel didn't seem to be transpiling this to valid es5 (it uses Symbol which is es2015) is this an issue that needs to be picked up separately?

@jamesadarich jamesadarich changed the title Make gatsby-remark-images blur up [gatsby-remark-images] Make images blur up Sep 4, 2018
left: 0;
transition: opacity 0.5s;
transition-delay: 0.5s;
box-shadow: inset 0px 0px 0px 400px ${
Copy link
Contributor

Choose a reason for hiding this comment

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

Was making this verbose intentional? This inflates outputted html with extra bytes. Perhaps we can keep it in readable form but actually output compressed code?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure, my assumption was that this was minified down so shouldn't make a difference but much easier to understand what's going on.

>${imageTag}</span>
<img
class="${imageBackgroundClass}"
style="width: 100%; height: 100%; position: relative; bottom: 0; left: 0; transition-delay: 0.5s; tranistion: opacity 0.5s; opacity: 1; background-size: cover; display: block;"
Copy link
Contributor

Choose a reason for hiding this comment

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

typo in transition property

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm also not sure if it's good idea changing span to img here - there might be a11y implications if screenreader see 2 image tags instead of one for essentially same image?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hmmm... not sure to be honest I'll take your guidance on this one. Looking at gatsby-image it seems that the actual image is wrapped in a Tag that's passed in as a prop. So would we put this back into the span and keep the background as is? As this would be similar to what's going on there.

Copy link
Contributor

Choose a reason for hiding this comment

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

I remember there were some discussions previously about and some potential issues with having second as placeholder - I don't remember what the resolution of the issue was at this moment. Is there any reason to actually change from current span to img?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

From memory it was while I was working through a good way to implement it so went through several variations so I think this is probably just a side effect. I'll add it back in so essentially the below?

<img class="${imageBackgroundClass}" ... />
<span>${imageTag}</span>

Copy link
Contributor

Choose a reason for hiding this comment

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

so previously it was

<span class="gatsby-resp-image-wrapper">
  <span class="gatsby-resp-image-background-image">
    <img>
  </span>
</span>

which won't work if we won't to hide placeholder that previously was in .gatsby-resp-image-background-image (as it would hide img too) maybe this:

<span class="gatsby-resp-image-wrapper">
  <span class="gatsby-resp-image-background-image"></span>
  <img>
</span>

to change as little as possible (limit potential regressions) in this PR?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'll have a play around to see what works 👍 thanks for comments, appreciate it :)

exports.onRouteUpdate = () => {
const imageWrappers = document.querySelectorAll(`.${imageWrapperClass}`)

Array.prototype.forEach.call(imageWrappers, (imageWrapper) => {
Copy link
Contributor

Choose a reason for hiding this comment

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

I think it would be much more readable if you would use:

const imageWrappers = Array.from(document.querySelectorAll(`.${imageWrapperClass}`))

imageWrappers.forEach(imageWrapper => {

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I remember why I didn't do this. There is no polyfill currently loaded and felt probably wasn't worthwhile in this case since readability was similar. Do you think it's worth adding a polyfill or keep as is @pieh?

@KyleAMathews
Copy link
Contributor

Yeah, IntersectionObserver is great as it's a cheap way to implement lazy loading — so definitely great but can come in a follow-up PR

@jamesadarich
Copy link
Contributor Author

Hey @pieh, I've addressed all feedback apart from 2 points.

  1. move the background to a span - the reason this needs to be an image is so that it takes up the correct space as the placeholder to avoid jumping during the page load. This is how gatsby-image achieves it so I would say this is probably OK

  2. refactor to use Array.from - I haven't done this as the readability seems similar but probably not worth a polyfill for this one case as it's not used anywhere else in gatsby on the browser.

Let me know if there's anything else I can do or you have any questions :)

@pieh
Copy link
Contributor

pieh commented Nov 16, 2018

  1. move the background to a span - the reason this needs to be an image is so that it takes up the correct space as the placeholder to avoid jumping during the page load.

But this was already working with paddingBottom which was ensuring proper aspect ratio.

This is how gatsby-image achieves it so I would say this is probably OK

That is not correct - placeholder image in gatsby-image has position: absolute - for fluid it is achieved with extra element that has paddingBottom which ensure proper aspect/ratio (and this is how it was done here as well)

Main issue here is that you are applying unneeded changes that don't fix anything and potentially cause some problems :(

2. refactor to use Array.from - I haven't done this as the readability seems similar but probably not worth a polyfill for this one case as it's not used anywhere else in gatsby on the browser.

You are right, I should have check to see if it's safe to use. Might be worth commenting there that we are not using something easier to use because we would need to polyfill it?

@jamesadarich
Copy link
Contributor Author

@pieh
1.
yep, true I missed that one sorry. Just so long since I originally did that I forgot I'll sort that :)

a) any guidance on where this should be done?
b) is this going to block the PR or should be something raised as an issue to resolve separately?

@pieh
Copy link
Contributor

pieh commented Nov 16, 2018

a) any guidance on where this should be done?
b) is this going to block the PR or should be something raised as an issue to resolve separately?

I mean this could be just code comment right above you using it - it would be great if this would something like article we could link to (i.e. https://css-tricks.com/snippets/javascript/loop-queryselectorall-matches/ ). Which btw it seems like using classic for loop might be best comprise between readable and supported without polyfill

@jamesadarich
Copy link
Contributor Author

true, I'll refactor to for of

@jamesadarich
Copy link
Contributor Author

Think we're there @pieh :) not a for of but a for because internet explorer. Let me know if we need anything else but think we should be good 👍

@pieh pieh changed the title [gatsby-remark-images] Make images blur up feat(gatsby-remark-images): make images blur up Nov 21, 2018
Copy link
Contributor

@pieh pieh left a comment

Choose a reason for hiding this comment

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

Thanks @jamesadarich!

@pieh pieh merged commit 5a5254e into gatsbyjs:master Nov 21, 2018
@gatsbot
Copy link

gatsbot bot commented Nov 21, 2018

Holy buckets, @jamesadarich — we just merged your PR to Gatsby! 💪💜

Gatsby is built by awesome people like you. Let us say “thanks” in two ways:

  1. We’d like to send you some Gatsby swag. As a token of our appreciation, you can go to the Gatsby Swag Store and log in with your GitHub account to get a coupon code good for one free piece of swag. (Currently we’ve got a couple t-shirts available, plus some socks that are really razzing our berries right now.)
  2. We just invited you to join the Gatsby organization on GitHub. This will add you to our team of maintainers. Accept the invite by visiting https://github.com/orgs/gatsbyjs/invitation. By joining the team, you’ll be able to label issues, review pull requests, and merge approved pull requests.

If there’s anything we can do to help, please don’t hesitate to reach out to us: tweet at @gatsbyjs and we’ll come a-runnin’.

Thanks again!

@pieh
Copy link
Contributor

pieh commented Nov 21, 2018

published gatsby-remark-images@3.0.0

@t2ca
Copy link
Contributor

t2ca commented Nov 21, 2018

Would be great if someone could make gatsby-remark-images-contentful compatible with this update.

Thanks!

@oorestisime
Copy link
Contributor

thank you all for finalizing this. @jamesadarich do you intend on having a look at lazy loading for this? i am happy to give this a go IF you don't intend to / not have time.

i don't use contentful so i won't touch that part sorry :/

@KyleAMathews
Copy link
Contributor

This is awesome! Great work @jamesadarich!

@jamesadarich
Copy link
Contributor Author

@KyleAMathews thanks, loving Gatsby glad I could give something back :)

@pieh thanks for your patience and assistance with this one 👍

@t2ca I've just had a brief look at this package and has a lot of stuff in common so probably worth sharing some of the functionality for sure. Maybe we could talk about how to do that if it's something you're keen on doing? Feel free to contact me directly :) Like with @oorestisime it's not something I use but it'd be cool to refactor the code to have more shared stuff so it's interesting but I think lazy loading for me is higher priority

@oorestisime I definitely did want to have a peek at this but maybe it's something we can collaborate on if that works for you? :)

@oorestisime
Copy link
Contributor

nah go ahead! my intention was just to make sure this gets done. it is not urgent, for me, so go for it. (i can have a look/test it once you have something :) )

gpetrioli pushed a commit to gpetrioli/gatsby that referenced this pull request Jan 22, 2019
BREAKING CHANGE: html markup has been changed, high resolution image (img.gatsby-resp-image-image) is no longer nested inside span with low resolution placeholder  (span.gatsby-resp-image-wrapper) - it's sibling of that span now. This might affect any custom styling that is applied to inline images
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.

5 participants