Когда продукт растет, скорость изменений всегда начинает конкурировать с рисками. Бизнес хочет выкатывать фичи быстрее, а разработчики — держать продакшен в безопасности. Feature Flags решают этот конфликт: позволяют менять функциональность без деплоя, тестировать гипотезы на ограниченной аудитории и мгновенно выключать ошибки.

Привет, Хабр! Меня зовут Михаил Олейник, я разработчик IBS. В этой статье — практический разбор, как устроены фича-флаги, где их хранить, как получать их состояние на фронтенде и что учитывать в реальных проектах. Если вы искали краткий и понятный гайд по теме, это он.

Что такое Feature Flags и как они работают

Feature Flag — это механизм, который позволяет включать или выключать части функциональности без релиза нового кода. По сути, условный оператор вокруг конкретной возможности приложения.

Фича-флаг представляет собой пару «ключ — значение». Значение может быть булевым (true/false) или содержать дополнительные параметры: процент аудитории, роли пользователей, варианты эксперимента и другие.

Пример структуры:

const FEATURE_FLAGS = {
   ENABLE_PAYMENT: true,
   ENABLE_REDESIGN_SIDEBAR: false,
   EXPERIMENTAL_SAVE_SONG_WIDGET: [
      { percentageOfUsers: 0.3, usersRoles: ['vip', 'user'] },
   ],
};

У первых двух флагов — булевое значение, то есть фича либо доступна, либо нет. У третьего — дополнительные правила: он включится только для 30% аудитории и только для ролей VIP и user. Нужные параметры определяет команда, исходя из задач проекта.

Сравним, как могла бы выглядеть страница корзины на маркетплейсе без механизма фича-флагов и с ним:

Самый простой сценарий: оборачиваем кнопку оплаты в флаг. Если флаг вернул true, показываем пользователю кнопку. Если false, скрываем или заменяем ее запасным компонентом. Так же можно управлять целыми экранами, API-логикой и экспериментами.

Практическая польза Feature Flags:

  • Kill switch. Если в прод ушла фича с критичным багом (например, возможность получить товар за 0 рублей), ее можно мгновенно отключить флагом — без поиска проблемы, правки кода и срочного деплоя.

  • Постепенный выпуск. Фича проходит несколько этапов. Сначала доступ к ней получат тестировщики, затем, например, 10% пользователей, затем 30% и, наконец, 100%. На каждом шаге собираются метрики, и только после успешной проверки флаг удаляется.

  • Бета-тестирование. Можно выдавать доступ к новой функциональности ограниченной группе пользователей.

  • A/B-тестирование. Разные варианты одной функции показываются разным сегментам аудитории. После анализа обратной связи выбирается лучший вариант.

  • Гибкость релизов. В продакшен можно выкатывать незавершенный код: фича будет скрыта, пока ее не включат.

  • Безопасные рефакторинг и редизайн.

  • Региональное управление. Флаги позволяют включать и выключать функциональность для определенных стран или регионов.

Где хранить фича-флаги

В коде. Просто, но непрактично. Любое изменение требует релиза, поэтому скорость реакции будет низкой.

В переменных окружения. Те же ограничения, что и у хранения в коде: изменения требуют ручного вмешательства и деплоя.

В сервисах SaaS (Software as a Service). LaunchDarkly, Split, Flagsmith, GrowthBook и другие — быстрые и функциональные решения. Однако они предполагают платную подписку, передачу части данных о пользователях и зависимость от внешнего сервиса.

В базе данных. Чаще всего — оптимальный подход. Он позволяет динамически управлять фичами во время работы приложения, не требует сторонних сервисов и закрывает большинство потребностей сложных продуктов. Но нужно иметь в виду, что он съест больше ресурсов и времени на реализацию, чем все остальные варианты.

Как получать фича-флаги на фронтенде

Если флаги хранятся в базе данных, на клиенте есть несколько способов получать их актуальное состояние:

Единоразовый запрос

Самая простая и надежная схема, которую часто объединяют с авторизацией: вместе с данными пользователя сервер возвращает список флагов и их значения.

Подходит для UI-логики, где не требуется мгновенная реакция.

Периодический опрос (polling)

Клиент через определенные интервалы запрашивает состояние флагов. При изменении значения флага меняем UI или логику.

Полезно, когда изменения могут происходить часто, но перезагружать страницу нельзя.

WebSocket

Идеален для сценариев, где важна скорость реакции: kill switch и поэтапный выпуск. Изменение состояния флага мгновенно обновит интерфейс.

Примеры реализации на фронтенде

В React-приложениях удобно использовать вспомогательный компонент-обертку для включения и выключения частей UI:

interface ToggleFeaturesProps {
   name: keyof FeatureFlags;
   on: ReactElement;
   off?: ReactElement;
}
export const ToggleFeatures: FC<ToggleFeaturesProps> = ({
   name,
   on,
   off = null,
}) => {
   const isOn = checkFeatureFlags(name);
   if (isOn) {
      return on;
   }
   return off;
};

Компонент принимает имя флага и варианты отображения on и off. В off мы передаем запасной вариант либо не передаем ничего. Внутри компонента делаем проверку через функцию checkFeatureFlag. Если вернется true, мы отрисовываем компонент, который пришел в пропе on. Если false, то отрисовываем запасной вариант, который был передан в off.

checkFeatureFlags может учитывать не только булевое значение, но и более сложные правила: роль пользователя, вариант фичи, попадание пользователя в процент выборки.

Пример проверки на процент аудитории:

const MAX_UINT_32 = 4294967295;
export const checkPercentage = (
   percentageOfUsers: number,
   name: keyof FeatureFlags,
   userId: string
) => {
   return murmurhash(${name}-${userId}) /
MAX_UINT_32 < percentageOfUsers;
};

Мы взяли за основу неизменяемое значение, относящееся к пользователю (id), и наименование фича-флага. Затем хэшировали эту комбинацию через алгоритм murmurhash, который возвращает целое 32-битное число, «нормализовали» полученное число и сравнили его со значением фича-флага.

Важно, чтобы алгоритм был детерминированным: один и тот же пользователь должен стабильно попадать в одну и ту же группу, то есть всегда видеть (или никогда не видеть) определенную фичу.

Недостатки и подводные камни

1. Рост сложности кодовой базы. Флаги добавляют ветвления и увеличивают количество тест-кейсов.

2. Увеличение объема кода.

3. Необходимость обслуживания. Флаги имеют жизненный цикл: одни живут долго, другие нужно удалять сразу после успешного релиза.

На что еще обратить внимание

  • следите за именами фича-флагов, чтобы избежать дублирования;

  • регулярно проводите «чистку» кода от устаревших флагов;

  • для критичных функций проверка по флагу должна быть и на клиенте, и на сервере;

  • часто удобнее завести специальный интерфейс наподобие админки для управления флагами.

Заключение

Feature Flags — это не просто способ «включать или выключать».

Это инструмент зрелой разработки, который позволяет безопасно внедрять фичи, контролировать эксперименты, быстро реагировать на инциденты и ускорять поставку ценности пользователям. При грамотном использовании фича-флаги дают команде гибкость, уменьшают риски и делают процесс разработки более предсказуемым.

Задавайте свои вопросы по фича-флагам в комментариях, постараюсь ответить!

Комментарии (0)