Платформа и её критики

Годами защитники веб-стандартов, производительности и доступности призывают веб-разработчиков "использовать платформу". Нолан Лоусон был одним из таких сторонников.

Аргумент прост: зачем писать что-то самому на JavaScript, если браузер может это делать? Любой самостоятельно написанный код, вероятно, будет медленнее и менее удобен, чем встроенные возможности браузера.

Однако стоит рассмотреть и противоположную точку зрения, хотя бы для того, чтобы понять позицию тех, кто скептически относится к идее использования платформы. Если это так очевидно, почему столько разработчиков нужно в этом убеждать?

Исторический контекст

Самая очевидная причина — историческая. Браузеры долгое время отставали от экосистемы, работающей на них. Библиотеки вроде jQuery заполняли критические пробелы, пока браузеры реализовывали эквивалентные API. И даже после этого приходилось ждать, пока устаревшие браузеры вроде IE6 исчезнут с рынка. Сегодня большинство браузеров выходят новыми версиями постоянно (Safari, хотя и примерно 7 раз в год, тоже обновляется регулярно), но до начала 2020-х веб-разработчики имели дело с весьма неоднородной веб-платформой. В таких условиях писать что-то самому было логичным выбором.

Привычка и близость

Другой фактор — привычка. Если разработчик обычно ищет React-компоненты на npm, он будет тянуться к ним независимо от задачи. Если поискать "sticky positioning" на npm, не найдётся пакета, который говорил бы: "просто используй CSS position: sticky, дурак".

Иногда даже наличие хорошего стандарта не спасает — библиотеки на npm заполняют полезный промежуток между удобством фреймворка и сырой платформой. Любопытно было наблюдать, как многие React-разработчики придерживались JSX и идиом React — сырые DOM API казались им "мерзкими" — но с удовольствием использовали низкоуровневые библиотеки, где манипуляции DOM встречаются постоянно. Например, библиотека виртуального списка могла смело применять сырые DOM API ради производительности, но предоставлять более высокоуровневые примитивы, доступные для начинающего React-разработчика. Экосистема компонентов создавала естественное разделение труда: опытные разработчики упаковывали незнакомые API платформы в более привычную форму.

Роль документации

Документация сыграла огромную роль. Пакеты на npm часто содержат детальные README'ы, сайты с примерами, туториалы и скриншоты. А документация платформы долго была рассеяна по блогам, StackOverflow и сайтам вроде CSS Tricks. Лишь когда MDN стал неотъемлемым стандартом (наряду с более перспективным web.dev от Google), ситуация улучшилась. Но часто эти сайты просто рекомендовали использовать известные библиотеки вроде jQuery или GreenSock!

Сравнение сайта Dragula с надписью "drag and drop так просто, что больно" и страницы MDN Drag and Drop API
Сайт Dragula рядом со страницей MDN для Drag and Drop API. Первый вариант по-прежнему выглядит более привлекательно.

За пределами библиотек: удовольствие от создания

Если бы дело было только в выборе между третьесторонними библиотеками и API платформы, это не полностью объясняло бы скептицизм. Ленивые разработчики, которые просто хотят готовое решение, не особо заботятся, откуда оно взялось — из npm, браузера или чьего-то GitHub Gist. Они решают проблему и идут дальше. Но есть другой источник сопротивления "используй платформу", на который стоит обратить внимание.

Для некоторых разработчиков создание собственного решения просто интереснее. Часто такой код легче понимать, особенно если нет глубокого знания веб-платформы. А после создания возникает эффект типа IKEA эффекта — хочется поддерживать и улучшать собственный код.

Представьте, что нужно создать модальное окно. Визуально понятна логика: контент появляется на экране, фон ещё виден, но частично закрыт, и клик вне окна его закрывает. Можно схватить position:absolute и z-index для позиционирования — но фон всё ещё скроллится, нужно отключить overflow у body… И если понимать доступность, понадобится обработка Esc, создание focus trap, возврат фокуса элементу, открывшему диалог…

Для многих разработчиков это звучит как кошмар (и способ создать что-то, что только наполовину работает). Но для других это звучит как развлечение! Подумайте, сколько узнаёшь, начиная это строить. И какую собственную фишку можно добавить — анимации, темы, опциональную кнопку закрытия… Вот так и получается библиотека, готовая к заливу на npm. Куда как веселее, чем просто взять <dialog> и покончить с этим — скучно же!

И для многих из нас, до появления API вроде <dialog>, это был способ учиться платформе! Многие, кто сейчас защищает "используй платформу", раньше сами писали polyfills, shims и библиотеки. Лоусон один из них: годы работал над инструментами для IndexedDB, WebSQL и других API браузерного хранилища в рамках разработки PouchDB. Это привело к достаточной уверенности, чтобы участвовать в заседаниях W3C и даже открывать issues и PR на спецификацию IndexedDB. Без принудительного заполнения пробела в платформе не уверен, нашёлся бы интерес и мотивация, чтобы достичь такого уровня экспертизы.

Темная сторона самостоятельного кодирования

Конечно, создание своего решения — не всегда благо. Иногда это просто незнание. На веб-платформе, в частности, много JavaScript-решений проблем, которые лучше решаются CSS, потому что многие разработчики просто не изучили CSS достаточно глубоко.

И справедливо будет сказать, что CSS исторически был сложным! Потому сайт и называется "CSS Tricks". Вещи вроде clear fix, floats и min-width: 0 трюк далеко не интуитивны. Вместо попыток понять внутренний алгоритм CSS часто проще представить нужную логику в виде императивного кода и выразить её на JavaScript. Плюс, долгое время CSS не имел прямого способа выразить типичные паттерны вроде ограничения количества строк, изменения размера textarea, скрытия полосы прокрутки и прочего. Неудивительно, что разработчики писали это сами, используя инструменты, которые уже понимали.

Проблема выходит за пределы веба

Это явление не ограничивается веб-разработкой. Может применяться к любому разработчику, работающему на платформе, которую он не полностью понимает. Например, в работе используется ClickHouse для хранения аналитических данных. Однажды коллега и автор этой статьи не согласились, как хранить большие JSON в колонке: первый построил систему сжатия перед сохранением, второй поместил данные в отдельное хранилище ключ-значение, вставив только ключ в ClickHouse. Оказалось, оба ошибались! ClickHouse автоматически сжимает данные, и как колонное хранилище лучше сжимает, если просто дать ClickHouse работать. А отдельное хранилище было просто худшей версией того, что уже делает колонный SELECT.

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

Верно для любого разработчика: iOS или Android, игровой движок, или любая другая платформа — вероятно, есть похожие истории. Есть причина, по которой стереотип опытного инженера — это тот, кто берет запутанный хаос начинающего и заменяет его одной строкой. Чем больше учишься, тем лучше понимаешь, как всё работает сквозь систему, и можешь свести свой вклад к минимуму (сокращая бремя поддержки в будущем).

Будущее с AI

Хотелось бы не говорить об AI весь этот текст (хватит за прошлый год), но как не задуматься, как AI-кодирование повлияет на всё это. У автора есть и оптимистичный, и пессимистичный взгляд:

  • Оптимистичный: LLM имеют энциклопедические знания платформы, на которой работают, и могут выбрать ровно тот API платформы, который нужен для опыта, описанного туманным английским. Так как это решение быстрее и корректнее, чем код пользователя, агент предпочтёт его после тестирования и бенчмарков. И IKEA эффект исчезает, когда разработчики не пишут код сами.
  • Пессимистичный: LLM обожают дублировать код — например, игнорируют существующие функции ради своих — и объём нестандартного, не-идиоматичного кода взлетит. Разработчики не приказывают агентам достаточно тестировать или пробовать альтернативы, просто коммитят первый вариант. И так как всегда можно добавить ещё епициклов, агенты будут итерировать переусложнённые решения, которые вообще не должны были существовать.

В собственном опыте с AI-кодированием видно оба явления. Хочется верить, что с лучшими моделями и средами обучения код будет тяготеть к оптимистичному сценарию, но уверенности нет.

Заключение

Вот такие долгие и слегка противоречивые мысли на счёт "используй платформу". Как принцип люблю его, потому что он кратко передаёт ощущение при виде переусложнённого кода и мысль, что было бы красивее и элегантнее, если бы автор лучше понимал слои под ними. Но при этом сам был таким автором, и помнит радость от создания такого красивого, запутанного кода (красивого лично для себя). Поэтому стоит понимать, откуда такие разработчики. Поэтому уверен, "используй платформу" будет слышно, пока существуют платформы.

Комментировать можно на федивёрсе или на Lobsters.