MST

星途 面试题库

面试题:优化 Next.js 路由系统中客户端与服务端渲染切换时的性能

假设在一个 Next.js 应用中,部分页面采用客户端渲染,部分页面采用服务端渲染,在用户从 CSR 页面导航到 SSR 页面,或反之的过程中,可能会出现哪些性能问题?请提出至少两种优化方案,并详细说明实现思路。
26.8万 热度难度
前端开发Next.js

知识考点

AI 面试

面试题答案

一键面试

可能出现的性能问题

  1. 白屏时间延长:从CSR页面导航到SSR页面时,由于SSR页面需要在服务器端渲染并传输到客户端,可能导致页面出现一段空白时间,影响用户体验。
  2. 闪烁问题:从SSR页面导航到CSR页面时,可能会出现页面内容先以SSR渲染的形式显示,然后又重新以CSR的方式渲染,造成内容闪烁。

优化方案

  1. 代码分割与预加载
    • 实现思路:对于CSR页面,使用Next.js的动态导入(Dynamic Imports)进行代码分割,只在需要时加载相关代码。对于从CSR导航到SSR页面的情况,可以在CSR页面中提前预加载SSR页面所需的资源。例如,在CSR页面的 useEffect 钩子中使用 next/linkprefetch 方法。
    import Link from 'next/link';
    import { useEffect } from'react';
    
    const CSRPage = () => {
      useEffect(() => {
        Link.prefetch('/ssr-page');
      }, []);
    
      return (
        <div>
          <Link href="/ssr-page">Go to SSR Page</Link>
        </div>
      );
    };
    
    export default CSRPage;
    
  2. 静态化与缓存
    • 实现思路:对于SSR页面,尽可能使用 getStaticProps 进行静态生成,这样页面可以在构建时生成静态HTML文件,提高加载速度。同时,可以利用CDN缓存SSR页面的静态资源,减少重复请求。在从SSR导航到CSR页面时,CSR页面也可以缓存一些不变的数据,避免重复获取。例如,在CSR页面的 useEffect 钩子中检查本地缓存,如果有数据则直接使用,否则再发起请求。
    import { useEffect, useState } from'react';
    
    const CSRPage = () => {
      const [data, setData] = useState(null);
    
      useEffect(() => {
        const cachedData = localStorage.getItem('csr - data');
        if (cachedData) {
          setData(JSON.parse(cachedData));
        } else {
          // 发起数据请求
          fetch('/api/data')
          .then(response => response.json())
          .then(result => {
              setData(result);
              localStorage.setItem('csr - data', JSON.stringify(result));
            });
        }
      }, []);
    
      return (
        <div>
          {data && <p>{data.message}</p>}
        </div>
      );
    };
    
    export default CSRPage;