Nova API de Loaders: Aprimorando Stale Caching e Tracing

Mudanças na camada de cache da deco e melhorias no tracing
05/12/2023·Tiago Gimenes

Introdução

Stale caching tem sido há muito tempo o segredo por trás da velocidade e confiabilidade dos sites deco.cx. Com APIs de comércio eletrônico frequentemente enfrentando latência entre 1 a 7 segundos, criar um mecanismo de renderização que responda em uma escala de sub-segundos requer uma camada de caching meticulosamente projetada. Hoje, estamos animados em anunciar uma mudança fundamental na forma como o stale caching opera no deco.cx, introduzindo uma API mais simples para desenvolvedores e melhorando significativamente a observabilidade.

No passado, utilizar a camada de stale caching do deco.cx significava que os desenvolvedores tinham que empregar uma implementação customizada de fetch fornecida pelo framework deco.cx. Esse fetch customizado modificava a URL solicitada, direcionando a requisição através do CDN do deco e incorporando stale caching. Por exemplo, ao buscar https://example.com, o framework realmente recuperaria https://decocache.com?src="https://example.com". No entanto, com o crescente número de aplicativos no decohub, alguns serviços já forneciam bibliotecas para interagir com suas APIs, tornando impraticável nossa implementação customizada de fetch. Além disso, a integração do tracing era desafiadora devido à falta de controle do framework sobre as conexões HTTP. Consequentemente, estamos nos afastando da implementação customizada de fetch, realocando a camada de caching para nossos loaders. Esta nova API oferece suporte perfeito tanto para o stale caching quanto para o tracing.

Optando pelas Novas Funcionalidades: Um Processo de Transição Simplificado

Para começar a usar a nova API de loaders, configure a variável de ambiente:

export ENABLE_LOADER_CACHE=true

Habilitar o Stale Caching

Por padrão, o stale caching permanece inativo nos loaders. Ativar essa funcionalidade requer uma modificação simples no código do seu loader:

// ... código do loader

export const cache = 'stale-while-revalidate'

Você tem a opção de configurar a variável de cache para stale-while-revalidate ou no-store, sendo o padrão no-store.

Agora, seu loader está com stale caching! Para confirmar, abra uma página onde seu loader é usado, adicione uma string de consulta ?<em></em>d à URL e observe as informações de tracing no terminal, incluindo os estados de cache como HIT, MISS, STALE e BYPASS.

[200] 1312ms /camisa-masc-classic-linen-ml-verde-forest-46661-206/p
[====================] 1312ms 200 /camisa-masc-classic-linen-ml-verde-forest-46661-206/p
[ ] 0ms load-page
[ ] 23ms router
[ ===================] 1234ms load-data
[ ===================] 1233ms Product Page@sections
[ ] 0ms PDP [email protected]
[ ===================] 1231ms STALE PDP [email protected]
[ ] 47ms render-to-string

HIT: Cache considerado fresco (max-age padrão: 60 segundos). STALE: Cache não está fresco, mas conteúdo antigo servido (validação em segundo plano acionada). MISS: Loader é cacheável, mas dados não estão no cache. BYPASS: Loader não é cacheável, possivelmente devido a configurações específicas.

Observe que a chave de cache varia com o conteúdo de props passado para o loader. Para variar a resposta do loader com o objeto Request, leia a próxima seção.

Variando o Cache

Alguns loaders podem precisar variar com base em propriedades disponíveis apenas no objeto Request, como strings de consulta, cookies, etc. Para alcançar isso, abra o arquivo do seu loader e exporte a função cacheKey:

export const cacheKey = (req: Request, ctx: AppContext): string => '';

Essa função permite que o desenvolvedor descreva precisamente como o cache deve variar.

Exemplo

Para ilustrar, considere um cenário prático. Suponha que você esteja construindo um loader para buscar uma resposta paginada, com informações de paginação armazenadas em um parâmetro ?page=. Veja como você pode implementar corretamente esse loader:

interface Props {
// ... props do loader
}

const loader = (props: Props, req: Request, ctx: AppContext) {
// Detalhes de implementação para buscar resposta paginada
}

export const cache = 'stale-while-revalidate'

// Varie o cache com o parâmetro de página
export const cacheKey = (req: Request, ctx: AppContext) => {
const url = new URL(req.url)
return url.searchParams.get('page')
}

Neste exemplo, a função loader encapsula a lógica para buscar uma resposta paginada, enquanto a configuração cache garante caching stale-while-revalidate. A função cacheKey varia inteligentemente o cache com base no parâmetro page, permitindo uma estratégia de caching dinâmica e eficiente adaptada ao seu caso de uso específico.

Conclusão

Essas mudanças marcam o início de melhorias futuras tanto em desempenho quanto em observabilidade para sites construídos no deco.cx. Vamos começar a testar esse novo recurso e implementá-lo gradualmente para nossos clientes por padrão.

Para mais informações, confira o PR original no GitHub.