gatsby_为什么我相信Gatsby.js拥有JavaScript的图像优化最佳工具-以及如何使用它们...

gatsby

by Bret Cameron

通过布雷特·卡梅伦

为什么我相信Gatsby.js拥有JavaScript的图像优化最佳工具-以及如何使用它们 (Why I believe Gatsby.js has JavaScript’s best tools for image optimisation — and how to use them)

使用Gatsby.js和GraphQL进行图像优化的初学者指南 (A beginner’s guide to using Gatsby.js and GraphQL for image optimisation)

Like so many developers, my first fully-functioning site was a blog. I built it as a custom WordPress theme, and I had grand plans for a homepage filled with high-quality images of the articles.

像许多开发人员一样,我的第一个功能完善的网站是一个博客。 我将其构建为自定义WordPress主题,并且制定了一个宏伟的计划,以制作包含高质量文章图像的首页。

When a pushed the site live for the first time, I typed in the URL and… waited. It was a major anti-climax. Far too many seconds passed by as the images slowly juddered into life.

当第一次将网站推送上线时,我输入了URL,然后……等待。 这是一个主要的反高潮。 随着图像慢慢变得生动起来,经过了太多的秒。

Up until this point, I hadn’t done any significant image optimisations. It was an important lesson for a relatively new developer, and I set about learning how to make as many optimisations as possible. But optimising the image sizes, configuring different sizes and resolutions of each image for different displays, and setting up lazy-loading with a nice “fade in” animation was a lot of work. Trying to solve these manually was good for learning, but it was certainly not something I wanted to do again and again.

到目前为止,我还没有进行任何重要的图像优化。 对于一个相对较新的开发人员来说,这是一个重要的教训,我着手学习如何进行尽可能多的优化。 但是优化图像尺寸,为不同的显示器配置每个图像的不同尺寸和分辨率,以及设置带有好的“淡入”动画的延迟加载是很多工作。 尝试手动解决这些问题对于学习很有帮助,但是我当然不想一次又一次地做这些事情。

Thankfully, there is a better way. Now, as a React developer, I have encountered lots of different image-processing systems and modules that make image optimisation straightforward. But — so far — nothing I’ve encountered comes close to Gatsby.js.

幸运的是,有更好的方法。 现在,作为React开发人员,我遇到了许多不同的图像处理系统和模块,这些系统和模块使图像优化变得简单明了。 但是,到目前为止,我所遇到的一切都与Gatsby.js差不多。

Using several Gatsby components, you can easily optimise your delivery of images — complete with “blur up” animations or traced SVG placeholders — plus added optimisations, like using WebP image formats for browsers that support them. They load quickly, in a way that looks really smooth, at the ideal resolution.

使用多个Gatsby组件,您可以轻松地优化图像的交付-包括“模糊”动画或跟踪的SVG占位符-以及添加的优化,例如将WebP图像格式用于支持它们的浏览器。 它们以理想的分辨率快速加载,看起来非常平滑。

介绍Gatsby图像优化 (Introducing Gatsby Image Optimisation)

Gatsby.js makes image optimisation easy, except for one thing: if you’ve never used GraphQL before, the process might take a little while to get used too. It took me a few goes to get to grips with Gatsby image, mainly because of not jumping into GraphQL.

Gatsby.js使图像优化变得容易,除了以下几点:如果您以前从未使用过GraphQL,则该过程也可能需要一段时间才能被使用。 我花了一些时间掌握Gatsby图像,主要是因为未跳入GraphQL。

I also felt that many tutorials (including the official ones) fell short when it came to explaining how to deal with more than one image. The official Gatsby starter contains an image component, and this would work fine if your site only had a handful of images. But what if it had tens or hundreds?

我还感到很多教程(包括官方教程)在解释如何处理多个图像方面都不够。 官方的盖茨比启动器包含一个图像组件,如果您的站点只有少量图像,则此组件可以正常工作。 但是,如果有几十个或几百个呢?

That’s what this article intends to answer. In it, we’ll take a step-by-step approach to combining the powers of Gatsby and GraphQL for image optimisation. We’ll start by rendering three images, and in the final section, I’ll discuss a few ways to scale up.

这就是本文要回答的问题。 在本文中,我们将逐步介绍如何结合Gatsby和GraphQL的功能来优化图像。 我们将从渲染三个图像开始,在最后一节中,我将讨论几种放大方法。

分步演练 (Step-by-Step Walkthrough)

步骤1:安装依赖项 (Step 1: Install Dependencies)

Gatsby has two main image components: gatsby-image and gatsby-background-image .

Gatsby具有两个主要的图像组件: gatsby-imagegatsby-background-image

To use either of them, you’ll need several additional components to your Gatsby project. (If you’re new to Gatsby, you can find out how to start a project here). Once your Gatsby project is set up, you can install all the necessary image-related plugins via npm, by typing:

要使用它们之一,您的Gatsby项目需要几个其他组件。 (如果您是Gatsby的新手,则可以在此处了解如何启动项目 )。 设置好Gatsby项目后,您可以通过输入以下内容通过npm安装所有必需的与图像相关的插件:

npm i gatsby-image gatsby-background-image gatsby-source-filesystem gatsby-plugin-sharp gatsby-transformer-sharp -s

This may look like a lot, but each plugin more-or-less does a single job:

这看起来可能很多,但是每个插件或多或少都会完成一项工作:

  • gatsby-image is used to display images

    gatsby-image用于显示图像

  • gatsby-background-image is used to display background images

    gatsby-background-image用于显示背景图像

  • gatsby-source-filesystem allows you to query files in your site’s file system using GraphQL

    gatsby-source-filesystem允许您使用GraphQL查询站点文件系统中的文件

  • gatsby-transformer-sharp is the plugin that enables you to create multiples images of the right sizes and resolutions via queries

    gatsby-transformer-sharp是一个插件,可让您通过查询创建尺寸和分辨率合适的多个图像

  • and gatsby-plugin-sharp connects the Sharp and Gatsby plugins together

    gatsby-plugin-sharp将Sharp和Gatsby插件连接在一起

步骤2:设定Gatsby (Step 2: Configure Gatsby)

Once installed, you should make sure that certain of the above plugins are present in your gatsby-config.js file in the root directory of your web app.

安装完成后,您应该确保上述gatsby-config.js文件中的某些插件存在于Web应用程序的根目录中。

In the example below, I have identified two directories, images and pages , where I’d like to be able to query my file system. In this article, we’ll only be focusing on images , but it’s common to query your pages directory as well!

在下面的示例中,我确定了两个目录, imagespages ,我想在其中查询我的文件系统。 在本文中,我们仅关注images ,但是查询pages目录也是很常见的!

module.exports = {  plugins: [    `gatsby-transformer-sharp`,    `gatsby-plugin-sharp`,    {      resolve: `gatsby-source-filesystem`,      options: {        name: `images`,        path: `${__dirname}/src/images`,      },    },    {      resolve: `gatsby-source-filesystem`,      options: {        name: `pages`,        path: `${__dirname}/src/pages`,      },    },  ],}

If you’re used to installing and importing npm packages, so far this may be feeling pretty straightforward. At this point, things begin to look a little more unusual.

如果您习惯于安装和导入npm软件包,那么到目前为止,这可能感觉非常简单。 在这一点上,事情开始看起来有点不寻常。

步骤3A:在GraphQL中测试查询 (Step 3A: Test Queries in GraphQL)

Now, we’re going to access the GraphiQL interface. By default, Gatsby app’s run on localhost:8000 . We can access the GraphiQL interface by adding /___graphql to the end of the domain (that’s 3 underscores in a row).

现在,我们将访问GraphiQL接口。 默认情况下,Gatsby应用程序在localhost:8000上运行。 我们可以通过在域的末尾添加/___graphql来访问GraphiQL接口(连续3个下划线)。

In here, we can try out different queries on our data before committing them into our code. It’ll save us time debugging later, because we know the queries are picking up the data we want.

在这里,我们可以对数据进行不同的查询,然后再将其提交到代码中。 这将为我们节省以后进行调试的时间,因为我们知道查询正在获取所需的数据。

First, let’s check that our gatsby-config.js file is working correctly. Type the following code into the GraphiQL interface and press the play icon (or CTRL/CMD + ENTER ):

首先,让我们检查一下我们的gatsby-config.js文件是否正常工作。 在GraphiQL界面中键入以下代码,然后按播放图标(或CTRL/CMD + ENTER ):

{  allDirectory {    edges {      node {        name      }    }  }}

If you see something similar to the image above, it’s working. Now, let’s query the contents of our images folder, by typing:

如果您看到与上图类似的图像,则说明它正在工作。 现在,通过键入以下内容来查询图像文件夹的内容:

{  allFile(filter:{ sourceInstanceName:{eq: "images"} }){    edges{      node{        relativePath        childImageSharp {          id        }      }    }  }}

If the “childImageSharp” property returns an ID, then that means that we can use Gatsby’s image optimisations on it. This will return null on files such as SVGs, because they cannot be further optimised, but it should give you a string for every jpg and png .

如果“ childImageSharp”属性返回ID,则意味着我们可以在其上使用Gatsby的图像优化功能。 对于诸如SVG之类的文件,这将返回null ,因为它们无法进一步优化,但应为每个jpgpng提供一个字符串。

步骤3B:准备我们的特定图像查询 (Step 3B: Prepare our Specific Image Queries)

Now let’s grab a handful of specific images. When performing queries on an image, you need to tell Gatsby whether that image is fixed or fluid . fixed images have known dimensions, and they require fewer processes to optimise. fluid images have dimensions that change based on viewport size and other contextual factors.

现在,让我们获取一些特定的图像。 在图像上执行查询时,您需要告诉Gatsby该图像是fixed还是fluidfixed图像具有已知的尺寸,并且需要较少的过程来进行优化。 fluid图像的尺寸会根据视口大小和其他上下文因素而变化。

I’m building a portfolio and I have images for each of my services. So let’s say we want to grab three images called webdev.jpg , design.jpg and writing.jpg , and we know that their dimensions are fluid.

我正在建立一个投资组合,并且每个服务都有图像。 因此,让我们说,我们要抓住三个图像称为webdev.jpgdesign.jpgwriting.jpg ,我们知道他们的尺寸是fluid

{   webdev:file(relativePath:{eq:"webdev.jpg"}) {    childImageSharp {      fluid(maxWidth: 1600) {        base64      }    }  }    design:file(relativePath:{eq:"design.jpg"}) {    childImageSharp {      fluid(maxWidth: 1600) {        base64      }    }  }    writing:file(relativePath:{eq:"writing.jpg"}) {    childImageSharp {      fluid(maxWidth: 1600) {        base64      }    }  }  }

Note that the terms before each colon can be anything we want. Here, it makes sense to stick to the file name. We’re also setting a max-width property of 1600 pixels, so Gatsby knows it doesn’t need to prepare versions of each image larger than this.

请注意,每个冒号前面的术语可以是我们想要的任何内容。 在这里,坚持使用文件名是有意义的。 我们还将最大宽度属性设置为1600像素,因此Gatsby知道不需要为每个图像准备大于此宽度的版本。

base64 is the property that contains a tiny, blurry version of our image that will load almost immediately, and then get smoothly replaced by a high-resolution version. If our query returns a value for base64 , then everything’s working. We’re ready to include this query in our code!

base64是一个属性,其中包含我们图像的微小模糊版本,几乎立即将其加载,然后平滑地替换为高分辨率版本。 如果我们的查询返回base64的值,则一切正常。 我们已经准备好将此查询包含在我们的代码中!

步骤4:导入元件并渲染 (Step 4: Import Components and Render)

Navigate to any component where you’d like to display the images. First, you need to import the StaticQuery and graphql components from "gatsby" at the top of your file, as well as Img or BackgroundImage , like this:

导航到要显示图像的任何组件。 首先,您需要从文件顶部的"gatsby"以及ImgBackgroundImage导入StaticQuerygraphql组件,如下所示:

import { StaticQuery, graphql } from "gatsby"import Img from "gatsby-image"import BackgroundImage from "gatsby-background-image"

Our React component should return a <StaticQuery> tag, which is a query property and a render property.

我们的React组件应该返回一个<StaticQue ry>标签,它is a查询属性and a render属性。

<StaticQuery query={  graphql`{    # our GraphQL queries go here  `}   render={(data) => (    <>      {/* our JSX goes here */}    </>  )}/>

We can paste our image queries above into the query property, but this time we’ll replace base64 with the fragment we want to render our images. In this case, we’ll use ...GatsbyImageSharpFluid .

我们可以将上面的图像查询粘贴到query属性中,但是这次我们将base64替换为我们要呈现图像的片段。 在这种情况下,我们将使用...GatsbyImageSharpFluid

But let’s say we later decided we wanted the traced SVG effect, and that we wanted to use the WebP format where possible. We can simply swap out our fragment with ...GatsbyImageSharpFluid_withWebp_tracedSVG .

但是,可以说我们后来决定要跟踪SVG效果,并希望尽可能使用WebP格式。 我们可以简单地用...GatsbyImageSharpFluid_withWebp_tracedSVG交换片段。

Our code should now look like this:

现在,我们的代码应如下所示:

<StaticQuery query={  graphql`{    webdev:file(relativePath:{eq:"webdev.jpg"}) {    childImageSharp {      fluid(maxWidth: 1600) {        ...GatsbyImageSharpFluid      }    }  }    design:file(relativePath:{eq:"design.jpg"}) {    childImageSharp {      fluid(maxWidth: 1600) {        ...GatsbyImageSharpFluid      }    }  }    writing:file(relativePath:{eq:"writing.jpg"}) {    childImageSharp {      fluid(maxWidth: 1600) {        ...GatsbyImageSharpFluid      }    }  }  `}   render={(data) => (    <>      {/* our JSX goes here */}    </>  )}/>

Last, we simply need to include the image in our JSX.

最后,我们只需要将图像包含在JSX中即可。

The Img component takes a fluid property (where you put reference the query data) and an alt property.

Img组件具有fluid属性(在其中放置了查询数据的引用)和alt属性。

<Img   fluid={data.webdev.childImageSharp.fluid}  alt=""/>

The BackgroundImage component takes a tag property (if left blank, it renders a div ), a fluid property, and a backgroundColor property.

BackgroundImage组件具有一个tag属性(如果留为空白,则呈现div ), fluid属性和backgroundColor属性。

<BackgroundImage  tag="section"  fluid={data.webdev.childImageSharp.fluid}  backgroundColor={`#000`}&gt;  {/* the child elements that go above the background */}</BackgroundImage>
汇集全部 (Bringing It All Together)

Here’s a complete Gatsby component that takes three images for our images folder and renders them:

这是一个完整的Gatsby组件,该组件为我们的images文件夹获取三张图像并进行渲染:

扩大策略 (Strategies for Scaling Up)

So, how do we make this work when we need to process larger numbers of images? Here are a few ideas to get you started.

那么,当我们需要处理大量图像时,如何使这项工作呢? 这里有一些想法可以帮助您入门。

循环浏览文件夹 (Looping Through a Folder)

Let’s say we had a list of icons we wanted to display. Rather than querying them all separately, we could put them in their own directory, and use a loop to iterate through the results of the query. For example, we could query the entire “icons” directory:

假设我们有一个要显示的图标列表。 可以将它们放在各自的目录中,而不是分别查询它们,并使用循环遍历查询结果。 例如,我们可以查询整个“ icons”目录:

{  icons:allFile(filter:{ relativeDirectory:{eq: "icons"} }){    edges{      node{        name        relativePath        childImageSharp {          id        }      }    }  }}

Then, if we log data.icons.edges to the console, we can see an array of items which we could iterate through. Here’s an example of what that might look like.

然后,如果我们将data.icons.edges记录到控制台,则可以看到可以迭代的一系列项。 这是一个可能看起来像的例子。

data.icons.edges.map(item => (  <Img     fluid={item.node.childImageSharp.fluid}     alt={item.node.name}   />))
传递动态数据 (Passing in Dynamic Data)

One important method is adding dynamic variables to our queries. GraphQL has a specific syntax for this.

一种重要的方法是将动态变量添加到我们的查询中。 GraphQL为此具有特定的语法。

To do this, let’s give our query a name, findFile , by using the query keyword. Then, in parentheses, we can name any number of new variables.

为此,我们使用query关键字为query命名findFile 。 然后,在括号中,我们可以命名任意数量的新变量。

In GraphQL, all variables must be preceded by $ . After the variable name, we use a colon and then specify the type: here, a String . Finally, we can use = to pass in a default fallback value, and this will allow us to test the query in GraphiQL.

在GraphQL中,所有变量必须以$开头。 在变量名之后,我们使用冒号,然后指定类型:此处为String 。 最后,我们可以使用=传递默认的后备值,这将使我们能够在GraphiQL中测试查询。

query findFile($relativePath: String = "webdev.jpg") {  file(relativePath: {eq: $relativePath}) {    id    relativePath    publicURL  }}

It’s possible to add further logic to these queries by using the directives @include(if: Boolean) and @skip(if: Boolean) .

可以通过使用指令@include(if: Boolean)@skip(if: Boolean)向这些查询添加更多逻辑。

GraphQL variables are particularly useful if we want our users to be able to dynamically filter data. But they also come in handy for any reason we might want to separate certain data from our actual query, for example, if we need to modify it in some way first.

如果我们希望用户能够动态过滤数据,则GraphQL变量特别有用。 但是由于任何原因,它们也会派上用场,例如,如果我们需要首先以某种方式进行修改,则可能出于某些原因希望将某些数据与实际查询分开。

创建自定义片段 (Creating Custom Fragments)

Remember ...GatsbyImageSharpFluid above? That’s a fragment, which is essentially shorthand for a reusable set of query fields. We can also define our own fragments.

还记得上面的...GatsbyImageSharpFluid吗? 这是一个片段,从本质上讲是可重复使用的查询字段集的简写。 我们还可以定义自己的片段。

Even if we’re only calling three query fields — id , relativePath and publicURL —that can add up to many lines of code extra code if we’re using them repeatedly. Instead, we could define a custom fragment, allowing us to reuse query fields. Rather than repeating the official documentation’s description of how to do this, I recommend you check it out.

即使我们仅调用三个查询字段( idrelativePathpublicURL ,如果我们重复使用它们,它们最多可以添加多行代码。 相反,我们可以定义一个自定义片段,从而允许我们重用查询字段。 建议您不要查看官方文档中有关如何执行此操作的说明。

结论 (Conclusion)

Overall, I hope this article has opened your eyes to the powerful image optimisation tools that come with Gatsby.js, and has given you some ideas for how to apply them to larger-scale projects.

总体而言,我希望本文使您对Gatsby.js随附的功能强大的图像优化工具大开眼界,并为您提供了一些有关如何将其应用于大型项目的想法。

In order to fully understand and maximise these powerful tools, you need to get to grips with both React and GraphQL. When I first started using Gatsby, I skipped over GraphQL, not realising that an understanding of it — at least to a basic level — was essential for making the most of Gatsby’s image optimisation features.

为了充分理解和最大化这些强大的工具,您需要掌握React和GraphQL。 刚开始使用Gatsby时,我跳过了GraphQL,但没有意识到对它的了解(至少是基本水平)对于充分利用Gatsby的图像优化功能至关重要。

翻译自: https://www.freecodecamp.org/news/why-i-believe-gatsby-js-has-javascripts-best-tools-for-image-optimisation-and-how-to-use-them-939c82d05395/

gatsby

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值