Друзья, всем привет! Я занимаюсь веб-разработкой уже 13 лет. Помню, как когда-то jQuery был настолько удобным, что повлиял на веб-платформу: так появился querySelector. В конце прошлого года в порыве рефлексии я был удивлен тем, насколько удобней с тех пор стали браузерные API: словно используя сборщики, транспиляторы и автопрефиксеры, я пользовался не веб-платформой, а чем-то другим, надстройкой, которая живет и развивается по своим правилам. Современные браузеры умеют асинхронно загружать js-модули, кешировать состояние страницы при переходах, отслеживать производительность, реагировать на предпочтения пользователя, не говоря уже о десятках API для всех случаев жизни, начиная NFC, заканчивая поддержкой геймпадов.
Но есть один важный вопрос, который нам с вами стоит обсудить: как нам делать веб-приложения, если завтра прилетит волшебник в голубом вертолете и заберет все привычные инструменты?
1. Использовать шаблонизацию
Типичное веб-приложение строит весь UI динамически, постоянно вызывая события перекомпоновки документа и перерасчета стилей. Тем временем уже давно существуют html шаблоны, которые разбираются браузером, но не рендерятся немедленно. Клонировать эти кусочки документа браузеру намного легче, чем разобрать кусок совершенно новой, незнакомой разметки.
Чем вам это не понравится
Склонировав шаблон, нужно будет наполнять его данными (и привязывать обработчики), обращаясь к дочерним элементам через DOM API.
2. Писать модульный js
ES6 модули — это реальность, которая с нами вот уже 5 лет. Они не просто способ разбить приложение на кусочки и загружать функционал по мере надобности. Это способ освободить главный процесс и не делать интерфейс неинтерактивным. Движок не будет останавливать процесс разбора документа и пользователь получит страницу, с которой можно будет взаимодействовать как можно быстрее. При этом загрузив модуль, повторно браузер не пойдет за ним на сервер, что выглядит как дедупликация кода, доступная сразу из коробки! Плюс tree shaking, так как невостребованные модули не будут загружены.
Приятный бонус — при локальной разработке сохранение файла с модулем доставит новый код на открытую страницу без ее перезагрузки (hot reloading из коробки!).
Чем вам это не понравится
Придется думать о приоритетах загрузки скриптов и том, как они повлияют на общее время загрузки модуля. Зато можно произвести очень тонкую настройку.
3. Учитывать обстоятельства
Низкая скорость соединения, отсутствие связи с сетью, низкий уровень заряда, предпочтения пользователя — на все это браузеры тоже реагируют, нужно только немного покопаться.
Network information API и matchMedia(‘prefers-reduced-data’) даст возможность узнать, есть ли сеть, какая пропускная способность нам сейчас доступна, чтобы не передавать лишние данные по сети и увеличить скорость работы, пожертвовав некоторыми необязательными вещами. Такими, например, как изображения или видео.
Battery status API и matchMedia(‘prefers-reduced-motion’) позволит отключить штуки, которые тратят заряд (в первую очередь, анимации).
4. Быть на шаг впереди браузера
При использовании ES6-модулей довольно быстро можно столкнуться с проблемой слишком длинных цепочек зависимостей. Корневой модуль загружает модуль, отвечающий за layout, тот, в свою очередь — модули компонентов и каждое звено этой цепочки увеличивает время загрузки. Решить эту проблему можно с помощью Early hints — это способ на ранней стадии запроса подсказать браузеру, какие еще ресурсы ему понадобятся в ближайшем будущем и загрузить их параллельно, не дожидаясь разбора и последовательных запросов. Получается почти как сборка бандла, но без самой сборки.
Чем вам это не понравится
Для того, чтобы получить видимый эффект, нужен сервер с http/2. Плюс, это будет работать только для navigation-запросов.
Спасибо что дочитали статью до конца, оставайтесь на связи и высказывайте свое мнение о том, что в ней написано.
Да, я понимаю, что все эти советы неприменимы в коммерческой разработке с большими командами. К ним стоит относиться как к экспериментам или даже микро-справочнику современных возможностей веб-платформы.