【问题标题】:Next.js SSR vs. SSGNext.js SSR 与 SSG
【发布时间】:2021-07-05 02:17:14
【问题描述】:

我正在开发一个包含许多页面的 Next.js 电子商务 应用程序,其中一些是全产品页面、特定产品页面、博客文章页面、个人资料页面、购物车页面等等.这个应用程序需要强大的 SEO,因此我选择了 Next.js,但是,我对它的数据获取选项 - SSR 和 SSG 没有太多经验。我在 Next.js 中阅读了很多关于 SSR 和 SSG 的文章,但我不确定我是否理解正确。

由于我是新手,我为几乎所有需要在渲染之前从 RESTful API 加载内容的页面选择了getServerSideProps。但是,我看到一篇文章指出,产品页面的最佳选择是将getStaticPropsgetStaticPathsfallback = true 一起使用,并在某个页面尚未预渲染时呈现加载指示器。然而,我的应用程序经常更改数据,数据库包含超过 10k 的产品,这些产品定期被删除、编辑或添加。我的第一个问题是,getStaticPropsgetStaticPaths 在这种情况下是否是一个不错的选择。 每次页面浏览都会更新产品数据吗? 或者我需要 SSR 吗? 客户始终需要查看产品的最新更新。同样的问题也适用于所有产品页面,因为它应该只显示当前可用的产品,并在缺货时立即隐藏它们。

我的第二个问题是关于部署的。我知道如果应用程序是静态构建和导出的,它可以部署到静态/共享主机。但是,如果我在我的应用程序中使用 SSR,据我所知,我必须使用虚拟服务器来托管应用程序。根据第一个问题,托管此类应用的选项有哪些?

非常感谢您的所有回答。

【问题讨论】:

    标签: reactjs next.js e-commerce server-side-rendering


    【解决方案1】:

    使用 getServerSideProps (SSR) 数据是在请求时获取的,因此您的页面将具有更高的首字节时间 (TTFB),但始终会使用新数据预渲染页面。

    With Static Generation (SSG) HTML 是在构建时生成的,并且会在每个请求上重复使用,TTFB 速度较慢,页面通常更快,但您每次都需要重新构建您的应用程序数据已更新(博客可接受,但电子商务不可接受)。

    使用增量静态重新生成 (ISG) 静态内容也可以是动态的,页面将在后台使用基于间隔的 HTTP 请求重建。 您可以使用getStaticProps 内的revalidate key 指定页面的更新频率,这与fallback : true 一起使用非常好,并且允许您(几乎)始终更新内容:

    function Blog({ posts }) {
      const { isFallback } = useRouter(); // if true show loading indicator
    
      return (
        // your page content
      )
    
    }
    
    export async function getStaticPaths() {
      return {
        // no pages are generated at build time
        paths: [],
        // Enabling statically generating all pages
        fallback: true,
      }
    }
    
    // This function gets called at build time on server-side.
    // It may be called again, on a serverless function, if
    // revalidation is enabled and a new request comes in
    export async function getStaticProps() {
      const res = await fetch('https://.../posts')
      const posts = await res.json()
    
      return {
        props: {
          posts,
        },
        // Next.js will attempt to re-generate the page:
        // - When a request comes in
        // - At most once every second
        revalidate: 1, // In seconds
      }
    }
    
    export default Blog
    

    注意事项: ISG 的灵感来自stale-while-revalidate,这意味着如果您的页面在 1 年内没有访问,即使您的重新验证时间是 1 秒,1 年后的第一个用户将看到 1 年的数据,因此从技术上讲,用户不会总是看到更新数据。有关更多信息和资源,请参阅 my answer 关于按需重新验证。

    next export 允许您在服务器上没有节点环境的情况下为网站提供服务(它会生成静态文件),请参阅this,但 ISG 和 SSR 不支持

    【讨论】:

    • 非常感谢您的广泛回答。现在清楚多了。我现在将坚持使用服务器端渲染,这似乎是这个特定项目更合适的选择。再次感谢!
    【解决方案2】:

    1. getStaticProps 和 getStaticPaths 是这种情况下的好选择吗?

    Ans. getStaticPropsgetStaticPaths 对于您的情况(即电子商务应用程序)来说,Incremental Static Generation 是一个不错的选择。

    2.产品数据会随着每次页面浏览而更新吗?

    Ans. 您可以在一段时间后再次预渲染产品页面。它是这样工作的:

    1. Next.js can define a "timeout" for this page — let’s set it at 60 seconds.
    2. The data for product Y is updated.
    3. When the page for product Y is requested, the user will see the existing (out of date) page.
    4. When another request comes in 60 seconds after the previous request, the user will see the existing (out of date) page. In the background, Next.js pre-renders this page again.
    5. Once the pre-rendering has finished, Next.js will serve the updated page for product Y.
    

    这种方法称为增量静态再生。要启用此功能,您可以在 getStaticProps 中指定 revalidate: 60

    3.在哪里部署 nextjs 应用?

    Ans. Next.js 可以部署到任何支持 Node.js 和 ofcourse 数据库的托管服务提供商,用于存储产品数据和其他 CRUD 操作。

    供参考:

    1. https://vercel.com/blog/nextjs-server-side-rendering-vs-static-generation
    2. https://nextjs.org/learn/basics/deploying-nextjs-app/other-hosting-options

    【讨论】:

    • 我就是这么想的。我试图找到一种方法将应用程序部署在静态站点的共享主机上,但现在我发现这是不可能的。我现在将坚持服务器端渲染。非常感谢您的帮助!
    猜你喜欢
    • 1970-01-01
    • 2019-12-27
    • 2022-01-03
    • 2021-08-21
    • 1970-01-01
    • 2021-04-07
    • 2020-10-29
    • 1970-01-01
    • 2021-12-02
    相关资源
    最近更新 更多