简体   繁体   中英

Gatsby - Prevent small images from being inlined as a data URI

I'm attempting to provide images for each of the apple-touch-icon sizes in my head tag. I'm doing this like so:

// not shown: import all image files: logo57, logo76, etc
<link rel="apple-touch-icon" sizes="57x57" href={logo57} />
<link rel="apple-touch-icon" sizes="76x76" href={logo76} />
<link rel="apple-touch-icon" sizes="120x120" href={logo120} />
<link rel="apple-touch-icon" sizes="152x152" href={logo152} />
<link rel="apple-touch-icon" sizes="167x167" href={logo167} />
<link rel="apple-touch-icon" sizes="180x180" href={logo180} />

The problem is that when the page is rendered, all of these images are included directly in the page as base 64 in data URIs, not relative urls. Like so:

<link rel="apple-touch-icon" sizes="180x180" href="data:image/png;base64,iVBORw0KGgoAAAA....">

This is problematic for a few reasons. For one, these images are only needed in the progressive web app scenario; they are not needed by normal desktop browsers and yet desktop browsers are forced to download all of these chunks of base 64, slowing down the page load. Secondly, even in the PWA scenario, each device will only need one of these images, not all of them, so page load time is slowed there as well.

This is a documented optimization for images <10,000 bytes, so it may be a negligible difference that they are all loaded here. But, the total size of the original pngs totals about 27kb (I don't know about after converting to base 64), and it seems like I'd rather not include this data in every page if it is not needed.

I've found that I can move the images all to the /static folder and reference them with href="logo57.png" , but then I lose the compile time verification that these images are in fact present at the given href, as well as the including of the image hash in the file name (for caching reasons).

How can I tell Gatsby to not inline these images directly into the page as data URI's?

Rather than using Webpack for these assets ( import x from "..." ) you should place them in your static folder and reference them directly. If your Gatsby site doesn't have a prefix (ie an index.js file is served from / ) then you can hardcode the paths (eg href="/favicon.png" ). Otherwise you'll want to use withPrefix to provide the prefix in production.

You could also use GraphQL for this. If for example you have the logo in a folder called images your code would be something like this:

const data = useStaticQuery(graphql`
  query Logo {
    file(absolutePath: { regex: "/images/logo.png/" }) {
      publicURL
    }
  }
`)

return <link rel="apple-touch-icon" sizes="57x57" href={data.file.publicURL} />

Please note, you'd need to use gatsby-source-filesystem for your images to be available in GraphQL. It's already used by Gatsby internally so no need to install it. Simply add it to your gatsby-config.js :

module.exports = {
  plugins: [
    { resolve: `gatsby-source-filesystem`, options: { path: `${__dirname}/src/images` } },
    // other plugins here...
  ],
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM