如何使用 GraphQL 和 Gatsby Image API 处理图像

作者选择/dev/color接受捐赠,作为Write for DOnations计划的一部分。

介绍

处理图像在构建网站中起着举足轻重的作用,但处理起来也具有挑战性。未优化的图像会降低网站的速度,而且许多在桌面上看起来很合适的图像很难缩小到移动设备上。视觉处理图像也可能很乏味且难以维护。

所有这些孤立的问题都不是什么大问题。主要问题是当您必须跟踪所有这些规则和图像缩放技术时。谈到Gatsby.js 项目,这就是Gatsby Image API派上用场的地方。通过使用GraphQL查询,您可以使用 Gatsby Image API 来处理图像压缩、使图像具有响应性,甚至处理基本的图像样式。

在本教程中,您将使用 Gatsby Image API 和 GraphQL 查询来压缩、转换和样式化图像。

先决条件

第 1 步 — 建立一个新的 Gatsby 项目

在第一步中,您将设置一个新的 Gatsby 项目并熟悉将在本教程中使用的关键图像插件。您还将下载并设置图像以在整个教程中进行优化。

首先,使用 CLI 工具启动一个名为 的新项目gatsby-image-project

  • gatsby new gatsby-image-project https://github.com/gatsbyjs/gatsby-starter-default

gatsby-starter-default将从 GatsbyGitHub 存储库中的入门模板创建一个新网站

创建项目后,进入新的项目目录:

  • cd gatsby-image-project

接下来,index.js在您选择的文本编辑器中打开文件:

  • nano src/pages/index.js

删除layout包装器组件之间的所有代码,使您的文件与以下内容相同:

gatsby-image-project/src/pages/index.js
import React from "react"
import { Link } from "gatsby"

import Layout from "../components/layout"
import Image from "../components/image"
import SEO from "../components/seo"

const IndexPage = () => (
  <Layout>
  </Layout>
)

export default IndexPage

接下来,使用以下突出显示的JSX替换已删除的代码,这会向网站添加一些 HTML 元素:

gatsby-image-project/src/pages/index.js
import React from "react"
import { Link } from "gatsby"

import Layout from "../components/layout"
import Image from "../components/image"
import SEO from "../components/seo"

const IndexPage = () => (
    <Layout>
      <div className="layout">
        <Image className="left-image"/>
        <h2>Hello</h2>
        <p>Welcome to my humble site</p>
        <p>All of our shirts are on sale!</p>
        <button className="shop-button">Shop</button>
      </div>
    </Layout>
)

export default IndexPage

Gatsby Image API 将Image在后面的步骤中元素提供新的测试图像有了这个,您现在可以尝试使用 HTML。

在本教程的后面,您将重新访问该index.js页面。现在,保存并退出文件。

要打开的下一个文件是gatsby-config.js. 在此文件中,您将找到负责处理图像的插件。

使用以下命令打开文件:

  • nano gatsby-config.js

一旦你已经打开了gatsby-config文件,找到gatsby-plugin-sharpgatsby-transformer-sharpgatsby-source-filesystem插件:

gatsby-image-project/gatsby-config.js
module.exports = {
  siteMetadata: {
    title: `Gatsby Default Starter`,
    description: `Kick off your next, great Gatsby project with this default starter. This barebones starter ships with the main Gatsby configuration files you might need.`,
    author: `@gatsbyjs`,
  },
  plugins: [
    `gatsby-plugin-react-helmet`,
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `images`,
        path: `${__dirname}/src/images`,
      },
    },
    `gatsby-transformer-sharp`,
    `gatsby-plugin-sharp`,
    {
      resolve: `gatsby-plugin-manifest`,
      options: {
        name: `gatsby-starter-default`,
        short_name: `starter`,
        start_url: `/`,
        background_color: `#663399`,
        theme_color: `#663399`,
        display: `minimal-ui`,
        icon: `src/images/gatsby-icon.png`, // This path is relative to the root of the site.
      },
    },
    // this (optional) plugin enables Progressive Web App + Offline functionality
    // To learn more, visit: https://gatsby.dev/offline
    // `gatsby-plugin-offline`,
  ],
}

这些插件如下:

  • gatsby-plugin-sharp: Sharp是 Gatsby 用来处理图像的图像优化库。gatsby-plugin-sharp在夏普和盖茨比之间架起了一座桥梁。

  • gatsby-transformer-sharp:此插件执行图像转换,例如调整大小、压缩和更改背景颜色。

  • gatsby-source-filesystem:这个插件允许你从你的文件系统中获取数据到你的应用程序中。在这种情况下,它使 GraphQL 能够查询图像。

现在您已经了解了哪些插件用于处理图像,请关闭文件。

接下来,将图像添加到您的应用程序,以便稍后进行优化、编辑和设置样式。在本教程中,您将从Unsplash 库存图片网站下载图片在浏览器中导航到Unsplash 上的这张衣服图片,然后将angela-bailey-jlo7Bf4tUoY-unsplash.jpg图片下载/imagesGatsby 项目文件夹中。图像必须位于正确的目录中,以便使用 GraphQL 查询图像并使用 Gatsby 的图像 API 对其进行转换。

或者,您可以从命令行下载图像。首先,移动到images目录:

  • cd src/images

接下来,执行以下命令:

  • curl -sL https://images.unsplash.com/photo-1556905055-8f358a7a47b2 -o angela-bailey-jlo7Bf4tUoY-unsplash.jpg

这将用于curl下载图像并将文件输出为angela-bailey-jlo7Bf4tUoY-unsplash.jpg.

在本节中,您将设置 Gatsby 项目以使用 Gatsby 的 Image API。向您介绍了盖茨比的配置文件找到gatsby-plugin-sharpgatsby-transform-sharpgatsby-source-filesystem虽然协同工作,以优化图像。在下一步中,您将使用 GraphQL 集成开发环境 (IDE) 来测试查询和优化图像。

第 2 步 – 使用 GraphQL 查询图像

您现在将使用 GraphQL 查询您的新图像。GraphQL是一种用于从 API 获取信息的查询语言。它也是 Gatsby 的数据层。

首先,返回 Gatsby 项目的根目录,然后启动开发服务器:

  • gatsby develop

站点构建完成后,您将收到以下输出:

Output
... success open and validate gatsby-configs - 0.081s success load plugins - 4.537s success onPreInit - 0.070s success initialize cache - 0.034s success copy gatsby files - 0.320s success onPreBootstrap - 0.177s success createSchemaCustomization - 0.050s success Checking for changed pages - 0.003s success source and transform nodes - 0.264s success building schema - 0.599s info Total nodes: 35, SitePage nodes: 1 (use --verbose for breakdown) success createPages - 0.057s success Checking for changed pages - 0.005s success createPagesStatefully - 0.188s success update schema - 0.046s success write out redirect data - 0.006s success Build manifest and related icons - 0.456s success onPostBootstrap - 0.465s info bootstrap finished - 19.515s success onPreExtractQueries - 0.003s success extract queries from components - 0.932s success write out requires - 0.029s success run page queries - 0.039s - 1/1 25.97/s You can now view gatsby-starter-default in the browser. http://localhost:8000/ View GraphiQL, an in-browser IDE, to explore your site's data and schema http://localhost:8000/___graphql Note that the development build is not optimized. To create a production build, use gatsby build warn ESLintError: /your_filepath/gatsby-image-project/src/pages/index.js 2:10 warning 'Link' is defined but never used no-unused-vars 6:8 warning 'SEO' is defined but never used no-unused-vars ✖ 2 problems (0 errors, 2 warnings) success Building development bundle - 10.814s

此输出包含两个链接。第一个链接https://localhost:8000/是您可以找到本地开发站点的地方。第二个链接http://localhost:8000/___graphql是GraphiQL 的位置。GraphiQL 是一个集成开发编辑器 (IDE),允许您在浏览器中进行查询这是一个有用的工具,可帮助您在将数据添加到代码库之前进行试验和进行数据查询。GraphiQL 仅在您运行开发服务器时有效。

在 GraphiQL 的帮助下,您可以尝试查询以检索新下载的图像。打开浏览器并http://localhost:8000/___graphql在地址栏中输入 GraphiQL URL 浏览器会显示GraphiQL界面:

GraphQL IDE 的屏幕截图

GraphiQL 分为三个部分。最左侧是Explorer,您可以在其中找到可以通过 GraphQL 访问的字段。IDE 中间是沙箱,您可以在其中进行查询。最后,在最右边你可以找到 GraphQL 的文档。

您的第一个目标是查询angela-bailey-jlo7Bf4tUoY-unsplash.jpg图像。由于映像位于本地文件系统中,因此您可以资源管理器框中选择文件这将显示子目录的下拉菜单。您将通过相对路径搜索图像文件,因此选择relativePathrelativePath显示另一组子文件夹。您将输入图像的确切路径,因此选择“等于”eq在引号内输入图像的路径angela-bailey-jlo7Bf4tUoY-unsplash.jpg

GraphQL IDE 显示了在文件系统中定位图像的查询

现在您准备尝试您的第一个图像处理。您的原始图像是 1920 x 1280 像素。这对于您的着陆页来说太大了,这将有助于使图像具有响应性。通常,您必须将宽度硬编码到CSS 中并添加媒体查询以使图像具有响应性。Gatsby 的 Image API 会为您完成所有这些工作,而您无需编写额外的 CSS。

资源管理器框中选择childImageSharp,它会转换引擎盖下的图像。确保从顶级菜单中选择它,而不是从file下选择从下一个下拉列表中选择流体流体图像会拉伸以填充其容器。流体的下拉选项,选中maxWidth并输入750

紫色查询参数正下方的蓝色值是您可以返回的不同值。选择srcsrcSet返回原始图像和变换图像的位置。然后点击播放按钮查看结果:

childImageSharp 参数

选择参数后,GraphiQL 构建以下查询:

query MyQuery {
  file(relativePath: {eq: "angela-bailey-jlo7Bf4tUoY-unsplash.jpg"}) {
    childImageSharp {
      fluid(maxWidth: 750) {
        src
        srcSet
      }
    }
  }
}

在 GraphiQL 界面右侧的框中,您将找到返回值。这将显示:

  • src: 处理后图像的位置。

  • srcSet:相同的图像设置为不同的大小。如果您希望图像具有响应性,此功能会派上用场。

您不必fluid在查询中进行选择您还可以选择fix固定图像使用<picture>元素创建响应式图像1x、1.5x 和 2x 像素密度以下是固定查询的示例:

query MyQuery {
  file(relativePath: {eq: "angela-bailey-jlo7Bf4tUoY-unsplash.jpg"}) {
    childImageSharp {
      fixed(cropFocus: CENTER) {
        src
        srcSet
      }
    }
  }
}

此查询将返回以下内容:

{
  "data": {
    "file": {
      "childImageSharp": {
        "fixed": {
          "src": "/static/8e3a47b77ddf6636755d7be661d7b019/0ad16/angela-bailey-jlo7Bf4tUoY-unsplash.jpg",
          "srcSet": "/static/8e3a47b77ddf6636755d7be661d7b019/0ad16/angela-bailey-jlo7Bf4tUoY-unsplash.jpg 1x,\n/static/8e3a47b77ddf6636755d7be661d7b019/44157/angela-bailey-jlo7Bf4tUoY-unsplash.jpg 1.5x,\n/static/8e3a47b77ddf6636755d7be661d7b019/7fddd/angela-bailey-jlo7Bf4tUoY-unsplash.jpg 2x"
        }
      }
    }
  },
  "extensions": {}
}

在此查询中,您有一个固定版本的图像,裁剪焦点设置为中心。您的返回值是图像的位置和一组不同的图像大小(分别为 1x、1.5x、2x)。

现在您已经使用 GraphiQL 和childImageSharp节点测试了 GraphQL 查询,接下来您将把查询的图像添加到模板中,并使用 Gatsby 的图像 API 进一步优化它。

第 3 步 — 优化您的图像在 Web 上的性能

在本节中,您将把 GraphQL 图像传输到index.js项目页面并执行更多图像优化。

在 Gatsby 项目根目录下的终端中,在您喜欢的文本编辑器中打开图像组件:

  • nano src/components/image.js

现在,使用您在 GraphiQL 界面中尝试过的查询。删除"gatsby-astronaut.png"并替换为"angela-bailey-jlo7Bf4tUoY-unsplash.jpg". 也替换maxWidth: 300maxWidth: 750

gatsby-image-project/src/components/image.js
import React from "react"
import { useStaticQuery, graphql } from "gatsby"
import Img from "gatsby-image"

/*
 * This component is built using `gatsby-image` to automatically serve optimized
 * images with lazy loading and reduced file sizes. The image is loaded using a
 * `useStaticQuery`, which allows us to load the image from directly within this
 * component, rather than having to pass the image data down from pages.
 *
 * For more information, see the docs:
 * - `gatsby-image`: https://gatsby.dev/gatsby-image
 * - `useStaticQuery`: https://www.gatsbyjs.com/docs/use-static-query/
 */

const Image = () => {
  const data = useStaticQuery(graphql`
    query {
      placeholderImage: file(relativePath: { eq: "angela-bailey-jlo7Bf4tUoY-unsplash.jpg" }) {
        childImageSharp {
          fluid(maxWidth: 750) {
            ...GatsbyImageSharpFluid
          }
        }
      }
    }
  `)

  if (!data?.placeholderImage?.childImageSharp?.fluid) {
    return <div>Picture not found</div>
  }

  return <Img fluid={data.placeholderImage.childImageSharp.fluid} />
}

export default Image

...GatsbyImageSharpFluid是一个 GraphQL 片段。这个语法可以获取所有不同的返回值的childImageSharpfluid您将使用 this 作为返回值而不是srcand srcSet

`childImageSharp` 和 `fluid` 返回值的 GraphiQL 资源管理器列表

image.js文件中,在 GraphQL 查询之后有一个if语句

gatsby-image-project/src/components/image.js
...
  if (!data?.placeholderImage?.childImageSharp?.fluid) {
    return <div>Picture not found</div>
  }

  return <Img fluid={data.placeholderImage.childImageSharp.fluid} />
}

export default Image

placeholderimage是在查询中给出并在 中返回的别名<Img fluid={data.placeholderImage.childImageSharp.fluid} />在 GraphQL 中,您可以命名查询在条件语句中,如果您没有图片,那么Picture not found着陆页上会出现这些词

保存并关闭此文件。

构建 Gatsby 站点后,图像将由 Gatsby Image API 处理和优化。这将减小图像文件的大小以减少您网站的加载时间。要对此进行测试,请导航到该images目录以查找原始文件大小:

  • cd src/images

现在使用以下命令列出文件:

  • ls -sh

-sh标志将以人类可读的格式向您显示文件的内存大小。您将收到以下输出:

Output
total 5.0M 4.8M angela-bailey-jlo7Bf4tUoY-unsplash.jpg 164K gatsby-astronaut.png 24K gatsby-icon.png

没有任何优化,图像是4.8M. 现在,您将在使用 Gatsby 的 Image API 后查看图像有多大。

导航到项目的根目录并启动开发服务器:

  • gatsby develop

开发服务器启动后,将本地地址放入浏览器。加载站点后,右键单击图像并选择Inspect

带有检查下拉菜单的图像

现在导航到浏览器开发人员工具网络选项卡。本教程将使用Google Chrome DevTools

本地图像大小

您的图像从 4.8 MB 变为 68.4 kB。这比没有使用 Gatsby Image API 时要小得多。

注意:如果图片请求的 HTTP 状态是304,图片可能会因为缓存而明显变小。要获得更可靠的图像大小视图,请清除缓存并刷新页面。

保持开发人员工具打开并转到元素选项卡。将鼠标悬停在图像上。您将找到 HTML 元素<picture>...</picture>及其子元素<source>...</source>

Gatsby 站点的渲染 HTML

source标签中,您可以找到srcSet属性(与您在 GraphQL 中查询的相同)。您还会发现图像的不同高度和宽度是自动生成的。这些不同的图像确保angela-bailey-jlo7Bf4tUoY-unsplash.jpg流畅,无需更改 CSS。

注意:将鼠标悬停在图像上时,您可能已经注意到图像无法通过键盘聚焦,这可能是可访问性问题。如果您想了解有关可访问性的更多信息,可以查看Ally 项目清单

在本节中,您在 Gatsby 模板中使用了 GraphQL Image 查询。您还angela-bailey-jlo7Bf4tUoY-unsplash.jpg无需编写额外的 CSS 即可进行优化

在下一节中,您将使用 来直观地转换图像childSharpImage

第 4 步 — 使用样式设计您的图像 childSharpImage

在本节中,您将angela-bailey-jlo7Bf4tUoY-unsplash.jpg借助 来改变 的外观childSharpImage为了测试这一点,您将图像更改为灰度。

image.js在文本编辑器中打开

  • nano src/components/image.js

进入您的placeholderImageGraphQL查询和内部fluid设置grayscaletrue

gatsby-image-project/src/components/image.js
import React from "react"
import { useStaticQuery, graphql } from "gatsby"
import Img from "gatsby-image"

/*
 * This component is built using `gatsby-image` to automatically serve optimized
 * images with lazy loading and reduced file sizes. The image is loaded using a
 * `useStaticQuery`, which allows us to load the image from directly within this
 * component, rather than having to pass the image data down from pages.
 *
 * For more information, see the docs:
 * - `gatsby-image`: https://gatsby.dev/gatsby-image
 * - `useStaticQuery`: https://www.gatsbyjs.com/docs/use-static-query/
 */

const Image = () => {
  const data = useStaticQuery(graphql`
    query {
      placeholderImage: file(relativePath: { eq: "angela-bailey-jlo7Bf4tUoY-unsplash.jpg" }) {
        childImageSharp {
          fluid(
            maxWidth: 750
            grayscale: true
            ) {
            ...GatsbyImageSharpFluid
          }
        }
      }
    }
  `)

  if (!data?.placeholderImage?.childImageSharp?.fluid) {
    return <div>Picture not found</div>
  }

  return <Img fluid={data.placeholderImage.childImageSharp.fluid} tabIndex='0' />
}

export default Image

保存并关闭文件。

返回您的终端并重新启动服务器。你会发现你的图像使用 改变了childImageSharp,而无需编写和维护不必要的 CSS:

灰度图像

灰度只是您可以使用childImageSharp. 如果您对其他childImageSharpprops感到好奇,请转到 Gatsby 的文档

在本节中,您使用childImageSharp. 有了这些知识,您可以利用 Gatsby Image API 执行更多的图像操作。

结论

在本教程中,您将 Gatsby 项目设置为使用 Gatsby Image API,使用 GraphQL 查询您的图像,优化您的图像性能,并使用childImageSharp. 如果您想了解有关 Gatsby 的更多信息,请查看官方 Gatsby 文档

觉得文章有用?

点个广告表达一下你的爱意吧 !😁