next-boost adiciona uma camada de cache aos seus aplicativos SSR (renderização do lado do servidor). Foi construído originalmente para Next.js e deve funcionar com qualquer aplicativo baseado em node.js http.Server .
next-boost alcança ótimo desempenho, renderizando páginas da web em worker_threads enquanto servem o cache no thread principal.
Se você estiver familiarizado com Next.js , next-boost pode ser considerado como uma implementação de regeneração estática incremental que funciona com getServerSideProps . E não deve ser usado com getStaticProps , no qual o Next.js fará o cache para você.
$ yarn add @next-boost/next-boost
$ yarn add @next-boost/redis-cache # using load-balancer and cluster
$ yarn add @next-boost/hybrid-disk-cache # simple site with disk cache next startworker_threads para SSR.next-boost.redis.js para configuração de amostra.next-boost.hdc.js para configuração de amostra next-boost com o próximo.js Após a instalação do pacote, basta alterar o script inicial do next start para next-boost . Todos os argumentos da linha de comando do next start , como -p para especificar a porta, são compatíveis.
"scripts": {
...
"start": "next-boost", // previously `next start`
...
},
Há um exemplo em examples/nodejs , que funciona com um http.Server simples.
Para usá-lo com express.js e next.js , verifique examples/with-express .
Ao usar worker_threads , a renderização SSR pesada da CPU não bloqueará o processo principal de servir o cache.
Aqui está a comparação do uso ApacheBench em uma postagem de blog buscada no banco de dados. O HTML pré -renderizado e a operação de banco de dados leva cerca de 10 ~ 20ms. A página leva cerca de 200ms para o Next.js renderizar.
$ /usr/local/bin/ab -n 200 -c 8 http://127.0.0.1:3000/blog/posts/2020/3/postnameNão é uma referência científica, mas as melhorias são visivelmente enormes.
Com next start (dados buscados com getServerSideProps ):
Document Length: 76424 bytes
Concurrency Level: 8
Time taken for tests: 41.855 seconds
Complete requests: 200
Failed requests: 0
Total transferred: 15325600 bytes
HTML transferred: 15284800 bytes
Requests per second: 4.78 [#/sec] (mean)
Time per request: 1674.185 [ms] (mean)
Time per request: 209.273 [ms] (mean, across all concurrent requests)
Transfer rate: 357.58 [Kbytes/sec] received
Com a CLI next-boost volante:
Document Length: 78557 bytes
Concurrency Level: 8
Time taken for tests: 0.149 seconds
Complete requests: 200
Failed requests: 0
Total transferred: 15747600 bytes
HTML transferred: 15711400 bytes
Requests per second: 1340.48 [#/sec] (mean)
Time per request: 5.968 [ms] (mean)
Time per request: 0.746 [ms] (mean, across all concurrent requests)
Transfer rate: 103073.16 [Kbytes/sec] received
Ele ainda supera a página estática gerada por Next.JS ( getStaticProps ), lidando com 2 ~ 2,5x solicitações por segundos no meu ambiente.
next-boost implementa um cache do lado do servidor na maneira de revalidados obsoletos-while. Quando uma página expirada ( stale ) for acessada, o cache será servido e, ao mesmo tempo, um processo em segundo plano buscará a versão mais recente ( revalidate ) dessa página e a salvará no cache.
A seguinte configuração cache os URIs correspondentes ^/blog.* . Somente rules de correspondência das páginas serão tratadas pelo next-boost e não há regras exclude .
module . exports = {
rules : [ { regex : '^/blog.*' , ttl : 300 } ] ,
}Existem 2 parâmetros para controlar o comportamento do cache:
ttl (time-to-live) : Após ttl segundos, o cache será reavalidado. E o ttl de uma página em cache será atualizado quando uma página for revalidada.tbd (time-before-deletion) : Quando uma página não é atingida novamente em ttl + tbd segundos, ela será removida completamente do cache. Acima: Apenas páginas de armazenamento em cache com URL começam com /blog .
Ao enviar uma obtenção com o cabeçalho x-next-boost:update para o URL, o cache será revalidado. E se a página não existir mais, o cache será excluído.
$ curl -H x-next-boost:update https://the_server_name.com/path_aSe você deseja excluir as páginas Mutiple de uma só vez, poderá executar o SQL no cache diretamente:
sqlite3 /cache_path/cache.db " update cache set ttl=0 where key like '%/url/a%'; " Isso forçará todos os URLs que contêm /url/a a serem reavalidados na próxima vez.
A exclusão de cache_path removerá todos os caches.
Por padrão, cada página com URLs diferentes será armazenada em cache separadamente. Mas, em alguns casos, você gostaria, /path_a?utm_source=twitter a ser servido com o mesmo conteúdo de /path_a . paramFilter é para filtrar os parâmetros de consulta.
// in .next-boost.js
{
...
paramFilter : ( p ) = > p !== 'utm_source'
}Por padrão, o URL será usado como chave para páginas em cache. Se você deseja que as páginas de servidores de diferentes domínios ou por agente de usuário diferentes, poderá usar essa função para personalizar a tecla de cache.
Notas:
string , seu servidor falhará. // in .next-boost.js
{
...
cacheKey : ( req ) = > ( req . headers . host || '' ) + ':' + req . url
}Como alternativa, você pode fornecer uma função em vez de matriz dentro da sua configuração.
// in .next-boost.js
{
...
rules : ( req ) = > {
if ( req . url . startsWith ( '/blog' ) ) {
return 300
}
}
} A função deve retornar ttl válido para a solicitação. Se a função retornar 0 ou valor falsy a solicitação não será armazenada em cache.
O poder que vem desse método é que você pode decidir se a solicitação está em cache ou não mais dinamicamente.
Por exemplo, você pode ignorar automaticamente toda a solicitação de usuários autenticados com base no cabeçalho:
// in .next-boost.js
{
...
rules : ( req ) = > {
if ( req . headers . authorization ) {
return false
}
return 10 // cache all other requests for 10 seconds
}
}Você também pode obter regras mais complexas com mais facilidade do que através do Regex. Por exemplo, você deseja diferentes TTL para cada uma das páginas de paginação.
// in .next-boost.js
{
...
rules : ( req ) = > {
const [ , p1 ] = url . split ( '?' , 2 )
const params = new URLSearchParams ( p1 )
return {
1 : 5000 ,
2 : 4000 ,
3 : 3000 ,
4 : 2000
} [ params . get ( 'page' ) ] || 1000
}
}Embora você precise escrever uma regra Regex complexa ou potencialmente mais regras, é fácil fazê -lo através da lógica JS.
No final, se você preferir escrever regex, mas deseja aproveitar a lógica JS, você sempre pode corresponder a um manipulador de regras.
Se disponível, .next-boost.js no Project Root será usado. Se você usar programaticamente, o nome do arquivo, o nome do arquivo poderá ser alterado nas opções que você passou para CachedHandler .
Dicas: Se você estiver usando a CLI next-boost com o Next.js, convém usar o arquivo de configuração.
E aqui está um exemplo .next-boost.sample.js no repo.
interface HandlerConfig {
filename ?: string
quiet ?: boolean
cache ?: {
ttl ?: number
tbd ?: number
path ?: string
}
rules ?: Array < URLCacheRule > | URLCacheRuleResolver
paramFilter ?: ParamFilter
cacheKey ?: CacheKeyBuilder
}
interface URLCacheRule {
regex : string
ttl : number
}
type URLCacheRuleResolver = ( req : IncomingMessage ) => number
type ParamFilter = ( param : string ) => boolean
type CacheKeyBuilder = ( req : IncomingMessage ) => string O log é ativado por padrão. Se você usar programaticamente next-boost , poderá desativar os logs passando a sinalização quiet da bandeira booleana como uma opção para CachedHandler .
...
const cached = await CachedHandler ( args , { quiet : true } ) ;
... Há também um sinalizador --quiet você estiver usando a linha de comando.
next-boost é limitado. Até que o URL seja atingido em todos os servidores de back -end, ele ainda pode perder o cache. Use proxy reverso com suporte ao cache (nginx, verniz etc.) para isso.GET apenas solicitações HEAD .worker_threads é usado e é um recurso Node.js 12+. next-boost funciona como uma substituição no local para next start usando o recurso de servidor personalizado do Next.JS.
Na página vinculada acima, você pode ver o seguinte aviso:
Antes de decidir usar um servidor personalizado, lembre -se de que ele só deve ser usado quando o roteador integrado do Next.js não puder atender aos seus requisitos de aplicativo. Um servidor personalizado removerá otimizações importantes de desempenho, como funções sem servidor e otimização estática automática.
O Next-Boost deve ser usado em VPs ou contêineres em nuvem, para que a função sem servidor não seja um problema aqui. Quanto à Automatic Static Optimization , porque não estamos fazendo nenhum app.render aqui, ele ainda funciona, tão perfeito como sempre.
Aqui está o artigo sobre quando não usar o SQLite. E para o objetivo principal do próximo Boost: SSR super mais rápido em VPSs de baixo custo, até onde eu sei, é a melhor escolha.
Mit. Copyright 2020 Rakuraku Jyo.