Новые инструменты и старые задачи фронтенда
Мне попался вопрос опытного разработчика, который пытался разобраться в современном фронтенде. Отдельные названия были ему знакомы, но из них не складывалось понимание того, как теперь устроено приложение. За Node.js, Angular и очередным способом разработки стало трудно увидеть, откуда приходят данные и какой код выполняется у пользователя.
В сотом выпуске «Веб-стандартов», в декабре 2017 года, мы с Вадимом Макеевым и Ольгой Алексашенко обсуждали, что изменилось за время подкаста. Новых инструментов стало больше, но далеко не все из них успели заменить прежние в наших проектах.
За новыми названиями остаётся JavaScript
Если регулярно читать новости, легко привыкнуть к новым словам и перестать замечать, сколько их накопилось. А человек, который какое-то время занимался своим проектом и не следил за обсуждениями, видит уже другой словарь. Ему может показаться, что изменилось вообще всё.
В вопросе, который я встретил, меня удивляло именно это расхождение. Разработчик не был новичком, но множество названий мешало ему соотнести новую архитектуру со знакомой работой. Когда-то сервер собирал страницу и отдавал её браузеру. Теперь вокруг получения данных, построения интерфейса и выполнения кода возникло столько отдельных инструментов, что исходные задачи стали хуже видны.
При этом данные всё ещё должны откуда-то прийти. Их может отдавать наш сервер, чужой сервис или код, который запускается в облаке. Клиентский фреймворк всё ещё выполняет JavaScript. Подходы к устройству приложения меняются, но знание того, как работает браузер и как он общается с сервером, продолжает помогать в них разбираться.
Меня беспокоило, как быстро можно потерять контекст. Даже знакомая задача становится непонятной, если её теперь описывают словами, которые ты пропустил. Мне проще разобраться в новой библиотеке, когда понятно, какую задачу она решает и что заменяет. Для этого не обязательно сразу пробовать её в проекте.
Что значит «инструмент умер»
В начале 2016 года в HTML Academy мы много работали с PhantomJS. Он выполнял нужную нам работу, но развивался медленно, и хотелось альтернативы. К концу 2017-го такая альтернатива появилась: Puppeteer позволял управлять Chrome. На этом фоне PhantomJS уже называли умершим.
Я с этим определением спорил. Он продолжал работать в продакшене — и у нас, и в других проектах. Прекращение активной разработки не выключает установленные программы. Новое решение может быть лучше, но существующая система от этого не перестаёт выполнять свою задачу в тот же день.
Вадим уточнил, что в Академии PhantomJS использовался в автоматических проверках вёрстки и сравнении изображений. За названием инструмента стояла работающая часть продукта. Появление Puppeteer было хорошей новостью, но из неё ещё не следовало, что всё уже переведено на него.
Похожее мы постоянно слышали о jQuery и Bootstrap. Вадим привёл их как примеры технологий, которые принято хоронить, хотя ими продолжают пользоваться. Оля рассказала, что в её проекте jQuery соседствовал с модулями ES6. В реальном коде старые и новые инструменты вполне могли оказаться рядом.
Возможность браузера и возможность проекта
Я надеялся, что в 2018 году CSS Grid станет таким же привычным выбором для раскладки, каким к тому времени стал Flexbox. Оля сразу напомнила о проекте, где всё ещё требовался Internet Explorer 11.
Дальше она рассказала о задаче с адаптивными изображениями. Для разных экранов нужны были разные кадрирования: на одном прямоугольная картинка, на другом квадратная. Элемент picture позволял выразить этот выбор в разметке, но в списке поддерживаемых браузеров были IE11 и старый Android, где нужного поведения не было.
Здесь было мало подготовить красивое решение для нового браузера. Нужно было выбрать, какое изображение получат остальные. Если оставить в качестве запасного варианта картинку для большого экрана, она могла не подойти мобильному. В результате приходилось выбирать менее удобную общую схему и обрезать изображение средствами вёрстки.
Я предложил рассмотреть обратный порядок: мобильное изображение сделать базовым, а для IE добавить Picturefill или отдельную обработку.
Мы в Академии тоже поддерживали IE11, но старый Android уже не создавал такой задачи: среди наших посетителей его было достаточно мало. Поэтому одинаковая браузерная возможность могла быть доступна нам и неудобна для другого продукта. Разница определялась ещё и тем, кто им пользуется.
Узнать устройство ещё не значит понять человека
Другой новостью было предложение заморозить строку User-Agent в Safari Technology Preview. Вадим видел в этом повод наконец перестать определять возможности браузера по его названию и версии. Если нужна определённая функция, логичнее проверить саму функцию.
Я относился к новости осторожно: экспериментальная сборка ещё не означала, что такое изменение дойдёт до обычного Safari. Но сам вопрос был интересным. С помощью User-Agent разработчики принимают решения не только о совместимости, но и о том, что показать человеку.
Оля привела пример ссылки на магазин приложений: владельцу iPhone показывают App Store, владельцу Android — другой магазин. Я предложил посмотреть на это со стороны пользователя, который хочет отправить ссылку знакомому. Он может открыть сайт с Android, а приложение искать для чужого iPhone. Устройство известно, намерение — нет.
Если нужную ссылку спрятали, человек не сможет сделать то, зачем пришёл. Объяснение, что две ссылки не поместились в дизайн, не делает оставшуюся удобнее. Мы решили за пользователя, что ему понадобится, опираясь на признак, который этого не определяет.
С проверкой возможностей браузера при этом тоже не всё сводилось к простому правилу. Наличие API ещё не гарантирует, что оно работает без ошибок. Бывают проблемы конкретной реализации, для которых трудно написать короткую проверку. И тогда версия браузера помогает понять, с чем мы столкнулись.
Мне хотелось сначала разобраться, чем заменить такие проверки. Отказ от разбора User-Agent может убрать плохую привычку, но вместе с ней нельзя просто потерять возможность обойти известную ошибку браузера.
Что видно на графике популярности
В одном из обзоров фронтенда за 2017 год мы смотрели на распространённость инструментов. Меня удивило, что рост webpack не сопровождался ожидаемым исчезновением Gulp и Grunt. Если судить по обсуждениям, казалось, что новый инструмент должен вытеснять прежние.
Оля описала собственную сборку: webpack занимался JavaScript, Gulp — стилями. Это был хороший пример того, чего не видно в простом сравнении названий. Два инструмента могли использоваться в одном проекте и выполнять разную работу.
К самой аналитике у меня тоже были вопросы. В том же обзоре был график библиотек для хранения состояния в React, где фигурировал один Redux. По такой картинке трудно судить о выборе между решениями: остальные варианты в сравнение не попали.