Next.js 的三种渲染方式(BSR、SSG、SSR)
<h1 class="Post-Title"> </h1><div class="Post-Author">
<div class="AuthorInfo">
<div class="AuthorInfo">
<div class="css-1gomreu"><img src="https://picx.zhimg.com/v2-0c378fd4c43666d7672cbf7b676fb1a9_l.jpg?source=32738c0c&needBackground=1" srcset="https://picx.zhimg.com/v2-0c378fd4c43666d7672cbf7b676fb1a9_l.jpg?source=32738c0c&needBackground=1 2x" alt="Jacky" class="Avatar AuthorInfo-avatar css-1syywx2"></div>
<div class="AuthorInfo-content">
<div class="AuthorInfo-head">
<div class="css-1gomreu">Jacky</div>
</div>
<div class="AuthorInfo-detail">
<div class="AuthorInfo-badge">
<div class="ztext AuthorInfo-badgeText css-0">一名奋飞的前端小菜鸟</div>
</div>
</div>
</div>
</div>
</div>
<button class="Button FollowButton FEfUrdfMIKpQDJDqkjte Button--primary Button--blue epMJl0lFQuYbC7jrwr_o JmYzaky7MEPMFcJDLNMG" type="button">关注他</button></div>
<div>
<div class="css-dvccr2">
<div class="css-1lr85n">55 人赞同了该文章</div>
</div>
</div>
<div class="Post-RichTextContainer">
<div class="css-1od93p9">
<div class="css-376mun">
<div class="RichText ztext Post-RichText css-oqi8p3">
<p data-first-child="" data-pid="h71I4k-V">Next.js 是一个轻量级的 React 服务端渲染框架</p>
<p data-pid="w53PRl_0">它支持三种渲染方式包括</p>
<ul>
<li data-pid="dtvy_Iod">客户端渲染 BSR (Broswer Side Render)</li>
<li data-pid="TACUX63y">静态页面生成 SSG (Static Site Generation)</li>
<li data-pid="HWtHCVsO">服务端渲染 SSR (Server Side Render)</li>
</ul>
<h2>旧瓶装新酒</h2>
<p data-pid="x-sO2ENG">上面说的几种渲染方式,其实并非什么新东西,其实可以和这些技术对应起来</p>
<ul>
<li data-pid="v9WOTJsk">BSR -- 用 JS、Vue、React 创建 HTML</li>
<li data-pid="T-4lEgYB">SSG -- 页面静态化,把 PHP 提前渲染成 HTML</li>
<li data-pid="J8bNicYu">SSR -- PHP、Python、Ruby、Java 后台的基本功能</li>
</ul>
<h2>不同点</h2>
<p data-pid="88PuaAln">Next.js 的预渲染可以与前端 React 无缝对接</p>
<hr>
<p data-pid="zm1Y7cab">下面,以一个文章列表页面作为例子,分别解析一下三种渲染方式吧</p>
<h2>客户端渲染</h2>
<p data-pid="nV62aS8J">客户端渲染,顾名思义就是只在浏览器上执行的渲染,通过Vue 和 React 构建的单页面应用SPA 都是采用这种方式渲染</p>
<h3>缺点</h3>
<p data-pid="DGSU6Rx-">1 .白屏,在 AJAX 得到渲染之前,页面中并没有内容,只能通过 Loading 来过度</p>
<p data-pid="AxAOvYo5">2. SEO 不友好,因为搜索引擎访问页面, 默认不会执行 JS,只能看到 HTML,而不会等待 AJAX 异步请求数据,所以搜索不到页面内容</p>
<p data-pid="Sigu-Dd1">代码</p>
<div class="highlight">
<pre><code class="language-js"><span class="kr">import <span class="p">{<span class="nx">NextPage<span class="p">} <span class="nx">from <span class="s1">'next'<span class="p">;
<span class="kr">import <span class="nx">axios <span class="nx">from <span class="s1">'axios'<span class="p">;
<span class="kr">import <span class="p">{<span class="nx">useEffect<span class="p">, <span class="nx">useState<span class="p">} <span class="nx">from <span class="s2">"react"<span class="p">;
<span class="kr">import <span class="o">* <span class="nx">as <span class="nx">React <span class="nx">from <span class="s2">"react"<span class="p">;
<span class="nx">type <span class="nx">Post <span class="o">= <span class="p">{
<span class="nx">id<span class="o">: <span class="nx">string<span class="p">,
<span class="nx">id<span class="o">: <span class="nx">string<span class="p">,
<span class="nx">title<span class="o">: <span class="nx">string
<span class="p">}
<span class="kr">const <span class="nx">PostsIndex<span class="o">: <span class="nx">NextPage <span class="o">= <span class="p">() <span class="p">=> <span class="p">{
<span class="c1">// [] 表示只在第一次渲染的时候请求
<span class="c1"> <span class="kr">const <span class="p">[<span class="nx">posts<span class="p">, <span class="nx">setPosts<span class="p">] <span class="o">= <span class="nx">useState<span class="o"><<span class="nx">Post<span class="p">[]<span class="o">><span class="p">([]);
<span class="kr">const <span class="p">[<span class="nx">isLoading<span class="p">, <span class="nx">setIsLoading<span class="p">] <span class="o">= <span class="nx">useState<span class="p">(<span class="kc">false<span class="p">);
<span class="nx">useEffect<span class="p">(() <span class="p">=> <span class="p">{
<span class="nx">setIsLoading<span class="p">(<span class="kc">true<span class="p">);
<span class="c1">// 使用 AJAX 异步请求数据
<span class="c1"> <span class="nx">axios<span class="p">.<span class="nx">get<span class="p">(<span class="s1">'/api/posts'<span class="p">).<span class="nx">then<span class="p">(<span class="nx">response <span class="p">=> <span class="p">{
<span class="nx">setPosts<span class="p">(<span class="nx">response<span class="p">.<span class="nx">data<span class="p">);
<span class="nx">setIsLoading<span class="p">(<span class="kc">false<span class="p">);
<span class="p">}, <span class="p">() <span class="p">=> <span class="p">{
<span class="nx">setIsLoading<span class="p">(<span class="kc">true<span class="p">);
<span class="p">})
<span class="p">}, <span class="p">[]);
<span class="k">return <span class="p">(
<span class="o"><<span class="nx">div<span class="o">>
<span class="o"><<span class="nx">h1<span class="o">><span class="nx">文章列表<span class="o"><<span class="err">/h1>
<span class="p">{<span class="nx">isLoading <span class="o">? <span class="o"><<span class="nx">div<span class="o">><span class="nx">加载中<span class="o"><<span class="err">/div> :
<span class="nx">posts<span class="p">.<span class="nx">map<span class="p">(<span class="nx">p <span class="p">=> <span class="o"><<span class="nx">div <span class="nx">key<span class="o">=<span class="p">{<span class="nx">p<span class="p">.<span class="nx">id<span class="p">}<span class="o">>
<span class="p">{<span class="nx">p<span class="p">.<span class="nx">id<span class="p">}
<span class="o"><<span class="err">/div>)}
<span class="o"><<span class="err">/div>
<span class="p">)
<span class="p">};
<span class="kr">export <span class="k">default <span class="nx">PostsIndex<span class="p">;
</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
</div>
<p data-pid="ZPjOaTHi">当网络不好的时候,loading 的时间很长,页面肯能会出现长时间白屏</p>
<p data-pid="e0UTolO5">由于初次请求的 HTML 中并没有文章内容,需要通过 AJAX 异步加载数据,而这个加载数据渲染的过程都是在客户端完成的,所以称为客户端渲染</p>
<hr>
<h2>静态页面生成 SSG</h2>
<p data-pid="mzsOWN81">在文章列表页面里,其实每个用户查到的内容都是一样的</p>
<p data-pid="Awtkxt75">那为什么还需要在每个人的浏览器上渲染一遍呢?</p>
<p data-pid="pBl1eNMR">为什么不在后端渲染好,然后发给每个人</p>
<p data-pid="inw64R0D">这样就可以</p>
<p data-pid="DDPaSDv1">N 次渲染变成了 1 次渲染</p>
<p data-pid="r_p8pORd">N 次客户端渲染变成了 1 次静态页面生成</p>
<p data-pid="bXL8VSHa">这个过程成为 动态内容静态化</p>
<p data-pid="ZGOrPeaO">优缺点</p>
<p data-pid="rnCskRyq">优点:这种方式可以解决白屏问题、SEO 问题</p>
<p data-pid="C6VnHj4H">缺点:所有用户看到的都是同一个页面,无法生成用户相关内容</p>
<p data-pid="mifmZMcn">如何实现</p>
<p data-pid="hczja-gG">首先我们来想一个问题</p>
<p data-pid="Ave-qgak">该如何获取 posts 呢? 因为加载数据的操作在后端,想通过 AJAX 获取 posts 显然不合适</p>
<p data-pid="LdRO4Aq1">答案是: 通过 <code>getStaticProps</code> 获取 posts</p>
<p data-pid="QSWgolN9"><code>getStaticProps</code> 是 Next.js 提供的一个方法,会在后端执行,返回一个 props,NextPage 在渲染的时候可以使用这个 props</p>
<p data-pid="A95QrEwG">代码</p>
<div class="highlight">
<pre><code class="language-js"><span class="kr">import <span class="p">{<span class="nx">GetStaticProps<span class="p">, <span class="nx">NextPage<span class="p">} <span class="nx">from <span class="s1">'next'<span class="p">;
<span class="kr">import <span class="p">{<span class="nx">getPosts<span class="p">} <span class="nx">from <span class="s1">'../../lib/posts'<span class="p">;
<span class="kr">import <span class="nx">Link <span class="nx">from <span class="s1">'next/link'<span class="p">;
<span class="kr">import <span class="o">* <span class="nx">as <span class="nx">React <span class="nx">from <span class="s1">'react'<span class="p">;
<span class="nx">type <span class="nx">Post <span class="o">= <span class="p">{
<span class="nx">id<span class="o">: <span class="nx">string<span class="p">,
<span class="nx">title<span class="o">: <span class="nx">string
<span class="p">}
<span class="nx">type <span class="nx">Props <span class="o">= <span class="p">{
<span class="nx">posts<span class="o">: <span class="nx">Post<span class="p">[];
<span class="p">}
<span class="c1">// props 中有下面导出的数据 posts
<span class="c1"><span class="kr">const <span class="nx">PostsIndex<span class="o">: <span class="nx">NextPage<span class="o"><<span class="nx">Props<span class="o">> <span class="o">= <span class="p">(<span class="nx">props<span class="p">) <span class="p">=> <span class="p">{
<span class="kr">const <span class="p">{<span class="nx">posts<span class="p">} <span class="o">= <span class="nx">props<span class="p">;
<span class="c1">// 前后端控制台都能打印 -> 同构
<span class="c1"><span class="nx">console<span class="p">.<span class="nx">log<span class="p">(<span class="nx">posts<span class="p">);
<span class="k">return <span class="p">(
<span class="o"><<span class="nx">div<span class="o">>
<span class="o"><<span class="nx">h1<span class="o">><span class="nx">文章列表<span class="o"><<span class="err">/h1>
<span class="p">{<span class="nx">posts<span class="p">.<span class="nx">map<span class="p">(<span class="nx">p <span class="p">=> <span class="o"><<span class="nx">div <span class="nx">key<span class="o">=<span class="p">{<span class="nx">p<span class="p">.<span class="nx">id<span class="p">}<span class="o">>
<span class="o"><<span class="nx">Link <span class="nx">href<span class="o">=<span class="p">{<span class="sb">`/posts/<span class="si">${<span class="nx">p<span class="p">.<span class="nx">id<span class="si">}<span class="sb">`<span class="p">}<span class="o">>
<span class="o"><<span class="nx">a<span class="o">>
<span class="p">{<span class="nx">p<span class="p">.<span class="nx">id<span class="p">}
<span class="o"><<span class="err">/a>
<span class="o"><<span class="err">/Link>
<span class="o"><<span class="err">/div>)}
<span class="o"><<span class="err">/div>
<span class="p">);
<span class="p">};
<span class="kr">export <span class="k">default <span class="nx">PostsIndex<span class="p">;
<span class="c1">// 实现SSG
<span class="c1"><span class="kr">export <span class="kr">const <span class="nx">getStaticProps<span class="o">: <span class="nx">GetStaticProps <span class="o">= <span class="nx">async <span class="p">() <span class="p">=> <span class="p">{
<span class="kr">const <span class="nx">posts <span class="o">= <span class="nx">await <span class="nx">getPosts<span class="p">();
<span class="k">return <span class="p">{
<span class="nx">props<span class="o">: <span class="p">{
<span class="nx">posts<span class="o">: <span class="nx">JSON<span class="p">.<span class="nx">parse<span class="p">(<span class="nx">JSON<span class="p">.<span class="nx">stringify<span class="p">(<span class="nx">posts<span class="p">))
<span class="p">}
<span class="p">};
<span class="p">};
</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
</div>
<h2>前端是怎么不通过 AJAX 获取到数据的</h2>
<p data-pid="wyyB7xMV">posts 数据我们只在服务器获取了,但又是怎样传递给前端的呢?</p>
<p data-pid="4eheMQWz">发现玄机</p>
<img src="https://pica.zhimg.com/v2-1c4c6d4165b1eef6565d7f160b8e6f92_1440w.jpg" width="884" class="origin_image zh-lightbox-thumb" data-caption="" data-size="normal" data-rawwidth="884" data-rawheight="922" data-original-token="v2-1c4c6d4165b1eef6565d7f160b8e6f92" data-original="https://pica.zhimg.com/v2-1c4c6d4165b1eef6565d7f160b8e6f92_r.jpg">
<p data-pid="U7n0fTV3">我们可以看到玄机就藏在 id 为 <em><code>_NEXT_DATA__</code></em> 的 script 标签中,里面储存了传给前端的 props 数据</p>
<p data-pid="DT-dyBqd">这就是同构 SSR 的好处,后端可以将数据直接传给前端,而不需要 AJAX 异步获取</p>
<h2>静态化的时机</h2>
<h3>环境</h3>
<ol>
<li data-pid="4tIzTGy2">在 开发环境 ,每次请求都会运行一次 getStaticProps 这是为了方便你修改代码重新运行</li>
<li data-pid="FzY0m-ut">在 生成环境,getStaticProps 只在 build 是运行一次,这样可以提供一份 HTML 给所有的用户下载</li>
</ol>
<p data-pid="4Uwc4JXd">如何体验生成环境</p>
<div class="highlight">
<pre><code class="language-text">yarn build
yarn start</code></pre>
</div>
<p data-pid="Ij8kwKnN">打包后我们可以会看到这样</p>
<img src="https://pic3.zhimg.com/v2-c4e27d38c70297383ebd9b5727117c84_1440w.jpg" width="856" class="origin_image zh-lightbox-thumb" data-caption="" data-size="normal" data-rawwidth="856" data-rawheight="383" data-original-token="v2-c4e27d38c70297383ebd9b5727117c84" data-original="https://pic3.zhimg.com/v2-c4e27d38c70297383ebd9b5727117c84_r.jpg">
<p data-pid="CXMrKOv5">解读</p>
<p data-pid="Ih8OhU9C">我看看到的页面前的三种图标,分别是 λ ○ ●</p>
<p data-pid="P5MGz1PM">λ (Serve) SSR 不能自动创建 HTML (下面会介绍)</p>
<p data-pid="KhyvJKm0">○ (Static) 自动创建 HTML (发现你没用到 props)</p>
<p data-pid="kiLtSC-7">● (SSG) 自动创建 HTML + JSON (等你用到 props)</p>
<p class="ztext-empty-paragraph"> </p>
<h2>三种文件类型</h2>
<p data-pid="KibS1Wqx">build 完成后,我们查看.next 文件里面,发现 posts.html、posts.js、posts.json</p>
<img src="https://pic4.zhimg.com/v2-d51e534b5a35297e8eb62f23b276bed7_1440w.jpg" width="611" class="origin_image zh-lightbox-thumb" data-caption="" data-size="normal" data-rawwidth="611" data-rawheight="598" data-original-token="v2-d51e534b5a35297e8eb62f23b276bed7" data-original="https://pic4.zhimg.com/v2-d51e534b5a35297e8eb62f23b276bed7_r.jpg">
<ul>
<li data-pid="ia2fh9OR">posts.html 含有静态内容,用于用户直接访问</li>
<li data-pid="TTStooir">post.js 也含有静态内容,用于快速导航(与 HTML 对应)</li>
<li data-pid="qyRKCP7B">posts.json 含有数据,跟 posts.js 结合得到页面</li>
</ul>
<p data-pid="Gzx4Elgf">为什么不直接把数据放入 posts.js 呢?</p>
<p data-pid="ayYwuwsq">显然是为了 posts.js 接受不同的数据,当我们展示每篇博客的时候,他们的样式相同,内容不同,就会用到这个功能</p>
<p data-pid="p3_D7AH_">动态内容静态化</p>
<ul>
<li data-pid="fLXioS1A">如果动态内容与用户无关,那么可以提前静态化</li>
<li data-pid="BDqxPauv">通过 getStaticProps 可以获取数据</li>
<li data-pid="GDnC2eIb">静态内容+数据(本地获取) 就得到了完整的页面</li>
<li data-pid="iKkq8V_I">代替了之前的 静态内容+动态内容(AJAX 获取)</li>
</ul>
<hr>
<h2>服务端渲染(SSR)</h2>
<p data-pid="CV56rMsT">如果页面和用户相关呢?</p>
<p data-pid="FvR1zUFj">这种情况较难提前静态化,需要在 用户请求时,获取用户信息,然后 通过用户信息去数据库拿数据,如果非要做,就要给每个用户创建一个页面,有时候这些数据更新极快,无法提前静态化, 比如微博首页的信息流</p>
<p data-pid="12GnVZzJ">那怎么办?</p>
<p data-pid="UW8P2ryn">要么客户端渲染, 会出现白屏</p>
<p data-pid="3rh8OJ69">要么服务端渲染 SSR,没有白屏</p>
<p data-pid="Ho8azBnE">运行时机</p>
<p data-pid="3i--MMtI">无论时开发环境还是生成环境,都是在请求之后运行 getServerSideProps</p>
<p data-pid="M7QZdpvm">代码</p>
<p data-pid="d3ucMSmk">和 SSG 代码基本一致,不过使用了 getSeverSideProps</p>
<p data-pid="iK1XJmd5">这段代码实现的时,服务器响应请求后获取浏览器信息,返回给前端展示</p>
<div class="highlight">
<pre><code class="language-js"><span class="kr">import <span class="p">{<span class="nx">GetServerSideProps<span class="p">, <span class="nx">NextPage<span class="p">} <span class="nx">from <span class="s1">'next'<span class="p">;
<span class="kr">import <span class="o">* <span class="nx">as <span class="nx">React <span class="nx">from <span class="s1">'react'<span class="p">;
<span class="kr">import <span class="p">{<span class="nx">IncomingHttpHeaders<span class="p">} <span class="nx">from <span class="s1">'http'<span class="p">;
<span class="nx">type <span class="nx">Props <span class="o">= <span class="p">{
<span class="nx">browser<span class="o">: <span class="nx">string
<span class="p">}
<span class="kr">const <span class="nx">index<span class="o">: <span class="nx">NextPage<span class="o"><<span class="nx">Props<span class="o">> <span class="o">= <span class="p">(<span class="nx">props<span class="p">) <span class="p">=> <span class="p">{
<span class="k">return <span class="p">(
<span class="o"><<span class="nx">div<span class="o">>
<span class="o"><<span class="nx">h1<span class="o">><span class="nx">你的浏览器是 <span class="p">{<span class="nx">props<span class="p">.<span class="nx">browser<span class="p">}<span class="o"><<span class="err">/h1>
<span class="o"><<span class="err">/div>
<span class="p">);
<span class="p">};
<span class="kr">export <span class="k">default <span class="nx">index<span class="p">;
<span class="kr">export <span class="kr">const <span class="nx">getServerSideProps<span class="o">: <span class="nx">GetServerSideProps <span class="o">= <span class="nx">async <span class="p">(<span class="nx">context<span class="p">) <span class="p">=> <span class="p">{
<span class="kr">const <span class="nx">headers<span class="o">:<span class="nx">IncomingHttpHeaders <span class="o">= <span class="nx">context<span class="p">.<span class="nx">req<span class="p">.<span class="nx">headers<span class="p">;
<span class="kr">const <span class="nx">browser <span class="o">= <span class="nx">headers<span class="p">[<span class="s1">'user-agent'<span class="p">];
<span class="k">return <span class="p">{
<span class="nx">props<span class="o">: <span class="p">{
<span class="nx">browser
<span class="p">}
<span class="p">};
<span class="p">};
</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
</div>
<p data-pid="KDF43irb">SSR 原理</p>
<p data-pid="1FmHiNmp">推荐 在后端 renderToString() 在前端 hydrate()</p>
<p data-pid="QeVAWRGt">后端将页面渲染,返回 HTML String 格式,传递到前端,前端进行 hydrate() ,会保留 HTML 并附上时间监听,也就是说后端渲染 HTML,前端添加监听。</p>
<p data-pid="4f5BK8OX">前端也会渲染一次,用以确保前后端渲染结果一致</p>
<hr>
<h2>总结</h2>
<h3>客户端渲染 SSR</h3>
<p data-pid="l18RNerA">只在浏览器上运行,缺点 SEO 不友好,白屏</p>
<p data-pid="HcR1EPmN">静态页面生成 SSG</p>
<p data-pid="KJ86zH8h">Static Site Generation,解决白屏问题、SEO 问题</p>
<p data-pid="nAglJ8Z0">缺点:无法生成和用户相关的内容 (所有用户请求的结果都一样)</p>
<p data-pid="YVwqQ-AB">服务端渲染 (SSR)</p>
<p data-pid="5PepS9fR">解决白屏问题、SEO问题</p>
<p data-pid="RrjT6nym">可以生成用户相关的内容</p>
<p class="ztext-empty-paragraph"> </p>
<h2>三种渲染模式如何选择</h2>
<img src="https://picx.zhimg.com/v2-481174213d589ef81d46849a7a064331_1440w.jpg" width="1091" class="origin_image zh-lightbox-thumb" data-caption="" data-size="normal" data-rawwidth="1091" data-rawheight="279" data-original-token="v2-481174213d589ef81d46849a7a064331" data-original="https://picx.zhimg.com/v2-481174213d589ef81d46849a7a064331_r.jpg">
<ul>
<li data-pid="LPXnujuF">有动态内容吗?没有什么也不用做,自动渲染为 HTML</li>
<li data-pid="NBzG8yG8">有动态内容,动态内容和客户端相关吗?相关就只能用客户端渲染 BSR</li>
<li data-pid="wb6PCNWh">有动态内容,动态内容跟请求/用户相关吗?相关就只能用服务端渲染 SSR 或 BSR</li>
<li data-pid="a2uAyils">其他情况可以用 SSG 或 SSR 或 BSR</li>
</ul>
</div>
</div>
</div>
</div>
</div>
<div id="MySignature" role="contentinfo">
漫思<br><br>
来源:https://www.cnblogs.com/sexintercourse/p/19071941
頁:
[1]