4

我们有一个大型而复杂的传统 React 应用程序,我们在过去几年中一直在构建它。它加载一个 index.html 注入 javascript 并像往常一样从 API 获取数据。不幸的是,冷加载时间非常糟糕(平均 5 - 7 秒)。加载完所有内容后,它像往常一样快速,但冷加载时间在特定的“关键”页面中扼杀了我们。这些是我们的公共用户页面,格式为:https://mywebsite/userId

我们正在寻找一种方法来显着加快这些路由的加载时间,并使用超越代码拆分或资源优化的方法。我们已经这样做了,并且正在通过 CDN 为我们的应用程序提供服务。

我们已经研究过为这些用户页面创建静态“快照”,我们需要使用 react-static 之类的东西快速加载它们,并将它们作为静态版本提供并在以后进行水合。使用 next.js 或 gatsby 之类的东西重写我们的项目不是一种选择,因为它需要太多的工作。SSR 也不是一个选项,因为我们的整个后端都是用 Django 而不是 Node.js 编码的

我们走在正确的轨道上吗?是否有可能/值得使用 react-static (或类似的工具)来做到这一点?有很多关于如何从头开始创建 react-static 项目的文档,但没有关于如何转换现有项目的文档,即使它只是我们需要的一小部分路由。

此外,一旦我们用户页面上的数据发生变化,我们如何触发适当快照的“重建”?用户不会经常更新他们的数据,大约每月 4 次中的 3 次,但我们有 3K 用户,所以平均每小时更新 15 次。我们可以只触发实际更改的路由的重建吗?

4

2 回答 2

1

就像你说的,你可以使用 react-static。
它们具有完全满足您需求的功能(用户的特定页面)。

在他们的示例中,他们使用一组帖子为每个帖子生成一个特定的静态文件。
加载时间要少得多,因为它只是 html 静态文件。

想象一下有这样的场景:

[
  {
    id: 'foo',
    ...
  },   
  {
    id: 'bar',
    ...
  },
  ...
]

按照下面的示例,这将生成类似这样的内容(在运行时):

- src
  - pages
    - blog
      - posts
        - foo // Specific post page
        - bar // Specific post page

看例子:

//static.config.js
export default {

  // resolves an array of route objects 
  getRoutes: async () => {

    // this is where you can make requests for data that will be needed for all
    // routes or multiple routes - values returned can then be reused in route objects below

    // ATTENTION: In here, instead of posts you'd fetch your users json data
    const { data: posts } = await axios.get(
      "https://jsonplaceholder.typicode.com/posts"
    );

    return [
      // route object
      {
        // React Static looks for files in src/pages (see plugins below) and matches them to path
        path: "/blog",
        // function that returns data for this specific route
        getData: () => ({
          posts
        }),
        // an array of children routes
        // in this case we are mapping through the blog posts from the post variable above
        // and setting a custom route for each one based off their post id
        children: posts.map(post => ({
          path: `/post/${post.id}`,
          // location of template for child route
          template: "src/containers/Post",
          // passing the individual post data needed
          getData: () => ({
            post
          })
        }))
      },
    ];
  },
  // basic template default plugins
  plugins: [
    [
      require.resolve("react-static-plugin-source-filesystem"),
      {
        location: path.resolve("./src/pages")
      }
    ],
    require.resolve("react-static-plugin-reach-router"),
    require.resolve("react-static-plugin-sitemap")
  ]
};
于 2020-12-25T19:00:41.483 回答
0

您可以使用 Service Worker。将重要的快速页面加载为静态,然后在后台使用 Service Worker 加载更长的资源。

您还可以使用 Service Worker 进行智能缓存。例如,服务器可以使用当前资源版本(第一页附带)设置一个 cookie,Service Worker 可以将其与它的资源版本进行比较,并决定是从缓存中加载它还是转到服务器。

于 2020-12-26T20:38:40.083 回答