使用Redis加速Next.js

21-05-23 banq

Next.js是一个非常成功的Web框架,它将服务器端渲染和静态站点生成结合在一起。通过CDN缓存,服务器端渲染SSG可以加快您的网站速度,同时SSR可以帮助您处理SEO和动态数据。

服务器端渲染是一项出色的功能,可帮助您编写全栈应用程序。但是,如果您不小心,则很容易影响Next.js网站的性能。在此博客文章中,我将解释如何利用Redis加快Next.js API调用的速度。在此之前,我将简要地介绍一种提高性能的简单方法。

SWR是一个非常智能的数据提取库。它使用HTTP RFC 5861描述的HTTP缓存无效策略(失效时重新验证)。当您使用SWR调用API时,它会立即返回缓存的数据,但会异步获取当前数据并更新您的UI。您还可以根据您对陈旧性的容忍度设置refreshInterval。

{ data: user } = useSWR(‘/api/user’, { refreshInterval: 2000 })

在上面的代码中,用户API将每2秒刷新一次。

SWR非常简单有效。但是在某些情况下,您将需要服务器端缓存:

  • 客户端缓存提高了客户端的性能。但是,如果客户端数量很多,则服务器端资源可能会承受高负载,这最终也会影响客户端性能。
  • 如果您使用具有配额的外部API,则需要在服务器端控制API的使用。否则,太多的客户端将迅速使用该API。
  • 如果您使用动态输入在服务器端计算,获取或处理了资源,则客户端缓存将不是很有用。

 

示例项目:Covid Tracker:

在此项目中,我们将使用Javier Aviles的Covid API并找到案例数最多的前10个国家/地区。检查网站源代码

我们将使用Redis缓存来自Covid API的响应,因此:

  • 响应将更快。如果您访问该网站,则会看到调用Covid API的时间为数百毫秒,而从Redis进行的获取则为1-2毫秒。
  • 我们不会因太多请求而压倒Covid API。

 

API代码

API代码首先检查我们是否在Redis中缓存了API结果。否则,我们将从Covid API中获取所有国家/地区列表,并按当日的病例数对它们进行排序,然后将前10名保存到Redis。保存到Redis时,我们设置“ EX” 60参数,这意味着Redis将在60秒内删除该条目。

import Redis from 'ioredis'

let redis = new Redis(process.env.REDIS_URL)

export default async (req, res) => {
   let start = Date.now();
   let cache = await redis.get("cache")
   cache = JSON.parse(cache)
   let result = {}
   if (cache) {
       console.log("loading from cache")
       result.data = cache
       result.type = "redis"
       result.latency = Date.now() - start;
       return res.status(200).json(result)
   } else {
       console.log("loading from api")
       start = Date.now();
       return fetch('https://coronavirus-19-api.herokuapp.com/countries')
           .then(r => r.json())
           .then(data => {
               data.sort(function (a, b) {
                   return b.todayCases - a.todayCases;
               });
               result.data = data.splice(1, 11)
               result.type = "api"
               result.latency = Date.now() - start;
               redis.set("cache", JSON.stringify(result.data), "EX", 60)
               return res.status(200).json(result)
           })
   }
}

 

猜你喜欢