面试题答案
一键面试可能出现的性能问题
- 白屏时间延长:从CSR页面导航到SSR页面时,由于SSR页面需要在服务器端渲染并传输到客户端,可能导致页面出现一段空白时间,影响用户体验。
- 闪烁问题:从SSR页面导航到CSR页面时,可能会出现页面内容先以SSR渲染的形式显示,然后又重新以CSR的方式渲染,造成内容闪烁。
优化方案
- 代码分割与预加载
- 实现思路:对于CSR页面,使用Next.js的动态导入(Dynamic Imports)进行代码分割,只在需要时加载相关代码。对于从CSR导航到SSR页面的情况,可以在CSR页面中提前预加载SSR页面所需的资源。例如,在CSR页面的
useEffect
钩子中使用next/link
的prefetch
方法。
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;
- 实现思路:对于CSR页面,使用Next.js的动态导入(Dynamic Imports)进行代码分割,只在需要时加载相关代码。对于从CSR导航到SSR页面的情况,可以在CSR页面中提前预加载SSR页面所需的资源。例如,在CSR页面的
- 静态化与缓存
- 实现思路:对于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;
- 实现思路:对于SSR页面,尽可能使用