Otimização de consultas de GraphQL optimizing-graphql-queries
Essas diretrizes são fornecidas para ajudar a evitar problemas de desempenho com as consultas do GraphQL.
Lista de verificação do GraphQL graphql-checklist
A lista de verificação a seguir tem como objetivo ajudar você a otimizar a configuração e o uso do GraphQL no as a Cloud Service do Adobe Experience Manager (AEM).
Primeiros princípios first-principles
Usar consultas persistentes do GraphQL use-persisted-graphql-queries
Recomendação
O uso de consultas persistentes do GraphQL é altamente recomendado.
As consultas persistentes do GraphQL ajudam a reduzir o desempenho da execução da consulta utilizando a Rede de entrega de conteúdo (CDN). Os aplicativos clientes solicitam consultas persistentes com solicitações GET para execução habilitada para fast edge.
Mais referências
Consulte:
Estratégia de cache cache-strategy
Vários métodos de armazenamento em cache também podem ser usados para otimização.
Ativar o armazenamento em cache do AEM Dispatcher enable-aem-dispatcher-caching
Recomendação
O AEM Dispatcher é o cache de primeiro nível no serviço AEM, antes do cache CDN.
Mais referências
Consulte:
Usar uma rede de entrega de conteúdo (CDN) use-cdn
Recomendação
As consultas do GraphQL e suas respostas JSON podem ser armazenadas em cache se direcionadas como solicitações GET
ao usar um CDN. Por outro lado, as solicitações não armazenadas em cache podem ser muito caras (recursos) e de processamento lento, com potencial para efeitos prejudiciais adicionais nos recursos da origem.
Mais referências
Consulte:
Definir cabeçalhos de controle de cache HTTP set-http-cache-control-headers
Recomendação
Ao usar consultas persistentes do GraphQL com um CDN, é recomendável definir cabeçalhos de controle de cache HTTP apropriados.
Cada consulta persistente pode ter seu próprio conjunto específico de cabeçalhos de controle de cache. Os cabeçalhos podem ser definidos na API GraphQL ou no AEM GraphiQL IDE.
Mais referências
Consulte:
Usar o pré-armazenamento em cache do AEM GraphQL use-aem-graphql-pre-caching
Recomendação
Esse recurso permite que o AEM armazene em cache ainda mais o conteúdo no escopo de consultas do GraphQL, que pode ser montado como blocos na saída JSON em vez de linha por linha.
Mais referências
Entre em contato com o Adobe para ativar esse recurso para seu programa e ambientes AEM Cloud Service.
Otimização de consulta do GraphQL graphql-query-optimization
Em uma instância do AEM com um alto número de fragmentos de conteúdo que compartilham o mesmo modelo, as consultas de lista de GraphQL podem se tornar caras (em termos de recursos).
Isso ocorre porque todos os fragmentos que compartilham um modelo que está sendo usado na consulta de GraphQL devem ser carregados na memória. Isso consome tempo e memória. A filtragem, que pode reduzir o número de itens no conjunto de resultados (final), só pode ser aplicada após carregar todo o conjunto de resultados na memória.
Isso pode causar a impressão de que até mesmo pequenos conjuntos de resultados podem resultar em baixo desempenho. No entanto, na realidade, a lentidão é causada pelo tamanho do conjunto de resultados inicial, pois ele deve ser manipulado internamente antes que a filtragem possa ser aplicada.
Para reduzir os problemas de desempenho e memória, esse conjunto de resultados inicial deve ser mantido o menor possível.
O AEM fornece duas abordagens para a otimização de consultas de GraphQL:
-
- A Classificação não está diretamente relacionada à otimização, mas à paginação
Cada abordagem tem seus próprios casos de uso e limitações. Esta seção fornece informações sobre a Filtragem e Paginação Híbridas, juntamente com algumas das práticas recomendadas para uso na otimização de consultas do GraphQL.
Usar filtragem híbrida do AEM GraphQL use-aem-graphql-hybrid-filtering
Recomendação
A filtragem híbrida combina a filtragem do JCR com a filtragem do AEM.
Ela aplica um filtro do JCR (na forma de uma restrição de consulta) antes de carregar o conjunto de resultados na memória para a filtragem do AEM. O objetivo é reduzir o conjunto de resultados carregado na memória, pois o filtro do JCR remove os resultados supérfluos.
Essa técnica mantém a flexibilidade que os filtros de GraphQL oferecem e delega o máximo possível da filtragem para o JCR.
Mais referências
Consulte:
Usar paginação do GraphQL use-aem-graphql-pagination
Recomendação
O tempo de resposta de consultas complexas, com grandes conjuntos de resultados, pode ser melhorado ao segmentar respostas em partes usando paginação, um padrão do GraphQL.
O GraphQL no AEM é compatível com dois tipos de paginação:
-
paginação baseada em limite/deslocamento
Isso é usado para consultas de lista; elas terminam comList
; por exemplo,articleList
.
Para usá-la, é preciso fornecer a posição do primeiro item a ser retornado (ooffset
) e o número de itens a serem retornados (olimit
ou o tamanho da página). -
paginação baseada em cursor (representada por
first
eafter
)
Ela fornece uma ID exclusiva para cada item; também conhecida como o cursor.
Na consulta, você especifica o cursor do último item da página anterior, além do tamanho da página (o número máximo de itens a serem retornados).Como a paginação baseada em cursor não se encaixa nas estruturas de dados das consultas baseadas em lista, o AEM introduziu o tipo de consulta
Paginated
; por exemplo,articlePaginated
. As estruturas de dados e os parâmetros utilizados seguem a Especificação de conexão de cursores do GraphQL.note note NOTE Atualmente, o AEM é compatível com a paginação para a frente (usando os parâmetros after
/first
).A paginação para trás (usando os parâmetros before
/last
) não é compatível.
Mais referências
Consulte:
Usar classificação do GraphQL use-graphql-sorting
Recomendação
Além de ser um padrão do GraphQL, a classificação permite que os clientes recebam conteúdo JSON em ordem de classificação. Isso pode reduzir a necessidade de processamento adicional no cliente.
A classificação só poderá ser eficiente se todos os critérios de classificação estiverem relacionados a fragmentos de nível superior.
Se a ordem de classificação incluir um ou mais campos localizados em um fragmento aninhado, todos os fragmentos que compartilham o modelo de nível superior deverão ser carregados na memória. Isso causa um impacto negativo no desempenho.
Mais referências
Consulte:
Práticas recomendadas best-practices
O principal objetivo de todas as recomendações de otimização é reduzir o conjunto de resultados inicial. As práticas recomendadas listadas aqui fornecem maneiras de se fazer isso. Elas podem (e devem) ser combinadas.
Filtrar somente nas propriedades de nível superior filter-top-level-properties-only
Atualmente, a filtragem no nível do JCR funciona somente para fragmentos de nível superior.
Se um filtro aborda os campos de um fragmento aninhado, o AEM precisa recorrer ao carregamento (na memória) de todos os fragmentos que compartilham o modelo subjacente.
Você ainda pode otimizar essas consultas de GraphQL combinando expressões de filtro em campos de fragmentos de nível superior, bem como aquelas em campos de fragmentos aninhados com o operador AND.
Usar a estrutura de conteúdo use-content-structure
No AEM, geralmente é considerada uma boa prática usar a estrutura do repositório para restringir o escopo do conteúdo a ser processado.
Essa abordagem também deve ser aplicada às consultas de GraphQL.
Isso pode ser feito aplicando um filtro no campo _path
do fragmento de nível superior:
{
someList(filter: {
_path: {
_expressions: [
{
value: "/content/dam/some/sub/path/",
_operator: STARTS_WITH
}
]
}
}) {
items {
# ...
}
}
}
/
à direita de value
é necessário para obter o melhor desempenho.Usar paginação use-paging
Também é possível usar a paginação para reduzir o conjunto de resultados inicial, especialmente se suas solicitações não usarem filtragem e classificação.
Se você filtrar ou classificar fragmentos aninhados, as consultas paginadas ainda poderão ser lentas, pois é provável que o AEM ainda precisará carregar quantidades maiores de fragmentos na memória. Portanto, se você combinar filtragem e paginação, considere as regras de filtragem (conforme mencionado acima).
Para a paginação, a classificação é igualmente importante, pois os resultados paginados são sempre classificados, seja de forma explícita ou implícita.
Se você estiver interessado principalmente em recuperar apenas as primeiras páginas, não há diferença significativa entre o uso das consultas ...List
ou ...Paginated
. No entanto, se o aplicativo estiver interessado em ler mais de uma ou duas páginas, considere usar a consulta ...Paginated
, pois ela tem um desempenho consideravelmente melhor com as páginas posteriores.
Operações lógicas em expressões de filtro logical-operations-in-filter-expressions
Se estiver filtrando em fragmentos aninhados, você ainda poderá aplicar a filtragem do JCR fornecendo um filtro de acompanhamento em um campo de nível superior, o qual é combinado usando o operador AND
.
Um caso de uso típico seria restringir o escopo da consulta usando um filtro no campo _path
do fragmento de nível superior e, em seguida, filtrar por campos adicionais que podem estar no nível superior ou em um fragmento aninhado.
Nesse caso, as diferentes expressões de filtro seriam combinadas com AND
. Portanto, o filtro no campo _path
pode limitar efetivamente o conjunto de resultados inicial. Todos os outros filtros em campos de nível superior também podem ajudar a reduzir o conjunto de resultados inicial, desde que sejam combinados com AND
.
Expressões de filtro combinadas com OR
não podem ser otimizadas se fragmentos aninhados estiverem envolvidos. Expressões OR
só podem ser otimizadas se nenhum fragmento aninhado estiver envolvido.
Evite filtrar em campos de texto multilinha avoid-filtering-multiline-textfields
Os campos de um texto multilinha (HTML, markdown, texto simples, JSON) não podem ser filtrados por uma consulta do JCR, pois o conteúdo desses campos deve ser calculado dinamicamente.
Se ainda precisar filtrar em um campo de texto multilinha, considere limitar o tamanho do conjunto de resultados inicial adicionando expressões de filtro adicionais e combinando-as com AND
. Limitar o escopo filtrando no campo _path
também é uma boa abordagem.
Evite filtrar em campos virtuais avoid-filtering-virtual-fields
Os campos virtuais (a maioria dos campos que começam com _
) são calculados enquanto uma consulta de GraphQL é executada e, portanto, estão fora do escopo da filtragem baseada em JCR.
Uma exceção importante é o campo _path
, que pode ser usado efetivamente para reduzir o tamanho do conjunto de resultados inicial, se o conteúdo for estruturado de acordo (consulte Usar a estrutura de conteúdo).
Filtragem: exclusões filtering-exclusions
Há várias outras situações em que uma expressão de filtro não pode ser avaliada no nível do JCR (e, portanto, deve ser evitada para se obter o melhor desempenho):
-
Filtrar expressões em um valor
Float
que usa a opção de filtro_sensitiveness
, no qual_sensitiveness
está definido como um valor diferente de0.0
. -
Filtrar expressões em um valor
String
usando a opção de filtro_ignoreCase
. -
Filtrar em valores
null
. -
Filtrar em matrizes com
_apply: ALL_OR_EMPTY
. -
Filtrar em matrizes com
_apply: INSTANCES
e_instances: 0
. -
Filtrar expressões usando o operador
CONTAINS_NOT
. -
Filtrar expressões em um valor
Calendar
,Date
ouTime
que usa o operadorNOT_AT
.
Minimizar aninhamento de fragmento de conteúdo minimize-content-fragment-nesting
O aninhamento de fragmentos de conteúdo é uma ótima maneira de modelar estruturas de conteúdo personalizadas. Você pode até ter um fragmento com um fragmento aninhado, que também tenha um fragmento aninhado, que tenha… e assim por diante.
No entanto, criar uma estrutura com muitos níveis pode aumentar os tempos de processamento de uma consulta do GraphQL, pois o GraphQL precisa percorrer toda a hierarquia de todos os fragmentos de conteúdo aninhados.
O aninhamento profundo também pode ter efeitos adversos na governança de conteúdo. Em geral, é recomendável limitar o aninhamento do Fragmento de conteúdo a menos de cinco ou seis níveis.
Não produzir todos os formatos (elementos de texto multilinha) do-not-output-all-formats
O AEM GraphQL pode retornar texto, criado no tipo de dados Texto de várias linhas, em vários formatos: Rich Text, Texto Simples e Markdown.
A saída de todos os três formatos aumenta o tamanho da saída de texto em JSON por um fator de três. Isso, combinado com conjuntos de resultados geralmente grandes de consultas muito amplas, pode produzir respostas JSON muito grandes que, portanto, levam muito tempo para serem computadas. É melhor limitar a saída somente aos formatos de texto necessários para renderizar o conteúdo.
Modificação de fragmentos de conteúdo modifying-content-fragments
Modifique somente os Fragmentos de conteúdo e seus recursos, usando a interface do usuário ou as APIs do AEM. Não faça modificações diretamente no JCR.
Testar suas consultas test-your-queries
O processamento de consultas do GraphQL GET é semelhante ao processamento de consultas de pesquisa, e é significativamente mais complexo do que as simples solicitações de API de conteúdo completo.
Planejar, testar e otimizar cuidadosamente suas consultas em um ambiente controlado não relacionado à produção é fundamental para o sucesso posterior, quando usado na produção.