跳转至

渲染模式

Rendering

Dynamic Rendering

SSR

  • 分块
    • RSC Payload(Server Components):在客户端更新DOM
    • Client Components
  • Hydration:React's process for attaching event handlers to the DOM, to make the static HTML interactive.

PPR(Partial Prerendering)

  • https://nextjs.org/docs/app/getting-started/partial-prerendering

Static Site Generation

  • https://nextjs.org/docs/app/guides/static-exports
  • prerender页面为html,输出在.next\server\app,就是一个路由缓存,路径也就是路由
  • 需要进行prerender的必须是SSC
    • generateStaticParams:返回页面的参数集合,即写死param,可以用fetch等api获取外部数据
    • 在App Route版本中,SSC直接调用fetch等api来获取数据
  • trailingSlash:是否保留末尾斜杠,nextjs配置,默认false
    • false:生成路径/posts/list/posts/list.html
    • true:生成路径/posts/list//posts/list/index.html
      • 推荐设置这个,这样就不需要对静态服务器进行额外配置了
  • 路由:很像SPA,但是实际不是

Static Export

  • 所谓静态导出其实就是直接进行一次服务端渲染,进行输出多个HTML以及JS、CSS等文件

Cache

Mechanism What Where Purpose Duration
Request Memoization Return values of functions Server Re-use data in a React Component tree Per-request lifecycle
Data Cache Data Server Store data across user requests and deployments Persistent (can be revalidated)
Full Route Cache HTML and RSC payload Server Reduce rendering cost and improve performance Persistent (can be revalidated)
Router Cache RSC Payload Client Reduce server requests on navigation User session or time-based
  • Cache API
    • fetch是一种扩展,可以设置选项next.revalidate(秒)和tags如果需要自定义缓存函数,使用unstable_cache
    • Request Memoization、Data Cache就是是2种使用情况
  • Full Route Cache其实就是PPR、SSG
    • 与Static Export不同,这个是SSR模式的,更新缓存时会重新输出这个缓存文件
    • 页面的revalidate就是导出这个整数变量
    • 不缓存:导出dynamic = 'force-dynamic' or revalidate = 0
    • 缓存fetch、非缓存fetch可以共存
    • 想要强制重渲染,就执行revalidateTag,因为Data Cache会先返回旧的,导致数据没有更新而没有重渲染
  • Router Cache
    • Layout缓存,前进后退时有用

request memoization

  • fetch会自动缓存,在同一个请求中,会使用缓存
    //request memoization: 使用fetch
    const posts: IJsonplaceholderPost[] = await fetch('https://jsonplaceholder.typicode.com/posts').then(res => res.json());
    const posts2: IJsonplaceholderPost[] = await fetch('https://jsonplaceholder.typicode.com/posts').then(res => res.json());
    
    
    //不缓存
    let data = await fetch('https://api.vercel.app/blog', { cache: 'no-store' })
    

data cache

  • 可设置缓存过期时间、手动删除缓存
    • 即便重启服务器也会保持缓存状态
    • 缓存过期时间:与手动删除不一样,会先返回旧数据,更新成功才会在之后调用返回新数据
  • fetch和unstable_cache是一样的
    //data cache: 持久化(缓存到本地文件.next\cache\fetch-cache)
    const posts: IJsonplaceholderPost[] = await fetch('https://jsonplaceholder.typicode.com/posts', {
            next: {
                revalidate: 5,
                tags: ["posts/list"]
            }
        }).then(res => res.json());
    //丢弃缓存
    //  revalidateTag
    //  revalidatePath
    
    //自定义缓存函数
    const getPosts = unstable_cache(
        async () => {
            console.log('Fetching posts... at', new Date());
            const res = await fetch('https://jsonplaceholder.typicode.com/posts');
            return res.json() as Promise<IJsonplaceholderPost[]>;
        },
        ['posts'], // 缓存键,用于标识缓存条目
        {
            revalidate: 5, // 5分钟(300秒)后重新验证
            tags: ['posts-data'] // 用于精确重新验证的标签
        }
    );