A/B-тестирование на статическом сайте работает без потери скорости, если вариант страницы выбирается на edge, а не в браузере после загрузки. Сервер сразу отдаёт готовый HTML с нужным вариантом, и пользователь не видит подмену контента. Дальше - как это устроено технически и что реально можно тестировать таким способом.
В проектах Exceltic.dev мы регулярно видим одну и ту же картину: команда подключает клиентский скрипт A/B-тестирования к лендингу, который до этого проходил аудит скорости, и через пару недель метрики в Google Search Console заметно проседают. Обычно причина в том, что скрипт подменяет контент уже после отрисовки страницы - браузеру приходится ждать код теста, перерисовывать блоки и пересчитывать раскладку.
Для сайта на платном трафике это не абстрактная метрика. Просадка LCP и CLS снижает конверсию и повышает стоимость клика в рекламных кабинетах, где скорость страницы учитывается при показе объявления. Разберём, почему клиентские инструменты ломают скорость и как тестировать варианты на edge - без перескока контента и лишнего веса скрипта.
Типичный сценарий: на быстрый статический лендинг добавляют скрипт вроде VWO, Optimizely или одного из преемников Google Optimize, чтобы проверить заголовок или кнопку действия. Скрипт загружается после HTML, определяет вариант в браузере и подменяет содержимое на лету.
Flicker оригинального контента (FOOC): кратковременная вспышка исходной версии страницы перед подменой на вариант теста, заметная пользователю как дёрганье интерфейса. Скрипт при этом блокирует рендеринг, пока не определит вариант, и добавляет собственный вес - это увеличивает LCP, CLS и время до интерактивности.
Почему обычные A/B-скрипты ломают скорость статического сайта
Статический сайт быстрый именно потому, что HTML для рендеринга уже готов на момент запроса. Клиентский A/B-скрипт нарушает эту модель: он получает управление уже в браузере, после того как страница частично отрисована.
Чтобы избежать flicker, большинство инструментов прячут содержимое страницы до момента, пока скрипт не определит вариант и не подменит DOM. Это создаёт задержку первой отрисовки и напрямую бьёт по LCP.
Дальше добавляется вес самого скрипта - обычно от 20 до 60 КБ в сжатом виде, плюс синхронный запрос к серверу тестирования за конфигурацией вариантов. На медленном канале это дополнительные 100-300 мс до того, как пользователь вообще увидит контент.
Итог: сайт, который проходил все проверки Core Web Vitals, после подключения тестирования показывает рост LCP на десятки процентов и скачки CLS от подмены блоков. Разница особенно заметна на мобильном трафике - там и канал медленнее, и устройство слабее.
Если скорость лендинга уже проседает, до внедрения тестов стоит сначала провести аудит и ускорение Core Web Vitals - иначе A/B-тест будет мерить конверсию на и без того медленной странице.
Как устроено тестирование на уровне edge
Edge-тестирование: подход, при котором вариант страницы выбирается не в браузере пользователя, а на уровне CDN или edge-функции - до того, как HTML попадёт к клиенту.
Запрос пользователя попадает не сразу на источник статики, а на edge-функцию, которая выполняется на ближайшей к пользователю точке присутствия CDN. Функция проверяет по куке, назначен ли уже вариант, и если нет - назначает случайно с учётом заданной пропорции трафика.
Дальше edge-функция отдаёт клиенту готовую HTML-страницу нужного варианта - либо переписывая отдельные блоки в потоке HTML на edge-платформе, либо проксируя запрос на заранее собранную статическую версию под этот вариант. В обоих случаях браузер получает финальный HTML сразу, без скрипта, который что-то подменяет после загрузки.
Такой паттерн поддерживают edge-платформы вроде Vercel Edge Middleware, Cloudflare Workers и Netlify Edge Functions - все три позволяют выполнять код до генерации ответа и модифицировать HTML или маршрутизацию запроса на уровне CDN, до того как он дойдёт до браузера.
Ключевое отличие от клиентского подхода: пользователь ни разу не видит исходную версию перед подменой, потому что edge-функция решает, какой вариант отдать, ещё до формирования ответа. Flicker физически не может произойти - подмены на клиенте просто нет.
Сравнение подходов к A/B-тестированию
Три основных способа тестировать статический сайт различаются по скорости, сложности внедрения и стоимости.
| Подход | Влияние на скорость | Сложность внедрения | Стоимость |
|---|---|---|---|
| Клиентский скрипт (VWO, Optimizely и похожие) | Высокое - flicker, блокировка рендеринга, +20-60 КБ | Низкая - вставить сниппет | Подписка на платформу, обычно от 100-300 $/мес |
| Edge-функция (Cloudflare Workers, Vercel Edge Middleware) | Минимальное - HTML готов сразу, без клиентской подмены | Средняя - нужен код на edge и логика назначения варианта | Оплата за выполнение функций, часто в рамках бесплатного лимита |
| Серверный редирект на отдельные статические сборки | Минимальное после первого захода, но лишний редирект на старте | Средняя-высокая - нужно поддерживать несколько сборок сайта | Хостинг нескольких версий сборки |
Клиентский скрипт проще всего внедрить, но именно он чаще всего портит метрики скорости - это плата за простоту.
Серверный редирект на отдельные сборки работает быстро после первого захода, но требует дублировать инфраструктуру сборки и синхронизировать контент между версиями вручную.
Edge-функция - средний по сложности, но лучший по соотношению скорости и гибкости вариант для команды, которая уже умеет работать с CDN.
Пошаговая реализация edge-теста
Внедрение теста на edge состоит из четырёх шагов: назначение варианта, отдача правильного HTML, отслеживание конверсии и оценка статистической значимости.
Назначение варианта и закрепление за пользователем
Edge-функция при первом заходе пользователя случайным образом присваивает вариант A или B с учётом заданной пропорции - например, 50/50 или 90/10, если тест только запускается.
Назначенный вариант сохраняется в куке на весь срок теста (закрепляющая кука: кука, которая фиксирует вариант за пользователем, чтобы он видел одну и ту же версию при повторных заходах). Без такого закрепления один и тот же посетитель может видеть то вариант A, то вариант B при разных визитах, что искажает результаты.
Пример логики назначения варианта на edge (концептуально)
on request:
variant = getCookie('ab_variant')
if not variant:
variant = random() < 0.5 ? 'a' : 'b'
setCookie('ab_variant', variant, maxAge: 30 days)
route to variant-specific HTML
Отдача правильного HTML
По значению куки edge-функция либо переписывает конкретные блоки в потоке HTML, либо проксирует запрос на заранее собранную версию /variant-b/.
Второй способ проще в поддержке для статических сайтов: вариант B - это просто отдельная папка со сборкой, которую генерирует та же система статической генерации, что и основной сайт.
Отслеживание конверсии по варианту
Клиентское событие конверсии - отправка формы, клик по кнопке действия - должно передавать значение варианта вместе с событием в аналитику или в собственный сервис сбора данных теста.
Пример события конверсии с меткой варианта (концептуально)
on formSubmit:
variant = getCookie('ab_variant')
sendEvent('lead_submitted', { variant: variant })
Без явной метки варианта в событии конверсии сравнить эффективность A и B будет нечем - аналитика просто не будет знать, какую версию видел конкретный пользователь.
Статистическая значимость результата
Тест нужно останавливать не по ощущению “вариант B выглядит лучше”, а по достижению статистической значимости - обычно порог 95% доверительного интервала при достаточном объёме конверсий на каждый вариант.
Для лендинга с невысоким трафиком набор нужного количества конверсий может занять несколько недель. Проверять значимость раньше срока и сразу отключать тест - частая ошибка, которая даёт случайный, а не устойчивый результат.
Что легко тестировать на статике, а что сложно
Edge-тестирование хорошо подходит для точечных изменений внутри одной и той же структуры страницы.
Легко тестировать:
- заголовки и подзаголовки;
- текст и цвет кнопки действия;
- порядок блоков на странице;
- наличие или расположение социального доказательства - отзывов, логотипов клиентов;
- заголовок и структуру формы захвата лида.
Сложнее тестировать:
- принципиально разную логику страницы, например другой сценарий воронки или другой набор полей формы с другой валидацией;
- варианты, зависящие от серверной интеграции, например разный расчёт цены;
- тесты с более чем 2-3 вариантами одновременно - сложность edge-логики и объём трафика на вариант растут быстро.
Для сценариев со сложно различающейся логикой обычно проще держать вариант B отдельной сборкой и явно направлять на неё часть трафика, чем собирать всё в одну edge-функцию с ветвлениями.
Если лендинг создаётся именно под платный трафик, тестирование стоит закладывать на этапе разработки - тогда структура страницы сразу проектируется под быструю подмену блоков. Это одна из задач, которую мы решаем при разработке лендинга под платный трафик.
Типичные ошибки при внедрении A/B-теста на edge
- Тестирование без закрепления варианта. Пользователь видит разные варианты при повторных заходах, данные теста становятся ненадёжными.
- Слишком много вариантов сразу. Три-четыре варианта на низком трафике растягивают тест на месяцы вместо недель.
- Остановка теста по первому впечатлению. Ранняя остановка при видимой разнице без проверки значимости часто даёт случайный результат.
- Игнорирование мобильного трафика при анализе. Поведение на мобильных и десктопе может отличаться, усреднённый результат маскирует эту разницу.
- Тестирование на изначально медленной странице. Разница в конверсии между вариантами теряется на фоне общей просадки скорости - сначала стоит закрыть базовые проблемы производительности, например по чек-листу для лендинга под платный трафик.
Для кого это актуально
Edge-тестирование имеет смысл для команд, которые уже ведут платный трафик на статический или headless лендинг и не готовы жертвовать скоростью ради экспериментов с конверсией. Особенно это касается проектов, где стоимость клика напрямую зависит от скорости страницы в глазах рекламной платформы, а разработка ведётся на стеке с CDN и edge-функциями - Vercel, Cloudflare, Netlify.
Часто задаваемые вопросы
Замедляет ли A/B-тестирование сайт? Клиентские инструменты вроде VWO или Optimizely обычно замедляют - они блокируют рендеринг и добавляют вес скрипта. Edge-тестирование через Vercel Edge Middleware или Cloudflare Workers практически не влияет на скорость, потому что вариант выбирается до отдачи HTML, а не после его загрузки в браузере.
Что такое flicker оригинального контента и как его избежать? Flicker (FOOC) - это кратковременное отображение исходной версии страницы перед подменой на вариант теста. Он возникает только при клиентской подмене контента. При edge-тестировании сервер сразу отдаёт готовый HTML нужного варианта, поэтому flicker физически не происходит.
Можно ли тестировать A/B на Cloudflare Pages или Vercel без сторонних платформ? Да, обе платформы поддерживают выполнение кода на edge - Cloudflare Workers, Vercel Edge Middleware, - этого достаточно для назначения варианта через куку и маршрутизации на нужную версию HTML. Сторонняя платформа тестирования нужна в основном для отчётности и статистических расчётов, а не для самой механики показа вариантов.
Сколько трафика нужно для статистически значимого результата? Зависит от базовой конверсии страницы и ожидаемой разницы между вариантами - универсального числа нет. Проверить это заранее помогает калькулятор на основе методологии хи-квадрат: чем меньше базовая конверсия и чем меньше ожидаемая разница, тем больше нужно трафика.
Стоит ли тестировать больше двух вариантов сразу? На небольшом трафике - нет. Каждый дополнительный вариант делит и без того ограниченный объём конверсий, и тест растягивается на месяцы. Для лендингов с трафиком ниже нескольких тысяч визитов в неделю разумнее тестировать по одному изменению за раз.
Если вы ведёте платный трафик на статический лендинг и хотите проверять гипотезы без риска для скорости - опишите задачу команде Exceltic.dev. Разберём текущую архитектуру сайта и оценим объём работ под edge-тестирование.