Я вижу возможность минимизировать передачу сетевых байтов моего веб-сайта, но не могу найти подходящего решения.
В Gatsby я использую файлы .mdx. В этих файлах я могу использовать компоненты React, такие как:
<Cards id = "id_1" />
В файле .json определены десятки карточек, которые можно использовать на веб-сайте, просто вызвав этот компонент в файле mdx и передав их идентификатор.
Компонент «Карты» выглядит примерно так:
import React from 'react'
import Img from 'gatsby-image';
import { StaticQuery, graphql } from 'gatsby';
const Cards = (props) => {
const card_id = props.id ? props.id.slice(0, 2) : [] // grab id
return <StaticQuery
query = {graphql`
query Query {
images: allFile(filter: { sourceInstanceName: { eq: "card-images" } }) {
edges {
node {
childImageSharp {
fluid(maxHeight: 256, quality: 100) {
...GatsbyImageSharpFluid_withWebp
...GatsbyImageSharpFluidLimitPresentationSize
}
}
name
}
}
}
allCardsJson {
nodes {
name
id
}
}
}
`}
render = {(data) => {
return(
// returns a component by filtering 'data' by 'card_id'
)
}}
/>
}
Все работает нормально, но...
При использовании этого компонента полный результат StaticQuery (имеется в виду: все карточки, так как фильтрация выполняется внутри возврата, а не внутри статического запроса) отправляется посетителям страницы. Это не нужно и приводит к пустой трате пропускной способности сети, потому что, например, на странице используется только одна карта (или несколько).
Я понимаю, что StaticQuery является... статическим. Таким образом, я не могу динамически фильтровать в этом запросе, чтобы ограничить размер результата.
DynamicQuery используются при построении страниц, а не внутри компонентов.
Можно ли каким-то образом создавать компоненты с динамическим содержимым (определенным где-то еще), но ограничиваться только необходимыми данными? (например, предоставив идентификатор, как я пробовал)
Я думаю о создании отдельного файла для каждой карты. Затем импортируйте необходимые карты в файл mdx и передайте его компоненту. Мысли?
Документации по моему варианту использования нет. Это заставляет меня задаться вопросом, использую ли я его по назначению.
🤔 А знаете ли вы, что...
JavaScript был первоначально создан для улучшения интерактивности веб-страниц.
Запросы GraphQL выполняются ОДИН РАЗ, когда вы запускаете gatsby develop
или gatsby build
. Это нелогично, как работает Гэтсби, но прочтите сами:
Gatsby использует GraphQL во время сборки, а не для живых сайтов.
Больше информации о процессе сборки gatsby и о том, как на него влияет GraphQL.
Это означает, что вы уже построили свой компонент так, как предполагалось. Во время сборки все ваши карты запрашиваются и сохраняются в памяти. При создании HTML-кода для ваших страниц с вашими карточками для создания вашей страницы используются только карточки с вашим идентификатором. Таким образом, пользователь видит только переданные страницы с отфильтрованными идентификаторами.
Вы можете дважды проверить, действительно ли на вашей странице находятся только карты с идентификатором:
gatsby clean
: убедитесь, что старые фрагменты вашей страницы удаленыgatsby build
: Создайте свой сайт с нуляpublic
в корне вашего проекта. Это классическая веб-страница, которую создает Гэтсби. Перейдите на свои страницы со своими карточками, например /public/blog/example-page-with-card
. Загляните внутрь HTML-кода страницы: содержит ли она все карточки или только одну с нужными вам идентификаторами?Я решил это, добавив используемые данные в контекст страницы, отредактировав файл gatsby-node.js:
<Cards data = {props.cards_data} />
.Это работает, но как-то странно. На мой взгляд, должно быть лучшее, более чистое решение.