Otimizando Caches do Site AEM

Visão geral

A otimização do armazenamento em cache em sua arquitetura AEM é uma das maneiras mais rápidas de obter um grande aumento de desempenho.  Este artigo se concentra em explicar como otimizar os diversos caches disponíveis em uma arquitetura AEM.

Arquitetura e Cache do AEM

Em todas as arquiteturas do AEM, o usuário encontra várias camadas de cache ao visitar seu site.  Existem 4 camadas de cache a serem consideradas em uma arquitetura padrão do AEM.  Isso inclui as instâncias de navegador da Web, CDN, Dispatcher e AEM.

Cache do Navegador

O primeiro nível de cache que um usuário encontra em uma visita repetida do seu site é seu próprio navegador.  O cache no nível do navegador é comumente feito através do Cache-Control: max-age=... resposta header.  A configuração max-age informa ao navegador em quantos segundos ele deve armazenar o arquivo em cache antes de tentar "revalidar" ou solicitá-lo novamente ao site.  Este conceito de cache max-age é comumente referido como "Expiração do cache" ou TTL ("Time to Live").

Existem várias opções (ou "diretivas") dentro do cabeçalho Controle de Cache que afetam como o armazenamento em cache ocorre.  Aqui estão algumas das diretivas comuns:

  1. private - a diretiva private no cabeçalho Controle de Cache faz com que o arquivo só seja armazenado em cache no navegador, não em caches intermediários, como CDNs.  Um uso prático para esta diretiva seria se a sua página incluir conteúdo personalizado / específico do usuário. 

    Exemplo de uso:
      Cache-Control: max-age=300, private
  2. s-maxage - a diretiva s-maxage no cabeçalho Controle de Cache permite que você defina um TTL diferente para caches compartilhados, como CDNs.  Quando esse valor é definido, o navegador usaria o que é definido max-age e outros caches respeitariam a configuração s-maxage em vez disso.

    Exemplo de uso:
      Cache-Control: max-age=600, s-maxage=300

Todos os navegadores modernos suportam o cabeçalho Controle de Cache. No entanto, alguns cabeçalhos deprecados antigos existem no HTTP/1.0, o que pode ainda ter um efeito no armazenamento em cache.  Esses cabeçalhos são Expires e Pragma.  Se você não precisa suportar navegadores muito antigos, não envie esses cabeçalhos de resposta.
Além do armazenamento em cache, a revalidação também é um conceito importante.  A revalidação depende dos cabeçalhos Last-Modified (response) / If-Modified-Since (request) e cabeçalhos ETag (response) / If-None-Match (solicitação).  

Cuidado:

Teste do navegador:

Ao testar o armazenamento em cache no Google Chrome, se você estiver testando por https e tiver um certificado auto-assinado, nada será armazenado em cache.  O Chrome não armazenará respostas em cache nem executará a revalidação quando houver um certificado não confiável ou inválido.

Nota sobre o despachante:

Há um problema com o AEM Dispatcher v4.2.3 e versões anteriores em que o /enableTTL somente armazena em cache usando diretiva max-age.  Isso significa que mesmo quando as diretivas private ou s-maxage são definidas ainda seria feito o armazenamento em cache se max-age estiver definido.  Esse problema foi resolvido no Dispatcher 4.2.4 e nas versões posteriores.

Armazenamento em cache de CDN

 UMA CDN ou "Rede de Entrega de Conteúdo"é uma rede distribuída de servidores da Web projetados para armazenar em cache e veicular conteúdo do local mais próximo de seus usuários.  Isso reduz o salto de rede e a distância do computador do usuário para o seu conteúdo, reduzindo assim "Round Trip Time" (RTT).  RTT é o tempo que o navegador leva para enviar uma solicitação ao seu site e receber uma resposta.  A competição no espaço do provedor de CDN tornou as CDNs muito rentáveis.  Isso torna fácil a decisão de usar uma CDN para seu site.  Se você não estiver usando uma CDN ainda, então você deve definitivamente incorporar uma CDN em seu site.

Existem muitos provedores de CDN, cada um oferece recursos e configurações diferentes.

Como funciona o CDN Caching

As CDNs armazenam conteúdo em cache seguindo regras semelhantes aos navegadores.  Eles se fiam no cabeçalho de resposta HTTP Cache-Control e geralmente se voltam para o cabeçalho Expires se nenhum cabeçalho Cache-Control é encontrado.

A maioria das CDNs fornece alguma maneira de acionar uma limpeza manual do cache.  Em muitos casos, as limpezas de cache têm algum atraso (por exemplo, 15 minutos) em relação à propagação para todos os servidores de borda que possuem seus arquivos.

Otimizando o uso da CDN

Há algumas coisas a se fazer para garantir que você esteja armazenando arquivos em cache de maneira ideal na CDN:

  1. Use uma CDN que suporte as diretivas stale-while-revalidate e stale-if-error no cabeçalho Cache-Control.
    • stale-while-revalidate - esta diretiva informa à CDN para servir a versão antiga (já armazenada em cache) do arquivo enquanto ela recupera um novo após o arquivo de cache ter expirado.
    • stale-if-error - de maneira similar, esta diretiva diz à CDN para servir a versão antiga (já armazenada em cache) do arquivo quando a origem responde com um erro durante a revalidação.
  2. Compressão de resposta GZip para todos os tipos de arquivos que não são pré-compactados.
    • Você deve fazer isso a partir do nível do dispatcher.  Isso garantirá que você reduza o número de bytes enviados para a CDN.  As CDNs geralmente cobram por bytes transferidos, portanto, compactar as respostas reduz o custo.
    • Ativar a compactação GZip no nível do Dispatcher:
      • Apache - use mod_deflate.  Tenha cuidado com o uso do Vary pelo mod_deflate.  Em determinados casos, o cabeçalho Vary pode fazer com que a CDN e o navegador ignorem totalmente o armazenamento em cache.
      • Microsoft IIS - use Compressão dinâmica.
      • Não permita a compactação gzip de arquivos grandes ou arquivos que já estejam compactados.  Observe que a maioria dos formatos de imagem e vídeo já está pré-compactada.  Compactá-los dinamicamente no nível do servidor da Web tem um custo muito alto para o desempenho. 
        • No Apache, isso pode ser feito por meio da diretiva AddOutputFilterByType:
          AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript application/javascript
        • No IIS, isso pode ser controlado pela configuração <dynamicTypes>.
  3. Se o seu provedor CDN suportar Edge-side Includes (ESI) aproveite esse recurso.
    • Os componentes do AEM podem ser desmembrados usando o ESI.  Para fazer isso, use o Apache Sling Dynamic Includes ou implemente uma solução personalizada.
    • É útil quando você tem páginas bastante estáticas, mas está veiculando mais conteúdo dinâmico em algumas partes da página.  Nesses casos, você está essencialmente dividindo a página em vários arquivos CDN.  Dessa forma, você pode armazenar em cache diferentes partes da página por diferentes períodos de tempo.

Provedores de CDN populares

Aqui está uma lista de alguns provedores de CDN populares:

Cuidado:

Tenha cuidado com o cabeçalho de resposta Vary.  Em certos casos, o Vary pode fazer com que tanto a CDN quanto o navegador ignorem totalmente o armazenamento em cache.  Como regra geral, evite adicionar Vary exceto por Vary: Accept-Encoding (aplicado somente quando a resposta é compactada por gzip).  Em outras palavras, se você precisar "variar" a saída de uma resposta, use um URL diferente.

Por exemplo, se você tiver uma versão diferente do HTML para celular e para computador, use um URL diferente.  Isso permitirá que as CDNs e os navegadores armazenem em cache com mais eficiência.

AEM Dispatcher Caching

Se o cache CDN expirou, então a solicitação alcança o cache do AEM dispatcher.  Nesse nível há muitas coisas que podem ser feitas para otimizar o armazenamento em cache.

Como esse é um tópico maior, consulte este artigo para detalhes sobre como otimizar o cache do dispatcher.

Instâncias de publicação do AEM

No nível do AEM, há algumas coisas que devem ser feitas para otimizar as várias camadas de cache:
  1. Defina os seguintes cabeçalhos de resposta HTTP que não são definidos pelo AEM por padrão.
    1. Cache-Control: max-age=... - Para definir este cabeçalho, ACS Commons - Dispatcher TTL poderia ser usado, ou você poderia implementar um código personalizado para configurá-lo.  
    2. Last-Modified - Se o conteúdo da página é relativamente estático, como um artigo, então você pode definir seu cabeçalho last-modified para cq:lastModified date/time (última vez que o artigo foi modificado).  No entanto, se a página for dinâmica com os resultados da consulta JCR contidos no conteúdo do componente, será melhor configurá-la para usar a data/hora atuais. 
    3. ETag - se você decidir usar isso em vez de Last-Modified, você poderia escrever um ReplicationEventListener que ouve ativações de página e gera um hash md5 do conteúdo da página.  Isso pode ser definido como uma propriedade no nó jcr:content da página na instância do autor.  Quando as páginas são replicadas, elas são enviadas para as instâncias de publicação.  Para componentes de página com conteúdo que é relativamente estático, isso poderia funcionar bem, no entanto, se a página é um pouco dinâmica ou faz referência a muito conteúdo, então o ETag teria que ser omitido (ou calculado).
  2. Se o site tiver conteúdo personalizado/dinâmico:
    1. Use Apache Sling Dynamic Includes para dividir o conteúdo para que diferentes partes da página possam ser armazenadas em cache por diferentes períodos de tempo.
      1. O cache pode ser feito com as seguintes tecnologias:
        1. Edge-side Includes (ESI) na CDN
        2. Server-side Includes (SSI) no servidor da web
        3. Ou Asynchronous Javascript and XML (AJAX) no navegador
      2. Os componentes da página podem ser divididos em solicitações separadas, que podem ser armazenadas em cache por diferentes períodos de tempo.  Partes da página que são relativamente estáticas podem ser armazenadas em cache por períodos muito mais longos.
    2. Considere usar o recurso HTTP Cache do ACS Commons.
  3. Otimizar bibliotecas do cliente.
    1. Ative minificação nas bibliotecas do cliente.
    2. Se os arquivos na biblioteca do cliente forem pré-minificados, desative a minificação nessa biblioteca do cliente.  Edite o nó cq:ClientLibraryFolder:
      1. Defina a propriedade jsProcessor do tipo String[] com o valor min:none 
      2. e defina a propriedade cssProcessor do tipo String[] com o valor min:none
      3. Veja mais detalhes, aqui.
    3. Incorpore bibliotecas cliente para minimizar e reduzir arquivos js e css.
    4. Implemente versioned-clientlibs do ACS Commons para permitir que o CDN e o Dispatcher armazenem arquivos js e css em cache por períodos mais longos.
Logotipo da Adobe

Fazer logon em sua conta