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

Can't get consistent Gatsby Img behavior #6532

Closed
d-ivashchuk opened this issue Jul 18, 2018 · 10 comments
Closed

Can't get consistent Gatsby Img behavior #6532

d-ivashchuk opened this issue Jul 18, 2018 · 10 comments
Labels
type: question or discussion Issue discussing or asking a question about Gatsby

Comments

@d-ivashchuk
Copy link
Contributor

Description

I've finally managed to get Gatsby images work as expected on desktop devices, to find out that they are totally not working on mobile safari/firefox/chrome on ios devices. Moreover, I can't get consistent behavior of images when deploying my project on gh-pages. One deploy everything works, other one, with no changes at all, images just get stuck on blur phase. I found a temporary fix of deleting cache folder in my project, but I don't think that it's the best way of solving this.

Steps to reproduce

Plugins that I use

{
   resolve: `gatsby-source-filesystem`,
   options: {
     path: `${__dirname}/src/posts`,
     name: 'posts',
   },
 },
 {
   resolve: `gatsby-source-filesystem`,
   options: {
     name: `images`,
     path: `${__dirname}/src/assets/images`,
   },
 },
 {
   resolve: `gatsby-source-filesystem`,
   options: {
     name: `photos`,
     path: `${__dirname}/src/assets/photos`,
   },
 },
 {
   resolve: `gatsby-source-filesystem`,
   options: {
     name: `headers`,
     path: `${__dirname}/src/assets/headers`,
   },
 },

 {
   resolve: `gatsby-transformer-remark`,
   options: {
     plugins: [
       {
         resolve: `gatsby-remark-images`,
         options: {
           maxWidth: 630,
         },
       },
       'gatsby-remark-copy-linked-files',
     ],
   },
 },
 `gatsby-transformer-sharp`,
 `gatsby-plugin-sharp`,
 `gatsby-plugin-react-helmet`,
 `gatsby-plugin-sass`,
],

Queries (note: they are placed in separate pages):

export const query = graphql`
  query HeaderQuery {
    headerImage: imageSharp(id: { regex: "/headers/" }) {
      sizes(maxWidth: 2000) {
        ...GatsbyImageSharpSizes_tracedSVG
      }
    }
  }
`
export const query = graphql`
  query PhotosQuery {
    allFile(
      filter: {
        extension: { regex: "/(jpeg|jpg|gif|png)/" }
        sourceInstanceName: { eq: "photos" }
      }
    ) {
      edges {
        node {
          childImageSharp {
            sizes(maxWidth: 2000) {
              ...GatsbyImageSharpSizes
            }
          }
        }
      }
    }
  }
`

Images:

<div className="g-container">
      {data.allFile.edges.map(entry => (
        <Img
          className="photo"
          title="grid image"
          alt="test"
          sizes={entry.node.childImageSharp.sizes}
        />
      ))}
    </div>

<Img
      className="header-legal"
      title="Header image"
      alt="test"
      sizes={data.headerImage.sizes}
    />
`

Expected result

1)I expect everything to work on every npm run develop or npm run deploy but from time to time they are not working in both development mode and build mode.
2)I expect images to have lazy load on mobile devices, but it seems like they don't even have blur, when page loads and behave like normal <img>

Actual result

You can see demo of not working mobile images here:

https://d-ivashchuk.github.io/taurus-gatsby/photos

Or here:

https://d-ivashchuk.github.io/taurus-gatsby/legal

Environment

  System:
    OS: macOS Sierra 10.12.6
    CPU: x64 Intel(R) Core(TM) i7-6820HQ CPU @ 2.70GHz
    Shell: 3.2.57 - /bin/bash
  Binaries:
    Node: 6.10.1 - /usr/local/bin/node
    npm: 6.1.0 - /usr/local/bin/npm
  Browsers:
    Chrome: 67.0.3396.99
    Firefox: 56.0.2
    Safari: 11.1.2
  npmPackages:
    gatsby: ^1.9.243 => 1.9.273 
    gatsby-image: ^1.0.54 => 1.0.54 
    gatsby-link: ^1.6.40 => 1.6.45 
    gatsby-plugin-google-analytics: ^1.0.24 => 1.0.31 
    gatsby-plugin-react-helmet: ^1.0.8 => 1.0.8 
    gatsby-plugin-sass: ^1.0.25 => 1.0.26 
    gatsby-plugin-sharp: ^1.6.48 => 1.6.48 
    gatsby-remark-copy-linked-files: ^1.5.30 => 1.5.37 
    gatsby-remark-images: ^1.5.60 => 1.5.67 
    gatsby-source-filesystem: ^1.5.27 => 1.5.39 
    gatsby-transformer-remark: ^1.7.39 => 1.7.44 
    gatsby-transformer-sharp: ^1.6.27 => 1.6.27 
  npmGlobalPackages:
    gatsby-cli: 1.1.58

Apart from this issue I want to thank you guys for creating Gatsby and helping people like me to become proficient with it. Great Job!

@m-allanson
Copy link
Contributor

Hmm can you replicate the same behaviour with the using-gatsby-image example site? Source is here https://github.com/gatsbyjs/gatsby/tree/master/examples/using-gatsby-image

@m-allanson m-allanson added the type: question or discussion Issue discussing or asking a question about Gatsby label Jul 19, 2018
@d-ivashchuk
Copy link
Contributor Author

I am trying to reproduce it, but everyting works fine on iphone(images get blurred and appear as expected).
I've tried to isolate everything, created new project using gatsby-starter-photon and created one page solely with an image there. One query, one image, same behavior as in my project where I get a mistake, image loads as if it is normal one, no blur at all on iphone, but everything works fine on desktop.
It is nothing special really, I've just follwed tutorial but for some reason it does not work on mobile devices.
I thought maybe it can conflict with gatsby-starter-photon in terms of styles or js and produce such behavior?

@d-ivashchuk
Copy link
Contributor Author

This is the closest I could get to reproducing this issue in more or less isolated environment.

https://d-ivashchuk.github.io/test/

I've used gatsby-starter-default and added gatsby-image to it. When deployed to gh-pages, lazy-loading works on desktop devices, but fails to work on mobile ios(at least, can't test on android at the moment)

Thanks for patience and help!

@KyleAMathews
Copy link
Contributor

Ah yeah — lazy loading doesn't work on IOS due to it not supporting IntersectionObserver. Closing this in favor of #4021 as we need to document this.

@PolGuixe
Copy link
Contributor

PolGuixe commented Jul 11, 2019

@KyleAMathews currently the newest version of iOS Safari supports IntersectionObserver. However, I am still getting weird behaviour and on Safari is loading extremely huge images on mobile.

I believe is due to Safari not support WebP. As per @coreyward comments here: #4926 Could it be? What should be the workaround?

@coreyward
Copy link
Contributor

@PolGuixe Are you using source images that are in WebP or setting the format argument to webp?

The srcSet field returned by Gatsby Image will include only the original format of the image unless you specify the format argument. If you use a fragment that specifies _withWebp, like GatsbyImageSharpFixed_withWebp, it will include the srcSetWebp field which will be included in the srcset attribute that is rendered as part of the Gatsby Image component, but with the original srcSet data as a fallback.

Which is all to say that you can safely include WebP images in a srcset served to Safari provided you do not only have WebP images in that srcset, and with Gatsby Image, the only way to mess that up is to either have your original images in WebP (exceedingly unlikely) or to set the format argument to webp.

If neither of these are the case and you are using a recent version of Gatsby Image (e.g. 2.2.x+) you may want to open a new, fully detailed issue.

@PolGuixe
Copy link
Contributor

@coreyward

Gatsby-Image: v2.2.4

// usage example
// ...
<Image
  {...query.prismicRestaurant?.data?.body_image?.localFile
   ?.childImageSharp}
  className={classes.image}
/>
//...

// query example
// ...
  body_image {
          localFile {
            id
            childImageSharp {
              fluid(maxWidth: 1200, quality: 100) {
                ...GatsbyImageSharpFluid_withWebp
              }
            }
          }
        }
//...

HTML code generated
Screenshot 2019-07-11 at 18 04 40

I don't see the srcSetWebp

Network:
In this case I scrolled down as soon as page loaded.
Screenshot 2019-07-11 at 18 03 00

In this case I waited for the first images to load and then scrolled and the other images started downloading afterwards,
Screenshot 2019-07-11 at 18 09 38
but many of them...

Should I open different bugs?

@coreyward
Copy link
Contributor

Since you're using fluid with a maxWidth: 1200, the sizes attribute tells the browser that the image will be shown at 100vw on viewports narrower than 1200px. Since your mobile device is likely rendering at a higher DPI, the browser will select an image that suits accordingly. For example, on a 375px wide display with a device pixel ratio of 2, the browser would expect to render the image at 750px wide. The closest match that won't result in a lower quality display is the 1200px wide image, so that's what would most likely be selected by the browser.

That 1200px wide image would probably be a smaller file size, but you've set the quality to 100%, which will result in minimal compression and large file sizes.

As for additional images loading, you have caching disabled, which is not an expected condition for normal users; if you re-enable caching you'll likely see that those images are not re-requested from the server but instead served from cache.

srcSetWebp is a field that the GatsbyImageSharpFluid_withWebp Gatsby Image fragment specifies. You don't need to know about it as a user, just providing details so you're aware of what's going on

@PolGuixe
Copy link
Contributor

PolGuixe commented Jul 12, 2019

@coreyward I am using quality 100% to accentuate the effect of these big pictures. 😅 Won't go like this into production.

I've checked the size of the image downloaded and instead of 1200px, the image is 1800px which is the next resolution step. The device I am using for testing is an iPhone 8 Plus. Edit: pixel ratio on this device is about 3, screen width 414px --> 414*3= 1242 > 1200 hence it jumps to the next resolution step.

Just to confirm best practices:

  1. Is it fine to use Webp format fragments even if the site is targeted to Safari because a fallback is generated and this will be used.

  2. In a fluid fragment, the maxWidth should be the maximum container width in the biggest screen size that needs to be supported.

  3. Quality set to 100% is not recommended to get fast-loading sites... 😅

I'll keep doing a test to see if I can get a good consistency.

@coreyward
Copy link
Contributor

Is it fine to use Webp format fragments even if the site is targeted to Safari because a fallback is generated and this will be used.

If you know that this is exclusively going to be used by iOS you could just leave off the _withWebp part of the fragment, but if you leave it there there's no real harm (a few extra bytes of data in the srcset).

In a fluid fragment, the maxWidth should be the maximum container width in the biggest screen size that needs to be supported.

If by this you mean that the maxWidth should be the largest that this image is displayed (i.e., its maximum contained size), then yes. If you're doing something where it's only displayed at, say, 50% of the viewport width (50vw) you can actually override the sizes attribute to provide a more accurate recipe for the browser, but the default is fairly safe.

Quality set to 100% is not recommended to get fast-loading sites... 😅

😉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: question or discussion Issue discussing or asking a question about Gatsby
Projects
None yet
Development

No branches or pull requests

5 participants