gatsby: Gatsby is not deferring offscreen images, as advertised
Description
One of the stated benefits of using gatsby-image is meant to be automatic lazy loading of images. However, despite using gatsby-image in all the images on our homescreen (both above and below the fold), Google Chrome’s Audit tool is revealing that in fact none of these images are being lazy loaded and are all instead loading, as soon as the user hits the page.
Steps to reproduce
We are using gatsby-image like so:
<GatsbyImage
{...gatsbyImage}
imgStyle={imgStyle}
style={style}
loading="lazy"
/>
where we are querying the image like so:
ollyImage: file(relativePath: { eq: "marketing/olly.png" }) {
childImageSharp {
fixed(width: 310) {
...GatsbyImageSharpFixed
}
}
}
And passing the resulting props in through ...gatsbyImage.
Expected result
Gatsby-image should not load these images when the user initially hits the page.
Actual result
All images using gatsby-image are being fetched on page load, instead of only when they are in view.
Environment
System:
OS: macOS 10.14.4
CPU: (4) x64 Intel(R) Core(TM) i5-7360U CPU @ 2.30GHz
Shell: 5.3 - /bin/zsh
Binaries:
Node: 12.4.0 - /usr/local/bin/node
Yarn: 1.16.0 - /usr/local/bin/yarn
npm: 6.9.0 - /usr/local/bin/npm
Languages:
Python: 2.7.10 - /usr/bin/python
Browsers:
Chrome: 79.0.3945.117
Firefox: 68.0.2
Safari: 12.1
npmPackages:
gatsby: ^2.18.15 => 2.18.15
gatsby-image: ^2.2.8 => 2.2.8
gatsby-paginate: ^1.1.1 => 1.1.1
gatsby-plugin-create-client-paths: ^2.1.3 => 2.1.3
gatsby-plugin-google-tagmanager: ^2.1.12 => 2.1.12
gatsby-plugin-offline: 2.2.9 => 2.2.9
gatsby-plugin-portal: ^1.0.7 => 1.0.7
gatsby-plugin-react-helmet: ^3.1.15 => 3.1.15
gatsby-plugin-react-svg: ^2.1.2 => 2.1.2
gatsby-plugin-s3: ^0.3.2 => 0.3.2
gatsby-plugin-sass: ^2.1.4 => 2.1.4
gatsby-plugin-sentry: ^1.0.1 => 1.0.1
gatsby-plugin-sharp: ^2.3.13 => 2.3.13
gatsby-plugin-styled-components: ^3.1.2 => 3.1.2
gatsby-plugin-typescript: ^2.1.2 => 2.1.2
gatsby-source-filesystem: ^2.1.9 => 2.1.9
gatsby-transformer-sharp: ^2.3.12 => 2.3.12
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Reactions: 11
- Comments: 26 (10 by maintainers)
I was digging more into it and could reproduce. The reason why this happens is because chrome’s built-in lazy loading have much higher viewport distance thresholds than what
gatsby-imageis doing when native lazy loading is not enabled.The threshold in chrome will depend on your connection type - you can check actual values in https://cs.chromium.org/chromium/src/third_party/blink/renderer/core/frame/settings.json5?l=971-1003&rcl=e8f3cf0bbe085fee0d1b468e84395aad3ebb2cad
Per https://web.dev/native-lazy-loading/
General take away - on fastest connection threshold is at least 3000 pixels - and it can increase up to 8000 pixels (for comparison gatsby-image has hardcoded 200px when native lazy loading is not available).
Now i’m not sure if we should allow some way to disable support for native lazy loading or not, but at least there is explanation why this happens
I’ll be checking this issue out and see why lighthouse audits fail. I’ll keep y’all posted!
This might be chrome being more aggressive on their native lazy loading, there is not much we can do unless we revert it. I’ll see if I can ask someone from the chrome team to help us understand it.
A link to your site might help me explain what’s going on
I’m also seeing the same problem (Chrome) images failed to load when they appear in the viewport.
we are using “gatsby”: “^2.18.7”, “gatsby-image”: “^2.4.3”, “gatsby-plugin-disqus”: “^1.2.0”, “gatsby-plugin-google-analytics”: “^2.3.5”, “gatsby-plugin-load-script”: “^1.1.0”, “gatsby-plugin-postcss”: “^2.1.16”, “gatsby-plugin-preload-fonts”: “^1.2.10”, “gatsby-plugin-react-helmet”: “^3.1.16”, “gatsby-plugin-remote-images”: “^2.1.0”, “gatsby-plugin-sass”: “^2.3.1”, “gatsby-plugin-sharp”: “^2.6.3”, “gatsby-plugin-typescript”: “^2.4.2”, “gatsby-source-filesystem”: “^2.3.7”, “gatsby-source-sanity”: “^5.0.4”, “gatsby-transformer-sharp”: “^2.5.2”,
@SandyWyper. My take is that image fetching is render blocking which affects time to interactive (TTI) as the browser gets “busy fetching” bellow the fold images. Lighthouse’ performance score weights are super sensitive to TTI (which is going to change on lighthouse v6) and become less important to the overall score. 🤷♂️
@wardpeet look forward to hearing about your findings. keep us posted 👍
Adding <img loading=“lazy” … /> solved the issue for me!!
We have noticed the same issue, which you can clearly see by inspecting the network tab for images at the following URL with the window resized narrow enough to ensure lower images aren’t loaded straight away: https://co-operate.coop.co.uk/choose-area/. All images are loaded straight away in Chrome, but are lazy-loaded in Firefox.
Incidentally, we’re not seeing the issue on this other page: https://co-operate.coop.co.uk/team-notes/week-notes-13-march-2020/ – @pieh, your comment is on point but doesn’t seem to explain that 😕
Something to do with the intersection observer, possibly? The images in the first example are all inside a flex layout, whereas the ones in the second are not. I’ll report back if I find anything else.