Переход от jQuery Mobile к современным фреймворкам: ретроспектива
jQuery Mobile 1.0 вышел в ноябре 2011. Его привлекательность была очевидной: строй мобильное приложение на HTML, CSS и jQuery с нативными UI-компонентами для iOS, Android и BlackBerry. Система атрибутов data-role делала мобильные компоненты такими же простыми, как добавление атрибутов к HTML.
Мы построили 12 проектов на jQuery Mobile между 2011 и 2013 годами. Прекратили использовать его в 2014. Оглядываясь назад на эти проекты, история поучительна.
Почему jQuery Mobile победил в 2011
<!-- jQuery Mobile 1.1 - полная страница мобильного приложения -->
<div data-role="page" id="catalog">
<div data-role="header">
<h1>Каталог товаров</h1>
</div>
<div data-role="content">
<ul data-role="listview" data-filter="true" data-filter-placeholder="Поиск...">
<li data-role="list-divider">Новинки</li>
<li>
<a href="#product-1">
<img src="/images/product1.jpg" class="ui-li-thumb">
<h2>Беспроводные наушники</h2>
<p>4 500 сом · В наличии</p>
</a>
</li>
</ul>
</div>
<div data-role="footer" data-position="fixed">
<div data-role="navbar">
<ul>
<li><a href="#home" data-icon="home" class="ui-btn-active">Главная</a></li>
<li><a href="#account" data-icon="user">Аккаунт</a></li>
</ul>
</div>
</div>
</div>
Никакого JavaScript кроме подключений библиотек. Атрибуты data-role делали всё: listview с data-filter="true" автоматически добавлял живой поиск. data-position="fixed" держал footer при прокрутке. Впечатляло для 100 строк HTML.
Стена производительности
Архитектура jQuery Mobile имела критический недостаток: она улучшала весь DOM при загрузке страницы. Каждый атрибут data-role запускал сканирование и улучшение. На странице с 50 элементами - быстро. На странице с 500 - 400мс JavaScript до того, как пользователь что-либо увидит.
// Попытки оптимизации
$.mobile.ajaxEnabled = false; // Отключить AJAX-переходы (главный убийца производительности)
$.mobile.pushStateEnabled = false; // Отключить управление историей
$.mobile.defaultPageTransition = 'none'; // Убрать анимации переходов
Отключение анимаций делало jQuery Mobile приложения быстрее. Они также начинали выглядеть в точности как сайты. Мы получали худшее из обоих миров: медленнее нативного, хуже выглядящее по сравнению с мобильным вебом.
Что мы узнали из провалов
Проект 1 (каталог товаров, 2012): 3000 SKU. Первоначальная загрузка занимала 8 секунд на iPhone 4. Разбили на страницы по 50 элементов - стало приемлемо, но поиск (встроенный фильтр listview) запрашивал DOM, не сервер - он мог фильтровать только видимые элементы. Пришлось перестраивать поиск через AJAX. Половина пользы от jQuery Mobile исчезла.
Проект 4 (заказы для ресторана, 2013): Сложное состояние корзины. Страничная навигация jQuery Mobile хранила состояние в DOM-элементах между переходами. После 5 шагов вперёд и назад DOM накапливал дублированные страничные элементы. Пришлось написать кастомную очистку, запускающуюся при каждом переходе.
Миграция на Backbone + кастомный CSS
К середине 2013 начали мигрировать jQuery Mobile проекты на Backbone.js с написанным вручную CSS:
var ProductListView = Backbone.View.extend({
tagName: 'ul',
className: 'product-list',
render: function() {
this.$el.empty();
this.collection.each(this.renderProduct, this);
return this;
},
filter: function(searchTerm) {
// Фильтр против ВСЕХ товаров, не только видимых
if (searchTerm.length > 2) {
this.collection.fetch({ data: { search: searchTerm }, reset: true });
}
}
});
.product-list li {
display: flex;
align-items: center;
padding: 12px 16px;
min-height: 60px; /* Touch-friendly */
border-bottom: 1px solid #eee;
-webkit-tap-highlight-color: rgba(0,0,0,0.1);
}
.product-list li:active { background-color: #f5f5f5; }
Первый рендер: 40мс против 400мс jQuery Mobile. Разница полностью в том, что не нужно сканировать и улучшать DOM.
Вердикт
jQuery Mobile был правильным ответом для 2011. Он снижал барьер для мобильной веб-разработки и закрывал реальные продуктовые задачи.
Он не был правильным ответом для 2014. Ограничения производительности и распространение техник мобильно-оптимизированного CSS сделали кастомные решения и более быстрыми, и более простыми.
Урок из дуги jQuery Mobile: фреймворки, успешные через снижение барьеров, часто несут вес этого дизайнерского решения по мере взросления экосистемы. То, что делало jQuery Mobile доступным в 2011 - декларативная система улучшения data-role - именно то, что делало его медленным в 2013.
Фреймворки, пришедшие на замену (React, Vue, Ionic), учились на его ошибках: на основе компонентов, а не DOM-сканирования; явный жизненный цикл, а не автоматическое улучшение; производительность как первоклассное ограничение дизайна.