Cognitive Load Theory для разработчиков — Лаборатория DX
Hard Авторский

Cognitive Load Theory для разработчиков

Intrinsic, extraneous и germane load — как это влияет на продуктивность инженеров

Первоисточник

Cognitive Load Theory

Sweller, Ayres, Kalyuga, 2011

Когда умные люди работают медленно

Знакомая картина: в команде сидят опытные инженеры, мотивации хватает, но скорость поставки падает квартал за кварталом. Менеджмент подозревает лень, кто-то предлагает добавить метрик и контроля. Чаще всего причина другая — люди перегружены когнитивно. Рабочая память переполнена, и никакая мотивация это не починит, пока не убрать лишнюю нагрузку.

Теорию когнитивной нагрузки (Cognitive Load Theory, CLT) сформулировал Джон Свеллер в 1988 году в контексте образовательной психологии. Он разбирался, почему студенты не усваивают материал, даже когда его хорошо объяснили. Ответ упирался в ограничения рабочей памяти: человек одновременно удерживает в голове примерно 4–7 элементов, и за этим порогом продуктивная работа невозможна. В 2010-х теорию начали прикладывать к разработке ПО, и интуитивные ощущения про «сложные проекты» получили строгий язык описания.

Три типа когнитивной нагрузки

Intrinsic load — внутренняя сложность

Нагрузка, которая принадлежит самой задаче. Распределённые системы сложны по природе. Конкурентное программирование требует удерживать в голове множество состояний. Бизнес-логика страховой компании запутана не потому, что кто-то плохо её спроектировал, а потому что страхование — это объективно сложная предметная область с большим количеством краевых случаев и нормативки.

Intrinsic load нельзя убрать, не меняя саму задачу. Но её можно держать в управляемых рамках: дробить задачи помельче, выстраивать абстракции, которые прячут детали до момента, когда они понадобятся, делить команды так, чтобы каждой доставался посильный кусок доменной сложности (отсюда Team Topologies).

Extraneous load — паразитная сложность

С точки зрения Developer Experience именно сюда уходят основные усилия. Extraneous load — это лишняя когнитивная нагрузка, которая не имеет отношения к задаче, но всё равно съедает ресурсы рабочей памяти. Невнятная документация. Запутанный процесс деплоя. Устаревшие инструменты, которые падают по случайным причинам. Двадцать шагов для подъёма локального окружения. Всё это — extraneous load.

Когда разработчик тратит час, чтобы понять, какой из трёх способов деплоя сейчас актуален, или полдня воюет с flaky-тестами, не связанными с его изменениями, ресурсы рабочей памяти уходят в задачи, которые не создают ценности. Чем больше extraneous load, тем меньше остаётся на intrinsic — на саму работу.

Большая часть DX-практики сводится к одной формуле: найти и убрать extraneous cognitive load. Ускорение CI-пайплайна, шаблон сервиса в Internal Developer Platform, страница документации, которая отвечает на вопрос с первого захода — всё это снижение extraneous load.

Germane load — продуктивная нагрузка

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

Germane load хочется максимизировать. Загвоздка в том, что для него нужно свободное место, а место занято extraneous load. Если разработчик весь день воевал с кривым тулингом, на вдумчивое изучение новой архитектурной модели или глубокий code review ресурсов уже не остаётся.

Что показывают исследования

Йо Ханнай из Университета Осло провёл серию работ о когнитивной нагрузке в разработке ПО и пришёл к нескольким понятным выводам. Контекстные переключения между задачами — один из главных источников перегрузки: каждое переключение требует «выгрузить» одну ментальную модель и «загрузить» другую, на это уходит 15–25 минут (Пол Грэм называл это maker’s schedule).

Размер кодовой базы, которую команда обязана знать и поддерживать, тоже коррелирует с когнитивной нагрузкой. Команда из пятнадцати микросервисов, каждый из которых написан немного по-своему и деплоится своим способом, будет жить в перегрузке, даже если по отдельности сервисы простые.

Как измерить когнитивную нагрузку

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

Подход посложнее — анализ задач. Посчитайте, сколько разных контекстов (репозиториев, сервисов, конфигов, команд) нужно затронуть для выполнения типичной фичи. Чем больше контекстов, тем выше нагрузка. Если добавить поле в API означает изменить код в четырёх репозиториях, обновить два конфига и согласовать с тремя командами, проблема с extraneous load налицо.

Полезны и косвенные индикаторы: длительность онбординга новых инженеров, частота ошибок при рутинных операциях, количество вопросов в корпоративном чате уровня «а как сделать X».

Что снижает нагрузку

Упрощение тулчейнов. Каждый инструмент, который разработчик обязан знать, добавляет когнитивной нагрузки. Регулярный аудит: действительно ли нужны три системы мониторинга и два способа деплоя?

Ограничение скоупа владения. «Правило двух пицц» от Amazon — грубая эвристика, но рабочая. Скелтон и Пайс формулируют точнее: команда должна владеть таким объёмом кода, который она удерживает в коллективной рабочей памяти.

Меньше контекстных переключений. Выделяйте инженерам блоки непрерывного времени для глубокой работы и защищайте их от митингов. Никакие инструменты не компенсируют постоянное дёрганье между задачами.

Документация. Хорошая документация позволяет выгрузить знания из голов в артефакт, который можно перечитать в нужный момент.

Стандартизация в меру. Единообразие снижает extraneous load. Чрезмерная стандартизация сама становится источником нагрузки, когда стандарт не подходит под задачу.

Рекомендации

Соберите команду и обсудите, что отнимает больше всего сил и не создаёт ценности. Список приоритизируйте: обычно первые три-пять пунктов дадут 80% эффекта. Фокус — на extraneous load, его можно убрать без компромиссов по функциональности. Germane load, наоборот, защищайте: время на изучение системы окупается многократно, даже если со стороны кажется, что команда «сидит и читает код».