next-boost ajoute une couche de cache à vos applications SSR (rendu côté serveur). Il a été construit à l'origine pour Next.js et devrait fonctionner avec n'importe quelle application basée sur Node.js http.Server .
next-boost atteint de grandes performances en rendant les pages Web sur worker_threads tout en servant la mise en cache sur le fil principal.
Si vous connaissez Next.js , next-boost peut être considéré comme une implémentation de la régénération statique incrémentale qui fonctionne avec getServerSideProps . Et il n'est pas destiné à être utilisé avec getStaticProps , dans lequel Next.js fera le cache pour vous.
$ 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 pour SSR.next-boost.redis.js pour une configuration d'échantillon.next-boost.hdc.js pour une configuration d'échantillon next-boost avec Next.js Après installer le package, modifiez simplement le script de démarrage du next start à next-boost . Tous les arguments de ligne de commande de next start , comme -p pour spécifier le port, sont compatibles.
"scripts": {
...
"start": "next-boost", // previously `next start`
...
},
Il y a un exemple sous examples/nodejs , qui fonctionne avec un http.Server ordinaire.
Pour l'utiliser avec express.js et next.js , veuillez vérifier examples/with-express .
En utilisant worker_threads , le rendu SSR lourds du CPU ne bloquera pas le processus principal de servir le cache.
Voici la comparaison de l'utilisation ApacheBench sur un article de blog obtenu à partir de la base de données. HTML préendué et l'opération DB prend environ 10 ~ 20 ms. La page prend environ 200 ms pour que Next.js rende.
$ /usr/local/bin/ab -n 200 -c 8 http://127.0.0.1:3000/blog/posts/2020/3/postnamePas une référence scientifique, mais les améliorations sont visiblement énormes.
avec next start (données obtenues avec 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
avec la CLI à bout de pas next-boost :
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
Il surpasse même la page générée statique de Next.js ( getStaticProps ), gérant 2 ~ 2,5x demandes par seconde dans mon environnement.
next-boost implémente un cache côté serveur à la manière de révalider l'emploi. Lorsqu'une page expirée ( stale ) est accessible, le cache sera servi et en même temps, un processus d'arrière-plan rapportera la dernière version ( revalidate ) de cette page et l'enregistrera dans le cache.
La configuration suivante mettra en cache les uris correspondant ^/blog.* . Seules rules de correspondance des pages seront gérées par next-boost et il n'y a pas de règles exclude .
module . exports = {
rules : [ { regex : '^/blog.*' , ttl : 300 } ] ,
}Il y a 2 paramètres pour contrôler le comportement du cache:
ttl (time-to-live) : Après ttl secondes, le cache sera révalidé. Et ttl d'une page en cache sera mis à jour lorsqu'une page sera revalidée.tbd (time-before-deletion) : Lorsqu'une page n'est plus frappée en ttl + tbd secondes, elle sera complètement supprimée du cache. Ci-dessus: seules les pages de mise en cache avec URL commencent par /blog .
En envoyant un GET avec l'en-tête x-next-boost:update de l'URL, le cache sera révalidé. Et si la page n'existe plus, le cache sera supprimé.
$ curl -H x-next-boost:update https://the_server_name.com/path_aSi vous souhaitez supprimer les pages mutiles à la fois, vous pouvez exécuter SQL sur le cache directement:
sqlite3 /cache_path/cache.db " update cache set ttl=0 where key like '%/url/a%'; " Cela obligera toutes les URL contenant /url/a pour être révalidées la prochaine fois.
La suppression de cache_path supprimera tous les caches.
Par défaut, chaque page avec différentes URL sera mise en cache séparément. Mais dans certains cas, vous aimeriez, /path_a?utm_source=twitter pour être servi avec le même contenu de /path_a . paramFilter est pour filtrer les paramètres de requête.
// in .next-boost.js
{
...
paramFilter : ( p ) = > p !== 'utm_source'
}Par défaut, l'URL sera utilisée comme clé pour les pages mises en cache. Si vous souhaitez servir des pages à partir de différents domaines ou par différents agents utilisateur, vous pouvez utiliser cette fonction pour personnaliser la touche de cache.
Notes:
string , votre serveur se bloquera. // in .next-boost.js
{
...
cacheKey : ( req ) = > ( req . headers . host || '' ) + ':' + req . url
}Alternativement, vous pouvez fournir une fonction au lieu du tableau à l'intérieur de votre configuration.
// in .next-boost.js
{
...
rules : ( req ) = > {
if ( req . url . startsWith ( '/blog' ) ) {
return 300
}
}
} La fonction doit renvoyer ttl valide pour la demande. Si la fonction renvoie 0 ou la valeur falsy , la demande ne sera pas mise en cache.
La puissance qui vient de cette méthode est que vous pouvez décider si la demande est mise en cache ou pas plus dynamiquement.
Par exemple, vous pouvez ignorer automatiquement toutes les demandes des utilisateurs authentifiés en fonction de l'en-tête:
// in .next-boost.js
{
...
rules : ( req ) = > {
if ( req . headers . authorization ) {
return false
}
return 10 // cache all other requests for 10 seconds
}
}Vous pouvez également obtenir des règles plus complexes plus facilement que via Regex. Par exemple, vous souhaitez différents TTL pour chacune des pages de pagination.
// 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
}
}Bien que vous ayez besoin d'écrire une règle regex complexe ou potentiellement plus de règles, il est facile de le faire via JS Logic.
En fin de compte, si vous préférez l'écriture de regex mais souhaitez tirer parti de la logique JS, vous pouvez toujours faire correspondre Regex dans un gestionnaire de règles.
Si disponible, .next-boost.js à la racine du projet sera utilisé. Si vous utilisez le prochain boost par programme, le nom de fichier peut être modifié dans les options que vous avez transmises à CachedHandler .
Conseils: Si vous utilisez CLI next-boost avec next.js, vous souhaiterez peut-être utiliser le fichier de configuration.
Et voici un exemple .next-boost.sample.js dans le référentiel.
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 La journalisation est activée par défaut. Si vous utilisez next-boost par programme, vous pouvez désactiver les journaux en passant le drapeau booléen quiet en option pour CachedHandler .
...
const cached = await CachedHandler ( args , { quiet : true } ) ;
... Il y a aussi un drapeau --quiet si vous utilisez la ligne de commande.
next-boost est limité. Jusqu'à ce que l'URL soit touchée sur chaque serveur backend, il peut toujours manquer le cache. Utilisez le proxy inversé avec la prise en charge du cache (Nginx, Varnish, etc.) pour cela.GET les demandes et les demandes HEAD .worker_threads est utilisé et il s'agit d'une fonctionnalité Node.js 12+. next-boost fonctionne comme un remplacement sur place pour next start en utilisant la fonction de serveur personnalisé de next.js.
Sur la page liée ci-dessus, vous pouvez voir l'avis suivant:
Avant de décider d'utiliser un serveur personnalisé, veuillez garder à l'esprit qu'il ne doit être utilisé que lorsque le routeur intégré de next.js ne peut pas répondre aux exigences de votre application. Un serveur personnalisé supprimera des optimisations de performances importantes, comme les fonctions sans serveur et l'optimisation statique automatique.
Le prochain boost est destiné à être utilisé sur les VP ou les conteneurs Cloud, donc la fonction sans serveur n'est pas un problème ici. Quant à Automatic Static Optimization , parce que nous ne faisons aucune app.render ici, cela fonctionne toujours, aussi parfait que toujours.
Voici l'article sur le moment de ne pas utiliser SQLite. Et pour le principal butin de Next-boost: SSR super plus rapide sur les VPS à faible coût, pour autant que je sache, c'est le meilleur choix.
Mit. Copyright 2020 Rakuraku Jyo.