A/B 使用分块测试 React SSR 应用程序

A/B testing for React SSR app with chunking

版本:

webpack: 4.30.0,
react: 16.8.6,
react-loadable: 5.5.0,

我在 webpack 中有一个入口 JS。其他块当前使用 react-loadable 创建,供应商 JS 使用 splitChunks 创建。

我的申请想法: SSR 和分块正在与 react-loadable 一起用于路由级组件。 dynamic-components chunk 可以使用 webpack 的 import promise 或 react Loadable 来制作。


现在,我想介绍一下A/B对这些动态组件的测试。

我有两种方法:

  1. 第一种方法: 在 if-else 中包装动态导入语句以导入该动态组件的 A/B 变体。在服务器级别,我会知道对于给定的用户,我会在 Redux 存储中设置一个标志,以便 select A/B 变化。 (app是SSR还是SPA都可以按照这个方法)

    此方法的注意事项:

    一个。似乎可行 :P

    b。不能很容易地扩展到 A/B/C。在这种情况下,我将不得不引入第三个 else 条件来动态导入 C 变体。由于文件名中的散列已更改,它将破坏路由级组件块(包含这些变体)的浏览器缓存。对于添加额外的 C 测试生效的所有路由级组件也会发生同样的情况。

    c。不得不用 if 条件不必要地污染代码。如果 A/B 测试完成,则必须再次修改代码,这将再次破坏浏览器缓存。

  2. 第二种方法: 我将在代码中只有 1 个动态导入,但我想要 3 个不同的块用于相同的组件 A、B 和 C,例如A/some_chunk[hash].jsB/some_chunk[hash].jsC/some_chunk[hash].js。在服务器级别,我将使用与方法 1 中相同的逻辑对用户进行 A/B/C 测试,但不是在 redux 存储中设置标志,**我将从 A 提供 some_chunk[hash].js 、B 或 C 文件夹,根据用户细分。

    此方法的注意事项:

    一个。我想问一下我们如何为动态组件创建块而不将它们实际导入到文件中。

    b。可以很容易地扩展 A/B/C 测试,因为现在 A/B 测试现在取决于所服务的文件服务器的变体。

    c。不会在客户端代码中使用 if-else 条件污染代码。没有浏览器缓存破坏问题。

    d。 ReactDOMServer.renderToString 将需要单独的服务器代码包装器组件,以了解为服务器端呈现选择哪个变体。

问题:

  1. 所以,我需要知道我们如何按照第二种方法创建块?因为如果无法访问(即未被任何其他文件导入),webpack 将忽略为文件创建块

  2. 您会推荐这种方法吗?做 AB 测试的正确的微型 FE 应用程序方法是什么?

PS:

如果这是可行的,那么我的路线图也将是基本布局的分块。我可以在代码中避免 if-else 条件的地方,并且可以根据 A/B 变体服务器发送到浏览器的方式更改整个布局。

这可以使用 webpack's weak resolve

来完成

来自 webpack 文档的示例:

const page = 'Foo'; // Trick: Can be taken from props
__webpack_modules__[require.resolveWeak(`./page/${page}`)];

我的用例:

假设,我们正在对具有变体 D1、D2 和 D3 的组件 D 进行 A/B 测试。

我们可以在该文件夹内创建具有 D1.js D2.js and D3.js 变体的文件夹 D/。现在,require.resolveWeak('./D/${variation}') 将在构建文件夹中打包 D1、D2 和 D3 的块。现在,在运行时,传递道具以选择特定的变体将动态加载该 JS。

注意: 例如:要选择 D2 变体,实验名称也必须是 D2(否则您必须存储实验名称到组件名称的映射)以作为道具传递。通常,人们通过多个 if-els 来进行 A/B 测试。因此,在 loadVariationOfD.js 中,if-else 不是 weak resolve import statement,而是与 dynamic imports 一起使用(我为此使用 loadable-components)。