Встретил интересное мнение забугорного программиста, и проникся, так как сам стараюсь минимизировать JS в проектах.
Перевод статьи Matt Reyer — A JavaScript-Free Frontend
Предисловие
Я разработал первую версию Slimvoice на базе Angular 1 с бэкэндом на Node.js и MongoDB в 2014 году (тогда все они были в моде). В 2015 году принял решение полностью изменить UI и переписал проект на React. Оглядываясь назад, я понимает, что — это было неудачным решением.
В новой версией я хотел доказать, что возможно обеспечить удивительный UX с отличным дизайном, в то же время значительно уменьшить сложность кода, максимально повысить надежность, при этом понизив ресурсные затраты для конечного пользователя . У меня получился интерфейс, которым я действительно горжусь.
В статье я рассказываю о решениях, которые принял в отношении веб-интерфейса, и делюсь некоторыми приемами UI без JavaScript, которые выработал на своём пути.
Single Page Apps
Кризис избыточного веса веб-сайтов, в целом, не идёт на поправку. Я устал от медленной загрузки сайтов, которые при этом не очень надежны. Кто-нибудь в последнее время пытался изменить описание карточки в Asana? Это чертовски медленная работа приложения… UI тормозит без веской причины, когда вы просто печатаете.
Во-первых, я живу в сельской местности, где скорость соединения с Интернетом составляет всего 2 Мбит/с. Загрузка «горячего» кэша Asana занимает 14 секунд . Во-вторых, приложение состоит из более чем 10 МБ несжатого JavaScript (изображено на рисунке внизу). Это огромный размер для исполняющего кода! Это вообще нормально?
С Progressive Web App среднего уровня сложности вам нужна целая команда разработчиков, чтобы оно нормально работало. Большую часть кода вы получаете только чтобы заработал frontend.
Шутки в сторону. Загрузка компонентов приложения в правильном порядке — определённая проблема, на решение которой мы добавляем еще больше программного обеспечения (см. Redux и его друзья).
Что если бы мы могли покончить со всем этим?
Чем больше у вас кода, тем вы менее гибкие. Это как тягучая смола. Библиотеки JavaScript постоянно растут, и я не думаю, что люди критически оценивают фактическую потребность в них. Люди часто измеряют JavaScript в килобайтах или мегабайтах, как будто это по умолчанию справедливая плата за пользование приложением. Но это не так. А ведь вы ещё должны дождаться, пока процессор проанализирует и выполнит весь этот код. Все это наслаивается друг на друга…
Хорошо, ближе к делу. Я обнаружил секрет развития frontend, которым поделюсь с вами. Мало кто знает об этом, так что не отвлекайтесь.
- Ваш интерфейс не сломается, если вы не будете использовать JavaScript.
- HTML не перестанет работать.
- Меньше кода всегда лучше.
Привет Elm — ты очень крут!
Простой HTML и CSS
Для Slimvoice я хотел пойти вразрез с современной технологией JS и сделать приложение полностью серверным. Вы можете сказать:
«Но Мэт! Пользователь должен каждый раз перезагружать страницу при использовании приложения, а это происходит довольно медленно!»
На что я скажу
«Ха! А вот и нет…»
Все мои ресурсы сжаты и кэшированы, что оставляет для передачи только HTML. У меня нет загрузочных лоадеров. В конечном счете — моё приложение быстрее, чем многие PWA, которыми я пользуюсь.
Не верьте мне на слово, откройте Инструменты разработчика в браузере и сравните Slimvoice с популярными PWA. Ах да, и у меня нет обработчика исключений JavaScript при отладке в консоли. Либо страница загрузилась, либо нет.
Checkbox/Label
Конечно, есть некоторые взаимодействия, при которых перезагрузка страницы была бы неприемлемой. Вот мой любимый трюк, чтобы добавить интерактивность к статической HTML-странице. Я использовал это в Slimvoice для всех выпадающих, модальных и фильтрующих UI элементов, и всё это работает без JavaScript.
- Создайте div, содержащий произвольный элемент, который вы хотели бы показать/скрыть:
- Непосредственно над ним добавьте инпут:
<input type="checkbox" id="myToggle" style="display: none;">
это создаст невидимый checkbox в DOM
- Какой бы DOM-узел вы не использовали в качестве переключателя, оберните его в:
<label for="myToggle"></label>
где атрибут for будет соответствоватьid checkbox
- Используйте CSS, чтобы все это заработало:
#myToggledUI {
display: none;
}
#myToggle:checked ~ #myToggledUI {
display: block;
}
Этот CSS говорит, что элемент #myToggledUI непосредственно предшествующий отмеченному элементу #myToggle должен быть показан, иначе скрыт. Оператор вообще ~ очень крутой! Полный рабочий пример.
А вот модальное окно, созданное с label, div и checkbox. Кнопка «Отмена» — это еще один label для того же checkbox, поэтому нажатие на него — модальное окно закрывает.
За модальным окном находится серый фон (position: fixed;), который также является label для checkbox, поэтому нажатие за пределами модального окна закрывает его.
Нет React компонентов. Нет слушателей события клика. Только простой и чистый HTML.
Я не делал этого в примере, но вы всегда можете добавить любые CSS переходы, которые вам нравятся. Здесь нет ReactCSSTransitionGroup.
Элементы details и summary
Теги details и summary используются редко, но во многих случаях вполне приемлемы. Я использовал их на странице благодарностей, чтобы показать/скрыть лицензии на различные части программного обеспечения с открытым исходным кодом, которое я использовал в Slimvoice.
Быстро. Легко. Нет JavaScript. Работает везде.
Жаль, что вы не можете контролировать их внешний вид, но я не думаю, что создание маленького треугольника раскрытия, соответствующего стандартам вашего бренда, стоит того, чтобы навязать пользователю несколько мегабайт JavaScript.
Формы и проверка входных данных
Многие поля ввода имеют встроенные функции проверки. Документация Mozilla является исчерпывающей.
- Не забывайте об required атрибуте, который запрещает отправку формы до тех пор, пока не будет заполнено определенное поле
- Поля ввода чисел имеют атрибуты min, max и step
- Текстовые поля могут быть типа email или пользовательского pattern
- Текстовые поля имеют атрибуты minlength и maxlength
- :valid и :invalid CSS-селекторы позволяют улучшить UX
Да прибудет чистота
Я действительно использовал некоторый JavaScript в новом Slimvoice, но только когда взаимодействие не могло быть воспроизведено любым другим способом. Например, я реализовал нечеткий поиск в списке клиентов, чтобы вы могли легко фильтровать клиентов. Взгляните на код.
Я решил, что очень важно, чтобы позиции счетов-фактур можно было сортировать с помощью перетаскивания, поэтому использовал Mithril для UI редактирования счетов. Это единственная JS-зависимость во всем проекте (и только на одной странице), и когда у меня будет время в будущем, я с удовольствием избавлюсь от неё.
В моём приложении так мало JavaScript, что даже если я его минифицирую — это не принесёт значительного прироста производительности. Взгляните на мой код.
Будущее
Простые HTML инпуты покрывали большинство моих потребностей, но я обнаружил, что хочу больше инноваций в спецификации HTML, чтобы охватить больше полей ввода и полностью устранить потребность в JavaScript.
- Почему у нас не может быть стандартного поискового элемента, который фильтрует список на стороне клиента (аналогично тому, как ng-repeat | filter: работает в Angular 1)?
- Разве стандартный HTML-элемент для сортировки с помощью перетаскивания не будет крут?
- Более продвинутая функциональность проверки, например, сравнение равенства двух разных полей формы.
- Способность выполнить вышеупомянутый трюк с модальным окном/checkbox без ощущения хака и написания странного CSS.
Почему настройки UI в спецификации HTML застоялись и переложили процесс создания пользовательских элементов на плечи JavaScript?
Я думаю, что иметь более надежный набор стандартных элементов UI гораздо важнее, чем WebVR, WebBluetooth или любой другой маразм, который разрабатывается в наши дни.
Заключение
Это работает? Безусловно! Полная перезагрузка самой большой страницы через Интернет составляет 230 КБ. Поскольку я всё кеширую и сжимаю, каждый последующий просмотр страницы составляет около 6 КБ; гораздо меньше, чем SPA, которые я видел с эквивалентной функциональностью. Slimvoice быстрый и маленький, но не идет на компромисс с UX. Пользователи до сих пор любят это. Убедитесь сами на https://slimvoice.co.
В моём коде нет нет ничего сложного. Я бы чувствовал себя комфортно, передавая свой код кому-то другому, ничего при этом не объясняя. Я не знаю никого, кто бы реально мог сказать такое о frontend, разработанном на React/Webpack.
Я программировал более десяти лет и шесть лет занимался разработкой веб-приложений. Эти годы доказали, что преимущества JavaScript и PWA не так уж велики, но их недостатки огромны и часто игнорируются. В обозримом будущем я полностью покончу с JavaScript как с основным языком.
- Вам, вероятно, не нужно Progressive Web App. Серьезно оцените, нуждается ли ваше приложение в такой сложности. Руководитель или клиент может потребовать PWA, потому что это круто и популярно, и подкрепит потребность множеством сомнительных аргументов. Убедитесь, что его аргументы верны.
- Хватит отслеживать людей. Не позволяйте другим компаниям делать это от вашего имени. Вы выживете без Google Analytics. Вы выживете без Intercom. Обслуживайте все с вашего собственного домена.
- Не бойтесь. Вы можете разработать «всё» самостоятельно! Вам не нужны фреймворки!
- Не следуйте за хайпом. Принимайте критические решения о том, почему один подход лучше другого, несмотря на то, что говорится на рекламных страницах или на то, что делают все остальные. Люди, продающие новые классные инструменты, обычно скрывают их недостатки. У всего есть цена.
Я очень доволен тем, как появилась эта версия Slimvoice, но, конечно, ищу способы снизить использование JavaScript до нуля. Я был бы рад ответить на любые вопросы о дизайне или опыте разработки.
И, конечно же, спасибо моей замечательной жене Ruth Reyer, которая помогла с UI и подтолкнула меня написать этот пост!