MST

星途 面试题库

面试题:Next.js动态路由参数验证在SSR和SSG场景下的差异与优化

对于Next.js的动态路由参数验证,在服务器端渲染(SSR)和静态站点生成(SSG)两种场景下,有哪些不同点需要注意?例如,在参数验证逻辑处理、性能优化以及缓存方面,怎样针对这两种场景进行针对性调整?请详细阐述并给出示例代码或优化策略。
12.1万 热度难度
前端开发Next.js

知识考点

AI 面试

面试题答案

一键面试

参数验证逻辑处理

  • SSR(服务器端渲染)
    • 在SSR场景下,参数验证可以在服务器端请求处理阶段进行。通常在页面的getServerSideProps函数中验证动态路由参数。因为是在服务器端执行,可直接访问后端资源进行复杂验证,如数据库查询验证参数是否存在。
    • 示例代码:
export async function getServerSideProps(context) {
    const { param } = context.query;
    if (!param || typeof param!=='string') {
        return {
            notFound: true
        };
    }
    // 假设这里根据param查询数据库验证
    const isValid = await checkParamInDatabase(param);
    if (!isValid) {
        return {
            notFound: true
        };
    }
    return {
        props: {
            param
        }
    };
}

function Page({ param }) {
    return <div>{param}</div>;
}

export default Page;
  • SSG(静态站点生成)
    • 在SSG场景中,参数验证主要在构建时进行。在getStaticProps函数和getStaticPaths函数中验证参数。由于构建后页面为静态,无法在运行时根据后端数据动态验证,需在构建前确保参数有效。
    • 示例代码:
export async function getStaticPaths() {
    const validParams = await getAllValidParamsFromDatabase();
    const paths = validParams.map(param => ({
        params: { param }
    }));
    return { paths, fallback: false };
}

export async function getStaticProps(context) {
    const { param } = context.params;
    if (!param || typeof param!=='string') {
        return {
            notFound: true
        };
    }
    return {
        props: {
            param
        }
    };
}

function Page({ param }) {
    return <div>{param}</div>;
}

export default Page;

性能优化

  • SSR
    • 避免在getServerSideProps中进行不必要的数据库查询或复杂计算,因为每次请求都执行此函数。可以使用缓存策略(如内存缓存)来存储常用数据,减少重复查询。
    • 例如,在Node.js中使用lru - cache库:
const LRU = require('lru - cache');
const cache = new LRU({
    max: 100,
    maxAge: 1000 * 60 * 5 // 5分钟
});

export async function getServerSideProps(context) {
    const { param } = context.query;
    let data = cache.get(param);
    if (!data) {
        data = await fetchDataFromDatabase(param);
        cache.set(param, data);
    }
    return {
        props: {
            data
        }
    };
}
  • SSG
    • 利用构建时生成静态页面的优势,减少运行时计算。提前在构建前处理好所有可能的数据,尽量减少fallbacktrue的情况,因为这可能导致运行时生成页面,失去SSG性能优势。
    • 例如,提前在构建时处理好复杂的聚合数据:
export async function getStaticProps() {
    const allData = await getAllDataFromDatabase();
    const aggregatedData = processAllData(allData);
    return {
        props: {
            aggregatedData
        }
    };
}

缓存方面

  • SSR
    • 服务器端缓存可以在不同请求间共享数据,减轻数据库压力。如上述lru - cache的应用,也可使用Redis等分布式缓存。但要注意缓存更新策略,避免脏数据。
    • 例如,在数据更新时清除相关缓存:
async function updateDataInDatabase(newData) {
    await databaseUpdate(newData);
    cache.del(newData.param);
}
  • SSG
    • SSG生成的静态页面本身就是一种缓存。可通过设置HTTP缓存头(如Cache - Control)进一步优化缓存。对于动态数据,可使用增量静态再生(Incremental Static Regeneration),在一定时间后自动重新生成页面。
    • 示例,在getStaticProps中设置增量静态再生:
export async function getStaticProps() {
    const data = await getDataFromDatabase();
    return {
        props: {
            data
        },
        revalidate: 60 * 60 * 24 // 每天重新生成一次
    };
}