Настройка A/B тестирования
Google Optimize закрыт в 2023 году. Актуальные инструменты — Statsig, Growthbook, Optimizely, VWO или собственная реализация через Edge Functions.
Выбор инструмента
| Инструмент | Тип | Лучший для |
|---|---|---|
| Growthbook | Open source / SaaS | Технические команды, self-hosted |
| Statsig | SaaS | Быстрый старт, интеграция с аналитикой |
| Optimizely | Enterprise SaaS | Крупные компании, сложные эксперименты |
| VWO | SaaS | Маркетинговые команды без dev |
| Vercel Edge Experiments | PaaS | Next.js на Vercel |
| Собственная реализация | - | Полный контроль, минимальный overhead |
Реализация через Vercel Edge Middleware
// middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
const EXPERIMENT_COOKIE = 'exp_checkout_v2';
const VARIANTS = ['control', 'variant-a', 'variant-b'];
function assignVariant(): string {
const rand = Math.random();
if (rand < 0.34) return 'control';
if (rand < 0.67) return 'variant-a';
return 'variant-b';
}
export function middleware(request: NextRequest) {
const response = NextResponse.next();
// Не участвуют: боты, уже назначенные пользователи
const existing = request.cookies.get(EXPERIMENT_COOKIE)?.value;
if (existing && VARIANTS.includes(existing)) {
return response;
}
const variant = assignVariant();
response.cookies.set(EXPERIMENT_COOKIE, variant, {
maxAge: 60 * 60 * 24 * 30, // 30 дней
httpOnly: true,
sameSite: 'lax',
});
// Variant передаём в заголовке для Server Components
response.headers.set('x-ab-checkout', variant);
return response;
}
export const config = {
matcher: ['/checkout/:path*'],
};
// app/checkout/page.tsx
import { cookies, headers } from 'next/headers';
export default function CheckoutPage() {
const variant = headers().get('x-ab-checkout') ??
cookies().get('exp_checkout_v2')?.value ??
'control';
return (
<>
{variant === 'control' && <CheckoutV1 />}
{variant === 'variant-a' && <CheckoutV2OneStep />}
{variant === 'variant-b' && <CheckoutV2TwoStep />}
<ABTracker experiment="checkout_v2" variant={variant} />
</>
);
}
Трекинг результатов
// components/ABTracker.tsx (Client Component)
'use client';
import { useEffect } from 'react';
export function ABTracker({ experiment, variant }: {
experiment: string;
variant: string;
}) {
useEffect(() => {
// GA4
gtag('event', 'experiment_impression', {
experiment_id: experiment,
variant_id: variant,
});
// PostHog
posthog.capture('$experiment_started', {
'$experiment_id': experiment,
'$variant_key': variant,
});
}, [experiment, variant]);
return null;
}
// Трекинг конверсии — в момент покупки
function trackConversion(variant: string) {
gtag('event', 'purchase', {
experiment_id: 'checkout_v2',
variant_id: variant,
value: orderTotal,
});
}
Statsig: быстрая интеграция
// Statsig SDK
import Statsig from 'statsig-node';
await Statsig.initialize(process.env.STATSIG_SERVER_KEY!);
// В API route / Server Action
const experiment = Statsig.getExperiment(
{ userID: userId, email: userEmail },
'checkout_redesign'
);
const checkoutLayout = experiment.get('layout', 'single-page');
const ctaColor = experiment.get('cta_color', 'blue');
// Клиентская сторона (React SDK)
import { useExperiment } from 'statsig-react';
function PricingCTA() {
const { config } = useExperiment('pricing_cta');
const buttonText = config.get('button_text', 'Get Started');
const buttonVariant = config.get('button_variant', 'primary');
return (
<Button
variant={buttonVariant}
onClick={() => {
statsig.logEvent('cta_clicked', buttonText);
}}
>
{buttonText}
</Button>
);
}
Статистическая значимость
Перед запуском теста — рассчитать необходимую выборку:
# Python: расчёт sample size
from statsmodels.stats.power import zt_ind_solve_power
# CVR = 3%, ожидаемый эффект = +15% (до 3.45%)
baseline_rate = 0.03
expected_effect = 0.15 # относительное улучшение
lift = baseline_rate * expected_effect # 0.0045 абсолютно
n = zt_ind_solve_power(
effect_size=lift / (baseline_rate * (1 - baseline_rate)) ** 0.5,
alpha=0.05, # 95% confidence
power=0.8, # 80% statistical power
)
print(f"Sample size per variant: {int(n)}") # ~12,000
Правило: не останавливать тест раньше запланированного размера выборки, даже если результаты выглядят хорошо.
Анализ результатов в GA4
GA4 → Explore → Free Form
Dimension: Experiment Variant (custom event parameter)
Metric: Conversions, Revenue
Segment по варианту → сравнение конверсий
Настройка A/B тестирования с трекингом в GA4/PostHog — 2–4 рабочих дня в зависимости от стека.







