创建超过60k的页面会降低页面性能

时间:2020-04-21 18:31:48

标签: javascript reactjs gatsby

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

但是,由于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。所有这些路径是否都必须添加到文件中?如果没有,在我创建页面时是否有方法可以纠正该问题?

enter image description here

更新2

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

2 个答案:

答案 0 :(得分:1)

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

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

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

注意:如果执行此操作后,您的context文件仍然很大,则可能有一些您不期望的数据。使用webpack-bundle-analyzer进行检查,以查看重量来自何处。

答案 1 :(得分:0)

我知道了。因此,我们实际上确实创建了另一个包含matchPath的动态产品页面。如果我们无法正确构建所有产品,而用户试图访问不是静态生成的产品,则使用此页面。在这种情况下,它将点击匹配路径以动态加载产品数据。该页面还使用与其他产品页面相同的模板。当我从创建中删除此页面时,所有其他产品都从match-path.json中删除,但是当包含该产品时,所有其他产品都添加到match-path.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, banners: PDPBannerData ? PDPBannerData.contentfulProductAdditionalContent : null },
      }
      createPage(productPage)
    })
  }

  const productPage = {
    path: '/product',
    component: path.resolve(`./src/templates/product.jsx`),
    context: { banners: PDPBannerData ? PDPBannerData.contentfulProductAdditionalContent : null },
    matchPath: `/furniture/product/*`,
  }
  createPage(productPage)

我认为这样做是有原因的,对此有何想法?我们正在谈论删除此动态页面,因此对于我们来说,删除它并继续前进可能并不重要。