Next.js là một khung công tác web rất thành công, kết hợp kết xuất phía máy chủ và tạo trang web tĩnh. SSG tăng tốc trang web của bạn nhờ bộ nhớ đệm CDN trong khi SSR giúp bạn SEO và dữ liệu động.
Kết xuất phía máy chủ là một tính năng tuyệt vời giúp bạn viết các ứng dụng ngăn xếp đầy đủ. Nhưng nếu bạn không cẩn thận, hiệu suất của trang web Next.js của bạn có thể bị ảnh hưởng một cách dễ dàng. Trong bài đăng trên blog này, tôi sẽ giải thích cách tận dụng Redis để tăng tốc các lệnh gọi API Next.js của bạn. Trước đó, tôi sẽ đề cập ngắn gọn đến một cách đơn giản hơn để cải thiện hiệu suất của bạn.
Sử dụng SWR trong các lệnh gọi API của bạn
SWR là một thư viện tìm nạp dữ liệu rất thông minh. Nó sử dụng chiến lược vô hiệu hóa bộ nhớ cache HTTP (stale-while-revalidate) được mô tả bởi HTTP RFC 5861. Khi bạn gọi một API bằng SWR, nó ngay lập tức trả về dữ liệu đã lưu trong bộ nhớ cache nhưng không đồng bộ nó tìm nạp dữ liệu hiện tại và cập nhật giao diện người dùng của bạn. Bạn cũng có thể đặt refreshInterval tùy thuộc vào khả năng chịu đựng của bạn đối với sự bền bỉ.
const { data: user } = useSWR('/api/user', { refreshInterval: 2000 })
Trong đoạn mã trên, API người dùng sẽ được làm mới sau mỗi 2 giây.
Lưu vào bộ nhớ đệm với Redis
SWR rất đơn giản và hiệu quả. Nhưng có những trường hợp bạn sẽ cần bộ nhớ đệm phía máy chủ:
- Bộ nhớ đệm phía máy khách cải thiện hiệu suất cho máy khách. Nhưng nếu số lượng máy khách nhiều, bạn có thể gặp phải tải cao đối với tài nguyên phía máy chủ, điều này cuối cùng sẽ ảnh hưởng đến hiệu suất phía máy khách.
- Nếu bạn đang sử dụng API bên ngoài với hạn ngạch, bạn sẽ muốn kiểm soát việc sử dụng API ở phía máy chủ. Nếu không, quá nhiều khách hàng sẽ sử dụng API nhanh chóng.
- Nếu bạn có tài nguyên được tính toán, tìm nạp hoặc xử lý ở phía máy chủ bằng cách sử dụng đầu vào động, thì bộ nhớ đệm phía máy khách sẽ không hữu ích lắm.
Dự án mẫu:Covid Tracker
Trong dự án này, chúng tôi sẽ sử dụng Javier Aviles ’Covid API và tìm ra 10 quốc gia hàng đầu có số trường hợp mắc bệnh nhiều nhất. Kiểm tra trang web và mã nguồn.
Chúng tôi sẽ sử dụng Redis để lưu vào bộ nhớ cache các phản hồi từ Covid API, do đó:
- Phản hồi sẽ nhanh hơn nhiều. Nếu kiểm tra trang web, bạn sẽ thấy việc gọi API Covid là hàng trăm mili giây trong khi tìm nạp từ Redis là 1-2 mili giây.
- Chúng tôi sẽ không áp đảo API Covid với quá nhiều yêu cầu.
Mã API
Đầu tiên, mã sẽ kiểm tra xem chúng tôi có kết quả API được lưu trong bộ nhớ cache trong Redis hay không. Nếu không, chúng tôi sẽ lấy danh sách tất cả các quốc gia từ API Covid và sắp xếp chúng theo số trường hợp trong ngày hiện tại và lưu 10 trường hợp hàng đầu vào Redis. Trong khi lưu vào Redis, chúng tôi đặt thông số "EX" 60 có nghĩa là Redis sẽ loại bỏ mục nhập sau 60 giây.
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);
});
}
};
Mã giao diện người dùng
Giao diện người dùng là một mã React đơn giản. Chúng tôi tìm nạp dữ liệu từ API bằng SWR.
export default function Home() {
function refresh(e) {
e.preventDefault();
window.location.reload();
}
const { data, error } = useSWR("api/data", fetcher);
if (error) return "An error has occurred.";
if (!data) return "Loading...";
return (
<div className={styles.container}>
<Head>
<title>Covid Tracker</title>
<meta name="description" content="Generated by create next app" />
<link rel="icon" href="/favicon.ico" />
</Head>
<main className={styles.main}>
<h1 className={styles.title}>Covid Tracker</h1>
<p className={styles.description}>
Top 10 countries with the most cases today
</p>
<div className={styles.grid}>
<div className={styles.card} onClick={refresh}>
<table className={styles.table}>
<thead>
<tr>
<th>Country</th>
<th>Today Cases</th>
<th>Today Deaths</th>
</tr>
</thead>
<tbody>
{data.data.map((item) => (
<tr>
<td>{item.country}</td>
<td>{item.todayCases}</td>
<td>{item.todayDeaths}</td>
</tr>
))}
</tbody>
</table>
<br />
<em>
Loaded from {data.type} in <b>{data.latency}</b> milliseconds.
Click to reload.
</em>
</div>
</div>
</main>
<footer className={styles.footer}>
This is a sample project for the blogpost
<a
href="https://blog.upstash.com/nextjs-caching-with-redis"
target="_blank"
rel="noopener noreferrer"
>
Speed up your Next.js application using Serverless Redis for caching.
</a>
</footer>
</div>
);
}
Liên kết Bên ngoài
https://swr.vercel.app/docs/with-nextjs
https://brianlovin.com/writing/caching-api-routes-with-next-js
https://coronavirus-19-api.herokuapp.com/countries
https://github.com/javieraviles/covidAPI