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

It's possible to preload images as in gatsby-image? #119

Closed
itesainnovation opened this issue Jun 30, 2020 · 4 comments
Closed

It's possible to preload images as in gatsby-image? #119

itesainnovation opened this issue Jun 30, 2020 · 4 comments

Comments

@itesainnovation
Copy link

Hi there! Is possible to preload images as seen in gatsby-image with the loading prop? Thanks!

@timhagn
Copy link
Owner

timhagn commented Jun 30, 2020

Hi @itesainnovation,

as CSS background images sadly don't have all the nice feats that img, picture & source elements have, there isn't a specific "loading" prop in gbi. Gonna try creating an example how to do this without them, as I needed preload functionality in a site before (or have a look at the files in the lib folder beforehand, especially the imageRef handling ones : ).

Best,

Tim.

@itesainnovation
Copy link
Author

Hi @timhagn! Thanks a lot for your quick answer. An example on how to implement this would be great 😃😃! We'll also check that!

Thanks!

@timhagn
Copy link
Owner

timhagn commented Jul 4, 2020

Hi @itesainnovation,

while I quickly threw together an example for you, I completely forgot that you don't have to dig into gbis internals any more since a few versions back to preload images % ). Earlier in the days you would have had to use something like the following (in the context of the example thereafter):

  /**
   * Preloads an image with gbi internals.
   *
   * @param fluidImage {object} The image to be preloaded, defaulting to the
   *                            Gatsby-astronaut`, as usually onLoad() has
   *                            no params.
   */
  // const preload = (fluidImage = astronaut) => {
  //   // Creates an image reference to be activated on critical.
  //   // we have to stub the second parameter `onLoad()` as we don't need it here
  //   // as we already set `critical`,  which directly load the image.
  //   createPictureRef(
  //     {
  //       fluid: fluidImage.childImageSharp.fluid,
  //       critical: true,
  //     },
  //     () => {}
  //   );
  // };

  /**
   * Let's kick off preloading the first image (Gatsby-icon) on mount.
   */
  useEffect(() => {
    // preload(icon);
  }, []);

and use it with the prop onLoad for the second image.
Meanwhile, you only have to use the props fadeIn={false} & critical to get the same result. And here it is, hope it helps:

import React from 'react'
import { graphql, useStaticQuery } from 'gatsby';
import styled from 'styled-components';

import BackgroundImage from 'gatsby-background-image';

/**
 * A preload Example Page, just throw it into `gbitest`s `pages` folder.
 *
 * @return {*}
 * @constructor
 */
const PreloadBackground = () => {
  const { astronaut, icon } = useStaticQuery(
    graphql`
      query {
        astronaut: file(relativePath: { eq: "gatsby-astronaut.png" }) {
          childImageSharp {
            fluid(quality: 100, maxWidth: 800) {
              ...GatsbyImageSharpFluid_withWebp_tracedSVG
            }
          }
        }
        icon: file(relativePath: { eq: "gatsby-icon.png" }) {
          childImageSharp {
            fluid(quality: 100, maxWidth: 512) {
              ...GatsbyImageSharpFluid_withWebp_noBase64
            }
          }
        }
      }
    `
  );

  return (
    <>
      <StyledStretchWrapper>
        <h1>Hi there</h1>
        <p>
          Welcome to the <code>gatsby-background-image</code> preload demo site.
        </p>
        <p>
          Scroll down to see the first preloaded{' '}
          <code>gatsby-background-image</code>
        </p>
        <p>Scroll further and the second preloaded one will surface.</p>
        <p>Or directly open the Network tab to see that the images have been loaded.</p>
        <p>Have phun : )!</p>
      </StyledStretchWrapper>
      <StyledStretchWrapper>
        <StyledBackgroundImage
          fluid={icon.childImageSharp.fluid}
          // The next two are important to prevent "blur-up".
          fadeIn={false}
          critical
          width={512}
          height={512}
        />
      </StyledStretchWrapper>
      <StyledStretchWrapper>
        <StyledBackgroundImage
          fluid={astronaut.childImageSharp.fluid}
          // Again preventing blurring up.
          fadeIn={false}
          critical
          width={800}
          height={800}
        />
      </StyledStretchWrapper>
    </>
  );
};

/**
 * Yup, I was lazy ; ).
 */
const StyledStretchWrapper = styled.div`
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  width: 100%;
  height: 100vh;
`;

/**
 * OK, you could have used a normal <Image /> as well instead of fixating the
 * width / height, but we wanted to demo it ^^.
 */
const StyledBackgroundImage = styled(BackgroundImage)`
  min-width: ${props => props.width}px;
  min-height: ${props => props.height}px;
`;

export default PreloadBackground;

Feel free to close your issue, should this asnwer your initial question : ).

Best,

Tim.

@itesainnovation
Copy link
Author

Thanks a lot! That is really helpful!!!!

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

No branches or pull requests

2 participants