🧐

Next.jsのMiddlewareでA/Bテストを行って最適なページを知る

2022/02/08に公開

Next.js v12でMiddlewareという機能が発表されました。
Middlewareの特徴は、フロントエンドとバックエンドの間で実行される処理を書けることです。

このユースケースのひとつに「A/Bテスト」があります。

今回は、なぜA/BテストでMiddlewareを使うのか、どうやってA/Bテストを行うのかを見ていきたいと思います。

A/Bテストとは?

まず、そもそもA/Bテストとは何かを簡単に説明します。

A/Bテストは、Webサイトに複数のバージョンを用意してどちらが良いか調べる手法です。
より商品が売れるサイト、より顧客が惹かれるサイトをつくるためのものです。

考え方はとっても簡単で、Webサイトを訪れるユーザをランダムに各バージョンへ割りあてて、どのバージョンで最もユーザがコンバージョンするか(商品を買ったり、資料請求したり)を調べます。

なぜA/Bテストをするの?

簡単なことのように思えますが、実はA/Bテストはとても大きな力をもっています。

有名な実例は、アメリカのオバマ大統領の選挙PRでしょう。
2008年の大統領選挙活動において、支援者(寄付金)募集サイトの画像とボタンのA/Bテストをすることで、Webサイトを訪れた人の登録率を8.26%から11.6%へ引き上げたと伝えられています。
これは、寄付金額にして6000万ドル相当だということです。

このように、あたなのWebサイトもちょっとの工夫でとてつもなくパワーアップする可能性があります。
それを簡単に実現してしまうのがA/Bテストなのです。

ここで重要なのは、どのバリエーションが最適なのかをデータで判断するということです。
「きっとこれが良い」というような誰かの考えではなく、実際にWebサイトを見たユーザの行動が答えを与えてくれるのです。

なぜA/BテストでMiddlewareを使うの?

Middlewareが発表される以前、A/Bテストを実施するには2つの方法がありました。

  • フロントエンドでバリエーションを割りあてる

Webサイトをロードしてからブラウザ上で表示を切り替える方法です。
この方法では、一度オリジナルのバージョンが表示されてから切り替わったり、表示を遅らせてユーザを待たせてしまうといった問題がありました。
(Googleオプティマイズ等の多くのLPOツールはこの方法です。)

  • バックエンドでバリエーションを割りあてる

サーバでどちらのバージョンを配信するか決めてからHTMLを返す方法です。
この方法ではCDNにうまくキャッシュできず、毎回サーバの応答を待たなければならないという問題がありました。

Middlewareならば上記2つの問題を解決できます。
つまり、CDNに複数バージョンをキャッシュし、ブラウザはロードされたものを単に表示するだけです。

A/Bテストを実施してみよう

まず対象となるページを準備します。
今回は表示する文字を変更してみましょう。

パスによって表示される文字が切り替わるように実装します。

pages/[variation].tsx
import { useRouter } from "next/router"

import { VARIATIONS } from "../variations"

export default function Index({ message }) {
  return (
    <div>
      <h1>{message}</h1>
    </div>
  )
}

export async function getStaticPaths() {
  return {
    paths: VARIATIONS.map((variation) => ({ params: { variation } })),
    fallback: false,
  }
}

export async function getStaticProps({ params }) {
  const variation = params.variation
  const message = "バリエーション" + variation.toUpperCase()
  return { props: { message } }
}
variations/index.ts
export const VARIATIONS = ["a", "b"]

pagesフォルダに_middleware.tsを配置します。

pages/_middleware.ts
import { NextRequest, NextResponse } from 'next/server'

import { VARIATIONS } from "../variations"

const COOKIE_NAME = "ab-test-veriation"

export function middleware(req: NextRequest) {
  const variation = req.cookies[COOKIE_NAME] || chooseVariation()
  const res = NextResponse.rewrite(`/${variation}`)

  res.cookie(COOKIE_NAME, variation)
  
  return res
}

const chooseVariation = () => {
  // 0 ~ 1 の一様乱数
  const r = crypto.getRandomValues(new Uint32Array(1))[0] / (0xffffffff + 1)
  
  const i = Math.floor(r * VARIATIONS.length)
  return VARIATIONS[i]
}

これだけです。簡単!

ポイントは2つ。

  • 各バリエーションへの割りあてがMiddlewareで行われている
  • Cookieを使用して、再度Webサイトを訪れたときに同じバリエーションが表示されるようにしている

ぜひ実際に動かしてみて、メッセージが変わることを確かめてみてください。

宣伝

ノーコードでA/BテストのようなWebサイト(特にランディングページ)の最適化ができるツール「SAITEKI LP」を開発しています。

https://lp.saiteki.site

興味があればTwitterに連絡ください!

Discussion