Розробка кастомної платформи A/B-тестування для сайту

Уявіть: ви запустили A/B-тест через Optimizely, але через тиждень помітили, що LCP зріс на 300 мс через сторонній скрипт. Або ви не можете отримати сирі дані — лише агреговані графіки. А вартість ліцензії для 10 000 відвідувачів — суттєві витрати на місяць. Кастомна платформа A/B-тестування вирішує

Розробка та обслуговування будь-яких видів сайтів:

Інформаційні сайти або веб-програми
Сайти візитки, landing page, корпоративні сайти, онлайн каталоги, квіз, промо-сайти, блоги, ресурси новин, інформаційні портали, форуми, агрегатори
Сайти або веб-програми електронної комерції
Інтернет-магазини, B2B-портали, маркетплейси, онлайн-обмінники, кешбек-сайти, біржі, дропшиппінг-платформи, парсери товарів
Веб-програми для управління бізнес-процесами
CRM-системи, ERP-системи, корпоративні портали, системи управління виробництвом, парсери інформації
Сайти або веб-програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, конструктори сайтів, портали надання електронних послуг, відеохостинги, тематичні портали

Це лише деякі з технічних типів сайтів, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Послуги, які ми пропонуємо
Показано 1 з 1Усі 2062 послуг
Розробка кастомної платформи A/B-тестування для сайту
Складний
~1-2 тижні

Наші компетенції:

Часті запитання

Останні роботи

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1418
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1286
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    983
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1243
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    983
  • image_bitrix-bitrix-24-1c_fixper_448_0.webp
    Розробка веб-сайту для компанії ФІКСПЕР
    998

Уявіть: ви запустили A/B-тест через Optimizely, але через тиждень помітили, що LCP зріс на 300 мс через сторонній скрипт. Або ви не можете отримати сирі дані — лише агреговані графіки. А вартість ліцензії для 10 000 відвідувачів — суттєві витрати на місяць. Кастомна платформа A/B-тестування вирішує всі ці проблеми: ви контролюєте код, дані та бюджет. Економія на ліцензійних відрахуваннях може сягати 70%, а окупність настає протягом 3–6 місяців. До того ж кастомна платформа працює в 2–3 рази швидше за рахунок відсутності зовнішніх скриптів.

Ми накопичили понад 5 років досвіду в розробці таких систем для інтернет-магазинів з трафіком 1 млн+ відвідувачів на місяць — понад 50 проєктів. Наша платформа будується за модульним принципом і легко адаптується під будь-яку архітектуру.

Переваги кастомної платформи A/B-тестування

Готові інструменти прискорюють старт, але при масштабуванні стають дорогими та негнучкими. Кастомна платформа окупається вже на кількох тестах — в одному з проєктів конверсія зросла на 15% після першого експерименту. При річному використанні економія на ліцензійних відрахуваннях може покрити вартість розробки протягом кількох місяців.

Як ми вирішуємо проблему детермінованого розподілу?

Ключова вимога A/B-тесту: користувач завжди повинен потрапляти в один і той самий варіант експерименту. Для цього ми використовуємо hash-based assignment. Хеш від user_id та назви експерименту за модулем 100% визначає номер варіанту. Результат зберігається в БД, що гарантує консистентність при багаторазових візитах.

Ось схема таблиць для зберігання експериментів та призначень:

CREATE TABLE experiments ( id SERIAL PRIMARY KEY, slug VARCHAR(100) UNIQUE NOT NULL, name VARCHAR(255) NOT NULL, description TEXT, status VARCHAR(20) DEFAULT 'draft', -- draft, running, paused, completed traffic SMALLINT DEFAULT 100, -- % трафіку, що бере участь в експерименті start_at TIMESTAMPTZ, end_at TIMESTAMPTZ, created_at TIMESTAMPTZ DEFAULT NOW(), updated_at TIMESTAMPTZ DEFAULT NOW() ); CREATE TABLE experiment_variants ( id SERIAL PRIMARY KEY, experiment_id INTEGER REFERENCES experiments(id), slug VARCHAR(100) NOT NULL, name VARCHAR(255), weight SMALLINT DEFAULT 50, config JSONB DEFAULT '{}', UNIQUE(experiment_id, slug) ); CREATE TABLE user_assignments ( user_id BIGINT NOT NULL, experiment_id INTEGER REFERENCES experiments(id), variant_id INTEGER REFERENCES experiment_variants(id), assigned_at TIMESTAMPTZ DEFAULT NOW(), PRIMARY KEY (user_id, experiment_id) ); 

PHP-сервіс реалізує детермінований розподіл з використанням crc32 та збереженням у БД:

class ExperimentAssignmentService { public function getVariant(int $userId, string $experimentSlug): ?string { $experiment = $this->getActiveExperiment($experimentSlug); if (!$experiment) return null; $existing = $this->assignmentRepo->find($userId, $experiment['id']); if ($existing) return $existing['variant_slug']; $trafficBucket = $this->hashToBucket($userId, $experimentSlug . '_traffic'); if ($trafficBucket >= $experiment['traffic']) return null; $variantBucket = $this->hashToBucket($userId, $experimentSlug); $variant = $this->selectVariant($experiment['variants'], $variantBucket); $this->assignmentRepo->assign($userId, $experiment['id'], $variant['id']); $this->eventTracker->track($userId, 'experiment.assigned', [ 'experiment' => $experimentSlug, 'variant' => $variant['slug'], ]); return $variant['slug']; } private function hashToBucket(int $userId, string $salt): int { $hash = crc32($userId . '_' . $salt); return abs($hash) % 100; } private function selectVariant(array $variants, int $bucket): array { $cumulative = 0; foreach ($variants as $variant) { $cumulative += $variant['weight']; if ($bucket < $cumulative) return $variant; } return end($variants); } } 

Трекінг подій у ClickHouse

Ми надсилаємо всі значущі дії користувача з контекстом експерименту. Щоб не сповільнювати користувацький досвід, події записуються асинхронно через чергу.

class ExperimentEventTracker { public function track(int $userId, string $event, array $properties = []): void { $activeVariants = $this->assignmentRepo->getUserVariants($userId); $payload = [ 'event' => $event, 'user_id' => $userId, 'session_id' => session_id(), 'occurred_at' => now()->toIso8601String(), 'experiments' => $activeVariants, 'properties' => $properties, ]; $this->queue->push(new TrackExperimentEvent($payload)); } } 

Дані зберігаються в ClickHouse — колонковій СУБД, оптимізованій для аналітичних запитів. Це дозволяє швидко рахувати конверсії та будувати звіти навіть при мільйонах подій.

Обчислення результатів: Z-тест

Після збору даних ми використовуємо двосторонній Z-тест для пропорцій (Wikipedia). Він показує, чи є різниця між конверсіями контрольної та тестової груп статистично значущою. Мінімальний виявлюваний ефект (MDE) налаштовується заздалегідь — наприклад, 5% при потужності 80%.

import numpy as np from scipy import stats def calculate_significance(control, treatment): p1 = control['conversions'] / control['users'] p2 = treatment['conversions'] / treatment['users'] n1, n2 = control['users'], treatment['users'] p_pool = (control['conversions'] + treatment['conversions']) / (n1 + n2) se = np.sqrt(p_pool * (1 - p_pool) * (1/n1 + 1/n2)) if se == 0: return {'error': 'Insufficient data'} z = (p2 - p1) / se p_value = 2 * (1 - stats.norm.cdf(abs(z))) diff = p2 - p1 se_diff = np.sqrt(p1*(1-p1)/n1 + p2*(1-p2)/n2) ci = [diff - 1.96*se_diff, diff + 1.96*se_diff] return {'significant': p_value < 0.05, 'p_value': round(p_value, 6), 'lift': round((p2-p1)/p1*100,2) if p1>0 else None} 

Щоб результати були достовірними, ми також перевіряємо Sample Ratio Mismatch (SRM) — чи не відхилився реальний розподіл користувачів від очікуваного. Якщо p-value хі-квадрат тесту нижче 0.01, дані позначаються як ненадійні.

Параметр Розрахунок
Конверсія conversions / users
Lift (p2-p1)/p1 * 100%
Довірчий інтервал p ± 1.96 * SE
Етап Тривалість Результат
Аналітика 1–2 дні Цілі, метрики, архітектура
Проектування 2–3 дні Схема БД, API, контракти
Реалізація 7–10 днів Код, тести
Тестування 2 дні Юніт, інтеграційне, навантаження
Деплой 1–2 дні Розгортання, моніторинг

Як працюють Feature Flags у A/B-тестах?

A/B-тестування та feature flags — суміжні концепції. Ми інтегруємо їх так: варіант експерименту містить JSON-конфігурацію, яка впливає на роботу фіч. Наприклад, варіант treatment_a включає {"checkout_steps": 1, "show_trust_badges": true}. Код на фронті або бекенді просто читає цей конфіг і змінює поведінку.

$variant = $experimentService->getVariant($userId, 'checkout-redesign'); $config = $experimentService->getVariantConfig('checkout-redesign', $variant); $checkoutSteps = $config['checkout_steps'] ?? 3; 

Що входить у роботу

  • Розробка assignment service з hash-based розподілом та unit-тестами
  • Трекінг подій з асинхронним записом у ClickHouse
  • Обчислення статистичної значущості (Z-тест, довірчі інтервали)
  • Адмін-панель для запуску та моніторингу експериментів
  • Документація з інтеграції та навчання вашої команди
  • Підтримка першого місяця пілотного запуску

Процес роботи

  1. Аналітика — розбираємо ваші цілі, метрики, поточну архітектуру (1–2 дні)
  2. Проектування — готуємо схему БД, API, контракти (2–3 дні)
  3. Реалізація — пишемо код, пишемо тести (7–10 днів)
  4. Тестування — юніт-тести, інтеграційне тестування, навантаження (2 дні)
  5. Деплой — розгортаємо у вашому середовищі, налаштовуємо моніторинг (1–2 дні)

З усіх питань звертайтеся до нас — ми допоможемо оцінити обсяг робіт і розрахувати економію.

Строки та бюджет

Орієнтовний час розробки — від 14 до 21 дня. Вартість розраховується індивідуально залежно від складності інтеграції та додаткових вимог. Замовте розробку кастомної платформи вже сьогодні — ми підготуємо пропозицію протягом 2 робочих днів.

Ми гарантуємо якість коду: використовуємо код-рев'ю, покриття тестами не менше 80%, і надаємо гарантію на усунення помилок протягом 30 днів після введення в експлуатацію. Отримайте консультацію та дізнайтеся, як кастомна платформа A/B-тестування може покращити ваші конверсії без компромісів щодо продуктивності.