首页 > 解决方案 > 创建 60k+ 页面会降低页面性能

问题描述

我在一个使用 gatsby 构建的相当大的电子商务网站上工作。到目前为止,我们一直在运行时动态加载所有产品数据,因此整个网站只有 1 个产品页面,总共大约 3k 个页面。

但是,出于 SEO 的原因,我们正在尝试静态构建我们所有的产品页面,这会为网站增加大约 6 万个页面。

完成此操作后,我们的 app.[hash].js 文件已增加到 10mb,并且总体页面性能下降。悬停链接会导致页面挂起半秒钟。

我们通过在调用创建页面时将产品数据作为页面上下文传递来创建产品页面:

  const productsRaw = await fetch(productsUrl)
  const products = await productsRaw.json()

  /* Build a page for each product */
  if (products) {
    products.forEach(product => {
      const productPage = {
        path: `/product${product.route}`,
        component: path.resolve(`./src/templates/product.jsx`),
        context: product,
      }
      createPage(productPage)
    })
  }

我们认为糟糕的页面性能与 app.js 文件跳转到 10mb 左右有关。我们是否可以进行任何优化来减小此文件的大小,或者在增加页数时这是不可避免的?

更新

分析webpack后发现问题是每个产品页面都添加到match-path.json文件中。这导致文件超过 10mb。是否有必要将所有这些路径添加到文件中,如果没有,是否有办法在创建页面时纠正它?

在此处输入图像描述

更新 2

我最终编写了一个脚本,在 webpack 运行之前从 match-path.json 中删除所有非正则表达式路径,并且该站点似乎运行良好并且性能非常好。我有什么办法可以防止它们首先被添加?

标签: javascriptreactjsgatsby

解决方案


虽然 60k 是在构建时生成的相当数量的页面,但这并不是极端的。您遇到的问题是您正在通过上下文传递产品数据。这旨在成为允许您在页面模板中查询数据的少量数据。

  1. gatsby-node.js, 调用createPage每个应该导出的页面
  2. context在传递给的内容中包含查找该页面数据所需的最少信息量createPage(例如 ID 或 slug)
  3. 在您的页面模板中,使用上下文过滤 GraphQL 查询返回的数据(的每个属性context都可用作命名 GraphQL 查询的参数)
  4. 在 GraphQL 查询中仅获取页面所需的数据;在组件的所有实例中保持不变的任何数据都可以使用静态查询来代替

如果您按照上述操作,每个页面查询数据将被写为一个单独的 page-data.json 文件,该文件将相当小(实际上只是查询数据)。当您将鼠标悬停在链接上时,这应该是唯一预取的数据。

注意:如果在执行此操作后您的app.<hash>.js文件仍然很大,那么您可能会在其中包含一些您不希望的数据。使用webpack-bundle-analyzer查看权重的来源。


推荐阅读