Почему веб такой сложный?

в 14:51, , рубрики: javascript, javascript fatique, Веб-разработка, Разработка веб-сайтов

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

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

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

image
источник картинки

Под современным фронтэндом и его друзьями сейчас понимают куда больше, чем кажется со стороны. Это и классические веб-сайты и SPA, и приложения на электроне, и мобильные приложения на cordova, NativeScript, React Native, и даже на Flutter. Это сложная инфраструктура с CDN-ами, геодецентрализованными службами, это чат-боты на JS, и даже инструменты машинного обучения для оптимизации сборки и даже генерации верстки.

А в самом вебе появляются чудовищно сложные решения, которые раньше могли работать исключительно в десктопном режиме. Я сам успел пару лет назад прикоснуться к разработке полноценного браузера генома в браузере — я занимался обеспечением перформанса и 60FPS, что было достаточно большой, но решаемой проблемой. Еще лет 5 назад никто и подумать не мог, что браузер генома мог бы быть не чем-то устанавливаемым на мощный компьютер, а это решение позволило врачам и исследователям работать с геномом даже с планшета или легковесного ноутбука.

Почему?

На данный момент связка HTML+CSS+JS является одной из самых мощных в вопросах построения интерфейсов — не только за счет своих возможностей, но и количества решений, построенных на ней — css-фреймворки, библиотеки визуальных компонент, интерфейсы к огромному количеству сервисов и SAAS. По КПД в часах разработки на потенциальную аудиторию и доступность — веб-технологии опережают и мобильные, и десктопные решения. И сейчас она распалась на целых три направления:

  • Разработка полностью статических и около-статических сайтов с частично динамическим контентом (галереи, попапы и так далее)
  • Разработка "классических" веб-приложений на серверных фреймворках (django, rails)
  • Разработка клиентских веб-приложений

И каждое из них обладает абсолютно отличающейся от других спецификой.

Разработка на JS действительно была болезненной, поэтому начали появляться решения, которые решали эту боль.

Если посмотреть на них, можно увидеть кое-что очень интересное: сначала начали появляться решения вроде jQuery и CoffeeScript, уменьшающие избыточность и многословность языка. Но они быстро угасли, и на их место пришли инструменты, позволяющие максимально эффективно повторно использовать код, статически обнаруживать ошибки, и строить эффективные абстракции, "пряча" отдельные уровни сложности за простыми и хорошо описанными интерфейсами.

Появился GraphQL, решающий проблемы со сложностью описания, документирования и поддержания REST. Появились TypeScript и Flow, которые решали проблемы нехватки типизации. Появились новые сущности языка, позволяющие эффективно работать с асинхронными операциями, классами, потоками данных. Появился WebAssembly, позволяющий переиспользовать код из других языков, и делать это быстро.

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

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

Еще более явным свидетельством стал ряд событий, произошедший дальше: появились React Native, NativeScript, Dart + Flutter и другие решения для переиспользования кода на нативных платформах. Это очень важный момент: за отсутствием возможности использовать в вебе другие языки, компании начали подстраивать свои процессы в поисках "серебрянной пули", которая им позволит сократить далеко не маленькие затраты на разработку и время на доставку нового функционала до всех клиентов. Любому проекту важно быть быстрым, и специалисты высокого уровня начали объединяться в поисках возможности эффективно работать на JS.

Кстати, по этой же причине начали частично отмирать шаблонизаторы: использование еще одной семантики показало себя менее эффективным, нежели использование знакомого всем HTML с небольшими расширениями на JS (Angular, Vue) или использование просто языка для описания верстки (React, Flutter). Невозможность расширить, необходимость знакомить разработчиков с новым языком, риск отмирания платформы, децентрализованность привели к тому, что начали предпочитать шаблонизаторы фреймворков, которые старались быть как можно ближе к платформам HTML/DOM.

Однако, помимо эффективного написания кода, есть еще и "коэффициент" для синхронизации команды. Если язык позволяет работать сверх-быстро, но при этом синхронизация отдельного функционала между двумя разработчиками создает чудовищную боль, он скорее всего остается нишевым. Поэтому многие возможности языка и решения направлены именно на уменьшение проблем с синхронизацией и отсутствием проблем. Они уменьшают этот "коэффициент", говорящий о том, сколько джуниоров может одновременно контролировать миддл, и сколько миддлов может контролировать ведущий разработчик. Из последних примеров таких возможностей — es6 imports частично решают в том числе проблему циклических зависимостей, а prettier позволяет получить ожидаемый, хорошо поддающийся merge-ам в git-е код вне зависимости от того, как пишет сам разработчик. Он не должен быть красивым, он должен хорошо синхронизироваться.

И в итоге за буквально несколько лет веб как платформа была захвачена большими компаниями и серьезными командами, отчего у большинства случилась "усталость от javascript". Кстати, основная претензия к почти-монополии Google на веб в лице Chromium и заключается в том, что они проталкивают в возможности веб-платформы и JS то, что им нужно (хотя это обычно совпадает с тем, что нужно большинству компаний).

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

Все стало сложно и все запутались

И никто не понимал, что делать. В чем, собственно, проблема? В тех самых трех отличающихся категориях.

  • Разработка полностью статических и около-статических сайтов с частично динамическим контентом: для этого типа приложений характерен HTML как точка входа, максимальная скорость загрузки и опциональный JS
  • Разработка "классических" веб-приложений на серверных фреймворках (django, rails): для этих решений на данный момент характерна загрузка c HTML как точкой входа, но вместо максимальной скорости загрузки они акцентированы на переиспользовании кода, DRY и интеграции с бэкэндом. JS-код частично сгенерирован фреймворком (нотификации, формы, турбо-ссылки и так далее), частично надо писать самим
  • Разработка клиентских веб-приложений. Вот тут происходит неожиданное: HTML вместо точки входа становится одновременно манифестом приложения и платформой рендеринга, а "точкой входа" становится JS.

Что я подразумеваю под точкой входа: это некая сущность, загрузка которой равна минимальной доставке до пользователя продукта. Если пользователю нужно показать информацию, то нам нужен HTML+CSS, если запустить приложение — нужен JS, который запускается из HTML.

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

Изоморфные приложения

Под "изоморфным" в веб-разработке обычно подразумевают нечто, что работает и на сервере, и на клиенте. В таком режиме умеют работать приложения на react, angular, vue.js, есть готовые фреймворки — Next и Nuxt, например.

Для них актуальны обе задачи: веб-приложение должно и доставлять свое изначальное состояние до пользователя максимально быстро, и выступать в качестве приложения. Иначе говоря, они должны доставить и HTML, и JS как две точки входа, одну для контента, другую для приложения. Это создает два противоречащих параграфа: с одной стороны, объем доставляемых данных должен быть минимальным, с другой — нужно переиспользование кода. Для JS это решается чанками вебпака, code splitting-ом и динамической загрузкой кода, шаблоны уехали в JS, но остается еще CSS. А самое главное — нам хочется не доставлять ни одного лишнего байта пользователю. А потом кому-то в голову все-таки дошла идея: у таких приложений действительно две точки входа. Их можно обрабатывать как две автономных сущности.

Из этого и родилась концепция CSS-in-JS, сфокусированная на двух отдельных процессах: генерации CSS-файла для статического контента, и сохранения стилей рядом с компонентами.

Все уехало в JS.

Теперь в JS можно найти и стили, и верстку, и собственно код.

Теперь все в JS и это хорошо

Стоит сделать еще одно отступление — теперь в продуктовую сторону.

Любому продукту в разработке или развитии важно иметь возможность "перехода" в другую сторону. Это действует на любом из уровней:

  • Возможность превратить визуальный компонент в компонент с минимальной логикой добавлением строчки кода — это очень круто. Необходимость переписывания его с нуля — не круто.

  • Дешевое превращение в SPA или в приложение с серверным рендером — это действительно круто, но это очень редко возможно. Разумнее, если это не накладывает издержек, начинать с самого начала с такой платформы.

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

Когда есть единая платформа, в рамках которой одни сущности могут превратиться в другие достаточно дешево, разработка осуществляется чертовски быстро.

В случае с приложением на angular/react/vue это именно так. Они сложные в понимании. Не так сложны, как Angular 1, конечно, но все равно — путь к их осознанию долог, и полугодичных онлайн-курсов не хватает для их понимания. Но они дают возможность за несколько часов сделать то, что раньше делалось несколько недель, а за несколько дней — то, что раньше занимало несколько месяцев.

Впрочем, верно и обратное — многим они не нужны, но их используют, потому что "модно".

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

Когда вы в следующий раз захотите сказать "веб стал очень сложным и раздутым" — подумайте о том, насколько сложно проектировать и делать почтовый клиент уровня google inbox (с интеллектуальными сущностями, включающимися в зависимости от письма), Web IDE типа Cloud9 или интернет-банк.

Но если к вам придет верстальщик и начнет рассказывать про то, что ему нужен react, потому что ему нужна строгая типизация и декораторы для верстки лэндинга, не поддавайтесь на уговоры.

Автор: Jabher

Источник


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js