利用Redis缓存使你的SSR网站速度提高42倍
让我们来看看如何利用Redis Cache与Node.JS和Express的关系:
Redis是一个主要作为数据库使用的内存存储。你可能听说过Redis,也听说过它有多酷,但从来没有过实际的使用案例。在本教程中,我将向你展示如何利用Redis来加速你的服务器端渲染(SSR)网络应用。如果你是Redis的新手,请查看我的安装Redis和创建键值对指南,以更好地了解它的工作原理。
在这篇文章中,我们将看看如何调整你的Node.JSExpress应用程序,以便利用Redis建立闪电般的缓存。
这样做的结果是相当戏剧性的。我能够将页面加载时间平均加快95%。
问题的背景
在Fjolt上,我使用Express在服务器上渲染网页并将其发送给用户。随着时间的推移,我增加了更多的功能,服务器渲染的复杂性也在增加--例如,我最近在代码示例中增加了行数,这需要在服务器上进行相当多的额外处理。服务器仍然是高速的,但随着更多复杂性的增加,服务器的计算有可能会花费越来越长的时间。
最终这意味着用户的页面加载时间会变慢,尤其是那些使用慢速3G连接的用户。我关注这个问题已经有一段时间了,因为我希望每个人都能快速享受阅读内容,也因为页面速度对SEO有重大影响。
当一个页面在Fjolt上加载时,我运行一个像这样的Express路线。
import express from 'express';
const articleRouter = express.Router();
// Get Singular Article
articleRouter.get(['/article/:articleName/', async function(req, res, next) {
// Process article
// A variable to store all of our processed HTML
let finalHtml = '';
// A lot more Javascript goes here
// ...
// Finally, send the Html file to the user
res.send(finalHtml);
});
每当有人加载一个页面时,文章就会被从头开始处理--而且所有的东西都是一次性处理。这意味着几个不同的数据库调用,一个。fs.readFile 函数和一些相当复杂的计算DOM操作来创建代码提示。这并不令人担心的复杂,但也意味着服务器要做大量的工作来处理多个页面上的多个用户。
在任何情况下,随着事情的扩大,这将成为一个规模越来越大的问题。幸运的是,我们可以使用Redis来缓存页面并立即显示给用户。
为什么使用Redis来缓存网页
使用Redis缓存可以将你的SSR网站从一个缓慢、笨重的庞然大物变成一个速度极快、反应灵敏的应用程序。当我们在服务器端渲染东西时,我们最终做了很多包装,但最终的产品是一样的--一个完整的HTML页面传递给用户。
SSR网站如何向用户提供内容
我们打包和处理响应的速度越快,用户的体验就越快。如果你有一个具有高进程负载的页面,意味着需要大量的处理来创建最终的、服务的页面,你有两个真正的选择。
- 开始删除进程并优化你的代码。这可能是一个漫长的过程,但会使服务器端的处理速度加快。
- 使用Redis,所以网页只在后台处理,而缓存的版本总是显示给用户。
说实话,你可能应该两者都做--但Redis提供了最快速的优化方式。当现实中没有多少优化可以做的时候,它也有帮助。
将 Redis 添加到你的 Express 路由中
首先,如果你的服务器或电脑上没有安装Redis,我们需要安装Redis。你可以在这里了解如何安装Redis。
接下来,通过运行以下命令在你的Node.JS项目中安装它。
npm i redis
现在我们已经启动并运行了,我们可以改变我们的Express Routes。还记得我们之前的路由是这样的吗?
import express from 'express';
const articleRouter = express.Router();
// Get Singular Article
articleRouter.get(['/article/:articleName/', async function(req, res, next) {
// Process article
// A variable to store all of our processed HTML
let finalHtml = '';
// A lot more Javascript goes here
// ...
// Finally, send the Html file to the user
res.send(finalHtml);
});
让我们加入Redis。
import express from 'express';
import { createClient } from 'redis';
const articleRouter = express.Router();
// Get Singular Article
articleRouter.get(['/article/:articleName/', async function(req, res, next) {
// Connect to Redis
const client = createClient();
client.on('error', (err) => console.log('Redis Client Error', err));
await client.connect();
const articleCache = await client.get(req.originalUrl);
const articleExpire = await client.get(`${req.originalUrl}-expire`);
// We use redis to cache all articles to speed up content delivery to user
// Parsed documents are stored in redis, and sent to the user immediately
// if they exist
if(articleCache !== null) {
res.send(articleCache);
}
if(articleCache == null && articleExpire == null || articleExpire < new Date().getTime()) {
// A variable to store all of our processed HTML
let finalHtml = '';
// A lot more Javascript goes here
// ...
// Finally, send the Html file to the user
if(articleCache == null) {
res.send(mainFile);
}
// We update every 10 seconds.. so content always remains roughly in sync.
// So this not only increases speed to user, but also decreases server load
await client.set(req.originalUrl, mainFile);
await client.set(`${req.originalUrl}-expire`, new Date().getTime() + (10 * 1000));
}
});
我们在这里做的改动并不复杂。在我们的代码中,我们只需要设置两个Redis键--一个用来存储页面的缓存HTML内容,另一个用来存储过期日期,这样我们就可以确保内容是持续更新的。
代码总结
让我们更详细地了解一下代码:
- 首先,导入Redis,以便它可以通过createClient使用。
- 每当用户访问我们的文章端点时,我们会加载Redis,而不是直接跳转到解析和显示文章。
- 我们在Redis数据库中检查两个键(
await client.get('key-name'))。一个键是req.currentUrl。例如,这个页面可能是/article/redis-caching-ssr-site-nodejs。另一个是过期,存储在,即。/article/redis-caching-ssr-site-nodejs-expire - 如果我们的文章存在一个缓存版本,我们立即将其发送给用户--导致闪电般快速的页面加载。然而,如果这是第一次有人访问这个页面,或者过期的密钥已经过期,我们就必须对文章进行长期解析。
- 你可能认为这意味着每隔10秒就得长距离加载页面--但事实并非如此,如果存在缓存版本,用户将始终被发送,但我们会每隔10秒更新一次缓存,以便提供最新内容。这种更新对用户的加载时间没有影响。因此,唯一会出现加载缓慢的情况是,这个页面以前从未被访问过。此外,由于我们使用URL来存储数据,我们可以肯定,独特的路由将在我们的Redis数据库中针对它们存储个别数据。最终,这使得我的网站的第一个字节的时间(TTFB)提高了95%,如顶部的图片所示。
注意事项和结论
由于我的路线变得过于复杂,这里节省的时间是相当多的。当然,如果你的路线不是超级复杂,你节省的时间可能会少一些。但是,使用这种方法,你仍然有可能获得相当大的速度提升。
这个例子证明了一个简单的变化可以对任何SSR网站产生巨大的性能影响,而且是Redis的一个很好的使用案例,显示了它可以有多么强大。我希望你发现这对你有帮助,并找到在你的网站和应用程序中使用它的方法。
经Johnny Simpson, DZone MVB许可发表于DZone。请看原文。