MST

星途 面试题库

面试题:Next.js动态路由数据驱动场景下的预渲染策略及优化

在使用Next.js动态路由构建数据驱动的应用时,页面可能需要在服务器端渲染(SSR)或静态站点生成(SSG)。请阐述在不同预渲染策略下,如何确保动态路由页面的数据及时更新,以及有哪些优化手段可以减少数据获取时间和提高页面加载速度。
23.6万 热度难度
前端开发Next.js

知识考点

AI 面试

面试题答案

一键面试

SSR 下确保数据及时更新及优化手段

  1. 确保数据及时更新
    • getServerSideProps 函数中进行数据获取。每次请求该页面时,此函数都会在服务器端运行,因此能获取到最新数据。例如,若从数据库获取数据,代码如下:
export async function getServerSideProps(context) {
    const { params } = context;
    const data = await fetch(`https://api.example.com/data/${params.id}`);
    const result = await data.json();
    return {
        props: {
            data: result
        }
    };
}
  • 若数据更新频率较高,可考虑在服务器端设置缓存机制。当数据有更新时,通过某种方式(如消息队列)通知服务器清除相关缓存,下次请求时获取最新数据。
  1. 优化手段
    • 数据缓存:如上述提到的服务器端缓存,减少重复数据库查询。可以使用诸如 Redis 之类的缓存工具,将常用数据存储在内存中,提高数据获取速度。
    • 优化数据库查询:确保数据库查询语句高效,例如添加合适的索引。若查询涉及多个表关联,优化表结构和查询逻辑,减少查询时间。
    • 代码优化:减少 getServerSideProps 中的不必要逻辑,将复杂计算提前处理或放到其他异步任务中,避免阻塞服务器响应。

SSG 下确保数据及时更新及优化手段

  1. 确保数据及时更新
    • 增量静态再生:使用 revalidate 选项。例如:
export async function getStaticProps(context) {
    const { params } = context;
    const data = await fetch(`https://api.example.com/data/${params.id}`);
    const result = await data.json();
    return {
        props: {
            data: result
        },
        revalidate: 60 // 每 60 秒重新生成一次页面
    };
}
  • 手动触发重新生成:对于重要数据更新,可通过 API 或管理界面手动触发页面重新生成。在 Next.js 12 及以上版本,可以使用 unstable_revalidateTag 功能。先定义标签:
export async function getStaticProps(context, { params }) {
    const data = await fetch(`https://api.example.com/data/${params.id}`);
    const result = await data.json();
    return {
        props: {
            data: result
        },
        revalidate: 60,
        tags: ['data -'+ params.id]
    };
}

然后在数据更新时,通过 API 调用触发重新生成:

// 在 API 处理函数中
import { unstable_revalidateTag } from 'next/cache';
export default async function handler(req, res) {
    // 更新数据逻辑
    await updateDataInDatabase();
    unstable_revalidateTag('data - 123'); // 假设 '123' 是具体的 id
    res.status(200).json({ message: 'Data updated and page revalidated' });
}
  1. 优化手段
    • 提前数据获取:在构建阶段尽可能并行获取数据。可以使用 Promise.all 同时发起多个 API 请求,减少整体数据获取时间。例如:
export async function getStaticProps(context) {
    const { params } = context;
    const [data1, data2] = await Promise.all([
        fetch(`https://api.example.com/data1/${params.id}`),
        fetch(`https://api.example.com/data2/${params.id}`)
    ]);
    const [result1, result2] = await Promise.all([data1.json(), data2.json()]);
    return {
        props: {
            data1: result1,
            data2: result2
        }
    };
}
  • CDN 缓存:利用 CDN 缓存静态文件,减少用户获取文件的时间。将生成的静态 HTML、CSS 和 JavaScript 文件分发到全球各地的 CDN 节点,使用户能从距离最近的节点获取资源。
  • 图片优化:对图片进行压缩和优化,使用现代图片格式(如 WebP)。Next.js 提供了 next/image 组件,它能自动优化图片加载,包括自适应图片尺寸、懒加载等。