[Перевод] Цена JavaScript в 2018 году
Процесс работы пользователей с интерактивными веб-сайтами может включать в себя шаг отправки им JavaScript-кода. Часто — слишком большого объёма такого кода. Если на сайте используется очень много JavaScript, это особенно сильно сказывается на мобильных пользователях. Например, вам случалось бывать на мобильных веб-страницах, которые, вроде бы, выглядят как уже готовые к работе, но не реагируют на щелчки по ссылкам или на попытки прокрутить страницу?
JavaScript-код, который попадает в мобильные браузеры, всё ещё остаётся самым дорогостоящим ресурсом, так как он, многими способами, может задержать переход страниц в состояние, в котором с ними можно взаимодействовать. Какую нагрузку на системы создаёт JavaScript в наши дни? Как анализировать сайты? Как ускорить загрузку и обработку браузерами интерактивных веб-страниц? Эдди Османи, перевод материала которого мы сегодня публикуем, решил найти ответы на эти и на многие другие вопросы, встающие перед теми, кто пользуется JavaScript для разработки веб-сайтов в 2018 году.
Общие положения
Взгляните на этот отчёт, демонстрирующий время, необходимое для обработки JavaScript-кода сайта CNN различными устройствами. Он построен на основе измерений, проведённых средствами проекта WebPageTest.org (вот таблица с исходными данными для этого отчёта, тут есть ещё данные по сайту Walmart).
Время, необходимое для обработки JS-кода сайта cnn.com различными устройствами
Как видно, телефон высшего класса (iPhone 8) справляется с задачей обработки JS-кода примерно за 4 секунды. Телефону среднего уровня (Moto G4) на решение той же задачи надо уже примерно 13 секунд. А бюджетному, хотя и современному устройству, такому, как Alcatel 1X, требуется около 36 секунд.
Сегодня мы поговорим о тех стратегиях, которые могут применять веб-разработчики для того, чтобы, с одной стороны, создавать удобные и современные сайты, а с другой — чтобы обеспечивать эффективную загрузку, обработку и функционирование JavaScript-составляющей этих сайтов. Вот, вкратце, основные моменты нашей беседы, которая, кстати, основана на моём недавнем выступлении:
- Для того чтобы веб-проекты работали быстро, нужно загружать лишь JavaScript-код, необходимый для текущей страницы. Использование технологий разделения кода (code splitting) позволяет организовать как можно более оперативную загрузку того, что пользователю точно понадобится, и применить методику ленивой загрузки (lazy load) для других фрагментов кода. Благодаря такому подходу страница получает шанс быстрее, чем в других случаях, загрузиться, и быстрее дойти до состояния, когда с ней можно будет взаимодействовать. Если вы используете системы, в которых, по умолчанию, применяется разделение кода, основанное на маршрутах, это меняет ситуацию в лучшую сторону.
- Придерживайтесь ограничений, установленных в отношении параметров проекта, так называемого «бюджета производительности» (performance budget), и научитесь их соблюдать. Так, например, рассчитывайте на то, что размер минифицированного и сжатого JS-кода, необходимого для страниц, предназначенных для мобильных устройств, не должен превышать 170 Кб. При преобразовании таких материалов к обычному виду получается примерно 700 Кб кода. Подобные ограничения имеют огромную важность для успеха проекта, однако, только они одни не могут чудесным образом сделать медленный сайт быстрым. Здесь играют роль командная культура, структура и средства контроля за исполнением правил. Разработка проекта без бюджета способствует постепенному падению производительности и может привести к неприятным последствиям.
- Научитесь проводить аудит JavaScript-бандлов (сборок) и сокращать их размер. Весьма вероятно, что клиентам приходится загружать полные версии библиотек, в то время как для работы проекта нужны лишь их части. Возможно, в проект включены полифиллы для браузеров, которые им не нужны, не исключено и дублирование кода.
- Каждое взаимодействие пользователя с сайтом — это начало нового периода ожидания, по истечении которого с сайтом можно будет работать (это то, что называют «время до интерактивности», TTI, Time to Interactive). Оптимизации стоит рассматривать в этом контексте. Размер передаваемого кода весьма важен для медленных мобильных сетей, а время, необходимое на парсинг JavaScript-кода — для устройств со скромными вычислительными возможностями.
- Если использование JavaScript на стороне клиента не приводит к улучшению пользовательского опыта — подумайте о том, нужно ли применять JS в данной ситуации. Возможно, в подобном случае быстрее было бы отрендерить HTML-код на сервере. Подумайте об ограничении использования клиентских веб-фреймворков, о применении их только для формирования страниц, которые совершенно не могут без этого обойтись. И рендеринг на сервере, и рендеринг на клиенте, при неправильном использовании этих технологий, превращаются в источник серьёзнейших проблем.
Современные веб-проекты и проблема чрезмерного использования JavaScript
Когда пользователь обращается к вашему сайту, то вы, вероятно, отправляете ему целую кучу файлов, многие из которых являются скриптами. С точки зрения веб-браузера это выглядит примерно так.
Примерно так чувствует себя браузер, который заваливают файлами
Как бы я ни любил JavaScript, я не могу не признавать тот факт, что он всегда представляет собой самую дорогостоящую, самую тяжёлую для обработки браузерами часть сайта. Собственно, мне хотелось бы рассказать о том, почему JavaScript может стать главной проблемой сайта.
JavaScript — самая тяжёлая часть сайта
По данным июльского отчёта HTTP Archive, посвящённого использованию JavaScript, средняя веб-страница в наши дни предусматривает использование примерно 350 Кб минифицированного и сжатого JavaScript-кода. Этот код распаковывается в нечто вроде скрипта размером 1 Мб, который нужно обработать браузеру. Для того чтобы мобильный пользователь смог взаимодействовать с такой страницей, ему придётся ждать более 14 секунд.
Средняя страница, содержащая 350 Кб сжатого JS-кода, становится интерактивной на мобильном устройстве примерно через 15 секунд
Если вы не знаете точно, как ваши JavaScript-бандлы влияют на то, сколько времени пользователям приходится ждать до того момента, когда они смогут взаимодействовать с вашим сайтом — взгляните на инструмент Lighthouse.
Время загрузки данных по мобильным сетям и их обработка на не самом быстром процессоре делают серьёзный вклад во время ожидания подготовки страницы к работе на мобильных устройствах.
Проанализируем состояние дел в области мобильных сетей, взглянув на данные OpenSignal. На следующем рисунке, слева, показана доступность 4G-сетей в мире (чем темнее цвет, которым закрашена территория страны — тем выше доступность), справа показаны скорости передачи данных (опять же — чем темнее — тем выше скорость). Страны, территория которых закрашена серым, в исследование не включены. Тут стоит отметить, что в сельской местности, даже в США, скорость мобильной передачи данных может быть на 20% медленнее, чем в городах.
Доступность 4G-сетей и скорость передачи данных
Выше мы говорили о том, что для загрузки и разбора 350 Кб минифицированного и сжатого JS-кода требуется определённое время. Однако если взглянуть на популярные сайты, окажется, что они шлют пользователям намного больше кода. Данные, представленные на рисунке ниже, взяты отсюда. Они представляют собой размеры распакованных JavaScript-бандлов различных известных веб-ресурсов, вроде Google Sheets, распакованный JS-код которого на настольных платформах занимает 5.8 Мб.
Размеры распакованных JavaScript-сборок для различных ресурсов
Как видите, и на настольных и на мобильных платформах браузерам, для работы с различными сайтами, иногда приходится обрабатывать по несколько мегабайт JS-кода. Главный вопрос здесь — можете ли вы позволить себе использовать такие большие объёмы JavaScript?
JavaScript — это не бесплатно
По словам Алекса Рассела, сайты, для работы которых требуются очень большие объёмы JavaScript, попросту недоступны для широких слоёв пользователей. По статистике пользователи не ждут (и не будут ждать) загрузки подобных ресурсов.
Можете ли вы себе это позволить?
Если вам приходится отправлять пользователям слишком большие объёмы JS-кода — подумайте о применении технологии разделения кода для разбиения бандлов на небольшие части, или об уменьшении объёма кода с использованием алгоритма tree-shaking.
В состав JS-бандлов современных сайтов часто входит следующее:
- Клиентский веб-фреймворк или библиотека пользовательского интерфейса.
- Средство для управления состоянием приложения (например, Redux).
- Полифиллы (часто для современных браузеров, которым они не нужны).
- Полные версии библиотек, а не только те их части, которые реально используются (например — вся библиотека Lodash, библиотека Moment.js в варианте с поддержкой всех региональных стандартов).
- Набор компонентов пользовательского интерфейса (кнопки, заголовки, боковые панели, и так далее).
Всё, что перечислено выше, вносит вклад в общий размер кода, который необходимо принять и обработать браузеру пользователя. Естественно, чем больше кода — тем больше времени нужно на то, чтобы браузер смог привести страницу в рабочее состояние.
Процесс загрузки веб-страницы похож на движущуюся в проекторе киноплёнку, на которой запечатлены три ключевых шага, отвечающих на следующие вопросы:
- Это происходит? (Is it happening?).
- Какая от этого польза? (Is it useful?).
- Можно ли этим пользоваться? (Is it usable?).
Вот как можно представить эти шаги, которые, в свою очередь, можно разбить на более мелкие «кадры», если продолжать аналогию с киноплёнкой.
Загрузка страницы — это процесс. В последнее время фокус внимания веб-индустрии смещается к показателям, которые отражают ощущения пользователей от работы с веб-страницами. Вместо того, чтобы отдавать всё внимание событиям onload
или domContentLoaded
, теперь мы задаёмся вопросом о том, может ли пользователь по-настоящему работать со страницей. Если он щёлкнет что-нибудь на странице, последует ли за этим немедленная реакция?
Процесс загрузки веб-страницы
- На шаге «Это происходит?» сайт может приступить к передаче каких-то данных браузеру. Здесь можно задаться вопросами о том, зафиксировано ли обращение браузера пользователя к серверу (например, по нажатию некоей ссылки), и о том, приступил ли сервер к формированию ответа.
- На шаге «Какая от этого польза?» сайт выводит на экран некий текст или другое содержимое, которое позволяет пользователю, во-первых, узнать что-то полезное, а во-вторых, способно его заинтересовать.
- На шаге «Можно ли этим пользоваться?» пользователь может начать полноценное взаимодействие с сайтом, которое может привести к неким событиям.
Интерактивные страницы и их проблемы
Выше мы упоминали такой показатель, как время до интерактивности (Time to interactive, TTI). Поговорим о нём подробнее. Ниже, на анимированном рисунке, который подготовил Кевин Шааф, можно видеть, как страница, не все материалы которой загружены и обработаны, заставляет пользователя думать, что он может выполнить некое действие, но, на самом деле, из-за того, что соответствующий JS код пока не до конца обработан, выполнить это действие нельзя.
Пользователей расстраивают страницы, которые слишком долго готовятся к работе
Для того чтобы страница была интерактивной, она должна иметь возможность быстро реагировать на воздействия пользователя. Маленькие объёмы JS-кода, приводящие страницы в действие, способствуют сокращению времени, необходимого для подготовки страниц к работе.
Если пользователь щёлкает по ссылке или прокручивает страницу, ему нужно видеть, что, в ответ на его действия, что-то происходит. Если страница не реагирует на воздействия пользователей, им это не нравится.
Вот отчёт, сформированный в тестовой среде средствами Lighthouse, содержащий набор показателей (здесь есть и Time to interactive), ориентированных на то, как страницу воспринимают пользователи.
Отчёт Lighthouse, включающий в себя показатели, отражающие восприятие страницы пользователем
Нечто подобное тому, что показано на предыдущем рисунке, происходит тогда, когда в некоем проекте используется серверный рендеринг, а клиенту передаются и результаты того, что сформировано на сервере, и JS-код, который используется для «оживления» пользовательского интерфейса (он, например, может подключать обработчики событий и некие дополнительные механизмы, отвечающие за поведение страницы).
Когда браузер занимается обработкой подобного кода, подключающего события, которые, вероятно, понадобятся пользователю, скорее всего, всё это будет выполняться в том же самом потоке, который обрабатывает пользовательский ввод. Это — так называемый главный поток.
Загрузка слишком большого объёма JavaScript-кода средствами главного потока (например, такое происходит при использовании тега ) плохо влияет на время до интерактивности. Загрузка JS-кода, который планируется выполнять в веб-воркерах или кэширование с помощью сервис-воркеров, не оказывают столь сильного негативного влияния на TTI.
Вот видео, в котором показан пример работы пользователя с неудачным сайтом. Обычно пользователь может спокойно устанавливать флажки или щёлкать по ссылкам. Однако если сымитировать блокировку главного потока, пользователю уже ничего сделать не удастся — ни установить флажок, ни щёлкнуть по ссылке.
Старайтесь свести к минимуму ситуации, в которых может быть заблокирован главный поток. Вот материал, в котором можно найти подробности об этом.
Мы видим, как команды, с которыми мы сотрудничаем, страдают от того, что JavaScript воздействует на TTI на сайтах многих типов.
JavaScript способен задержать выход видимых элементов в интерактивный режим
Подобная ситуация может быть серьёзной проблемой для многих компаний. Выше показано несколько примеров из поисковика Google. На экране появляются элементы, выглядят они так, как будто с ними уже можно работать, но, если за их функционирование отвечают слишком большие объёмы JS-кода, в рабочий режим они выходят с некоторой задержкой. Это может не понравиться пользователям. В идеале нужно, чтобы всё, с чём может взаимодействовать пользователь, приходило бы в рабочее состояние как можно быстрее.
TTI и мобильные устройства
Вот показатели TTI для сайта news.google.com при использовании медленного 3G-подключения к интернету. Здесь можно посмотреть данные, на основе которых построена эта диаграмма. Измерения произведены средствами WebPageTest и Lighthouse.
TTI для news.google.com
Проанализировав эти данные, можно увидеть, что между устройствами самой низкой и самой высокой категорий наблюдается серьёзный разрыв. Так, у самого мощного устройства в тесте TTI составляет около 7 секунд. У самого простого — это уже 55 секунд.
Тут у нас возникает вопрос о том, каким должен быть показатель TTI. Мы полагаем, что стоит стремиться к тому, чтобы страницы становились бы интерактивными на устройствах среднего класса, подключённых к медленным 3G-сетям, менее чем за 5 секунд.
Стоит стремиться к TTI в 5 секунд
Возможно, тут вы скажете, что все ваши пользователи обладают топовыми телефонами и подключены к быстрым сетям. Однако, так ли это на самом деле? Возможно, некто подключён к «быстрой» Wi-Fi-сети в каком-нибудь кафе, но, на самом деле, ему доступна лишь скорость, характерная для 2G или 3G-соединений. Оценивая возможности пользователей нельзя сбрасывать со счетов разнообразие устройств и способов выхода в сеть, применяемых ими.
Влияние уменьшения размеров JS-кода на TTI
Вот несколько примеров того, как уменьшение размеров JS-кода страниц повлияло на TTI.
- Проект Pinterest уменьшил JS-бандлы с 2.5 Мб до менее чем 200 Кб. Время до интерактивности снизилось с 23 секунд до 5.6 секунд. Доход компании вырос на 44%, число подписок выросло на 753%, количество активных еженедельных пользователей мобильной версии сайта выросло на 103%.
- Сайт AutoTrader сократил JS-бандл на 56%, что привело к уменьшению TTI примерно на 50%.
- Ресурс Nikkei.com урезал размер JS-бандла на 43%, что позволило улучшить TTI на 14 секунд.
Эти результаты позволяют говорить о том, что сайты стоит проектировать в расчёте на гибкую мобильную среду, и при этом стараться, чтобы они не были привязаны к большим объёмам JavaScript-кода.
Проектировать сайты стоит в расчёте на гибкую мобильную среду
На TTI влияет много всего. Например, на этот показатель может подействовать использование для просмотра сайта мобильного устройства, сетевые возможности которого ограничены неким тарифным планом, на TTI может повлиять то, что пользователь работает через общедоступную, не особенно быструю, точку доступа Wi-Fi, или то, что мобильный пользователь находится в постоянном движении, периодически теряя сеть.
Когда с вашим сайтом работает кто-то, находящейся в ситуации, похожей на те, которые мы только что описали, и при этом, для обеспечения работоспособности ресурса требуется загрузить и обработать большой объём JS-кода, для пользователя сеанс взаимодействия с сайтом может окончиться пустым экраном. Или, если сайт всё же хоть что-то выведет на экран, может понадобиться очень долго ждать, прежде чем с ним можно будет работать. Подобные проблемы, в идеале, можно смягчить, просто сокращая размер JS-кода, необходимого для работы сайтов.
Почему JavaScript — это так дорого?
Для того чтобы понять, почему подготовка JavaScript-кода страниц к работе способна создать огромную нагрузку на систему, давайте поговорим о том, что происходит, когда сервер отправляет данные браузеру.
Итак, всё начинается с того, что пользователь вводит в адресную строку браузера URL сайта, на который он хочет попасть.
Всё начинается с ввода URL в адресную строку браузера
Затем запрос отправляется серверу, который возвращает браузеру HTML-разметку. Браузер разбирает эту разметку и находит ресурсы, необходимые для формирования страницы: CSS, JavaScript, изображения. Затем браузеру нужно всё это запросить у сервера и обработать.
Именно по такому сценарию всё происходит, например, при работе с Google Chrome.
Сложность во всём этом процессе вызывает то, что JavaScript, в итоге, оказывается узким местом всей системы. В идеале нам хотелось бы, чтобы браузер быстро вывел графическое представление страницы, после чего с ней уже можно было бы взаимодействовать. Но, если JavaScript — это узкое место, то, после вывода чего-либо на экран, пользователь вынужден беспомощно разглядывать то, с чем он не может работать.
Наша задача заключается в том, чтобы JavaScript перестал бы быть узким местом в современных сценариях взаимодействия пользователей с веб-ресурсами.
Как ускорить работу с JavaScript?
Задача ускорения JavaScript может быть разбита на несколько подзадач. Время, которое тратится на всё то, что связано с JS, складывается из времени загрузки, парсинга, компиляции и выполнения кода.
Скорость JavaScript складывается из скорости загрузки, парсинга, компиляции и выполнения кода
Всё это значит, что скорость нам нужна и при передаче кода, и при его обработке.
Если слишком много времени тратится на парсинг и компиляцию скрипта в JS-движке, это влияет на то, как скоро пользователь сможет взаимодействовать со страницей.
Рассмотрим некоторые данные о вышеупомянутых процессах. Вот подробные сведения о том, на что V8, JavaScript-движок, используемый в Chrome, тратит время при обработке страниц, содержащих скрипты.
Шаги парсинга и компиляции кода занимают 10–30% времени в V8 при загрузке страницы
Оранжевым выделены фрагменты, представляющие собой время, необходимое на парсинг кода популярных сайтов. Жёлтым представлено время компиляции. Вместе два эти этапа занимают около 30% общего времени, требуемого на обработку JS-кода страницы. 30% — это серьёзная цифра.
В Chrome 66 V8 занимается компиляцией кода в фоновом потоке, что способно сэкономить до 20% времени компиляции. Однако парсинг и компиляция всё ещё остаются чрезвычайно дорогими операциями, поэтому редко можно увидеть большой скрипт, который начинает выполняться менее чем через 50 мс. после загрузки, даже если его компиляция выполняется в фоновом потоке.
Чем JavaScript-код отличается от других ресурсов?
Стоит учитывать, что время, необходимое, например, на обработку скрипта размером 200 Кб, и на обработку изображения, имеющего такой же размер, серьёзно различается. В этом примере объём данных, передаваемых по сети, может быть одинаковым, время на их передачу тоже. Этого нельзя сказать о затратах ресурсов, необходимых на то, чтобы превратить полученные данные в нечто такое, с чем можно работать.
200 Кб JavaScript-кода и JPEG-файл такого же размера — это разные вещи
JPEG-изображение нужно декодировать, растеризовать и вывести на экран. А JS-бандл надо, если рассматривать это упрощённо, загрузить, распарсить, скомпилировать, выполнить. На самом же деле движку приходится решать и другие задачи в процессе обработки JS-кода. В целом, стоит учитывать, что на обработку JavaScript-кода, размеры которого, в байтах, сопоставимы с размерами других материалов, тратится гораздо больше системных ресурсов.
Одна из причин, по которой к вопросу скорости обработки JavaScript-кода браузерами в последнее время привлечено столько внимания, заключается в невероятном распространении мобильных технологий.
Мобильный веб и разнообразие устройств
В мире мобильного веба существуют самые разные устройства. Если попытаться, довольно упрощённо, классифицировать их по стоимости, то это телефоны начального уровня, стоящие в районе 30$, устройства среднего уровня, стоимость которых не превышает 200$, и топовые аппараты, цена которых находится в районе 1000$.
Различные мобильные устройства
Если обстоятельства сложатся удачно, то сайту придётся работать на аппаратах среднего и высшего уровня. Однако в реальности не у всех пользователей есть подобные устройства.
Так, большинство пользователей может работать в интернете с аппаратов начального и среднего уровня. При этом, даже если ограничиться этими двумя уровнями, разброс возможностей устройств, входящих в них, может быть очень большим. Скажем, процессоры в некоторых из них будут работать на полной скорости, а в некоторых их частота может быть понижена ради энергосбережения или для того, чтобы устройства не перегревались.
Сравнимые процессоры могут иметь разные размеры кэшей. В устройствах, в конце концов, могут использоваться совершенно разные процессоры, не говоря уже о других компонентах систем. Как результат, время, необходимое на обработку ресурсов, таких, как JavaScript, будет очень сильно зависеть от характеристик устройств, используемых для просмотра сайтов. Причём, телефоны начального уровня используются по всему миру, даже в США.
Вот результаты исследования используемых в настоящее время Android-смартфонов, проведённого компанией newzoo. Как видно, ОС Android установлена на 75,9% используемых телефонов, при этом ожидается, что в 2018 году к ним добавится ещё 300 миллионов устройств. Многие из этих новых устройств будут бюджетными.
Android-смартфоны в 2018 году
Посмотрим, сколько времени занимает парсинг и компиляция JavaScript на различных современных устройствах. Вот исходные данные.
Время, необходимое для обработки (парсинга и компиляции) 1 Мб несжатого JS-кода (это, например, может быть около 200 Кб минифицированного кода, сжатого с помощью gzip). Замеры произведены вручную, на реальных устройствах.
В верхней части диаграммы находятся устройства высшего класса, вроде iPhone 8, которые обрабатывают скрипты сравнительно быстро. Если спуститься пониже, то там уже находятся устройства среднего уровня, вроде Moto G4, и совсем простой Alcatel 1X. Разница между этими устройствами заметна невооружённым глазом.
Со временем телефоны, работающие под управлением Android, становятся дешевле, но не быстрее. Обычно в дешёвых телефонах используются слабые процессоры с небольшим L2/L3 кэшем. В результате, если ориентироваться на устройства высшего уровня, можно совершенно не учесть нужды среднего пользователя, таким устройством не обладающего.
Вернёмся теперь к примеру с реальным сайтом, которого мы уже касались. Измерения проведены средствами WebPageTest, вот исходные данные.
Время, необходимое для обработки JS-кода сайта cnn.com различными устройствами
На iPhone 8 (с использованием чипа A11) обработка выполняется на 9 секунд быстрее, чем на телефоне среднего уровня. Речь идёт о том, что на iPhone 8 сайт станет интерактивным на 9 секунд раньше.
Теперь, когда, когда WebPageTest поддерживает Alcatel 1X (этот телефон продавался в США примерно по 100$, его распродали на старте продаж), мы можем просмотреть «раскадровку» загрузки сайта cnn.com на телефонах начального и среднего уровня. У Alcatel 1X полная загрузка сайта с использованием 3G-сети заняла 65 секунд. Это даже не «медленно». Это просто недопустимо.
Загрузка cnn.com телефонами Alcatel 1X, Moto G gen 1, Moto G4
Это исследование подсказывает, что нам, вероятно, надо перестать считать, что все наши пользователи работают в быстрых сетях на мощных устройствах. Поэтому приложения стоит тестировать в реальных сетях и на реальных аппаратах. Разнообразие мобильных устройств, на которых приходится работать сайтам — это реальная проблема.
Не стоит считать, что все пользователи пользуются быстрыми сетями и мощными устройствами
Илья Григорик говорит, что изменчивость — это то, что убивает пользовательский опыт. Даже быстрые устройства могут иногда работать медленно. И быстрые сети могут бы медленными. Изменчивость способна сделать медленным абсолютно всё, что угодно.
В то время как изменчивость способна убить пользовательский опыт, разработка веб-проектов в расчёте на не самые производительные устройства позволяет сделать так, чтобы и «быстрые», и «медленные» пользователи чувствовали бы себя комфортно. Если ваша команда может проанализировать статистические сведения и понять, какие устройства используются для работы с вашим сайтом, это даст вам подсказку касательно того, какое устройство, вероятно, стоит держать в офисе и использовать его для тестирования сайта.
Тестировать сайты стоит на реальных устройствах, подключённых к реальным сетям
Если вариант с собственным телефоном среднего уровня вам не подходит — проект WebPageTest предлагает доступ к настроенным телефонам Moto G4 при выборе мобильных конфигураций тестирования. Там есть и другие конфигурации.
Кроме того, тесты надо проводить в сетях, в которых работают типичные пользователи. Выше я говорил о том, как важно тестировать сайты на телефонах начального и среднего уровня, а Брайан Холт сделал следующее отличное замечание на эту тему: очень важно знать свою аудиторию. Он говорит, что знание аудитории и оптимизация производительности приложения с учётом нужд аудитории — это крайне важно.
Знайте свою аудиторию
Тут надо отметить, что не каждый сайт должен хорошо работать на устройстве начального уровня, подключённом к 2G-сети. Таким образом, ориентация на производительные устройства — это тоже вполне нормальная линия поведения.
Вот отчёт, который можно получить, пройдя по пути Google Analytics → Audience → Mobile → Devices. Он демонстрирует сведения об устройствах и операционных системах посетителей сайта.
Отчёт из Google Analytics
Многие ваши пользователи могут быть в верхней части диапазона, или они могут быть распределены по разным диапазонам. Главное — знать, какие устройства используются для работы с вашими сайтами, что позволит принимать обоснованные решения о том, что важно, а что нет.
Оптимизация для медленных сетей и маломощных устройств
Если вам нужна скорость в применении к JavaScript — обращайте внимание на время загрузки материалов в медленных сетях. Вот какие улучшения можно внести в проект в данном направлении: уменьшение объёма кода, минификация кода, сжатие (с использованием gzip, Brotli, Zopfli).
Время загрузки чрезвычайно важно для тех, кто пользуется медленными сетями
Не забудьте и о кэшировании данных при обслуживании повторных визитов.
Время парсинга JavaScript — это крайне важный показатель для маломощных телефонов.
Время парсинга кода — крайне важный показатель для телефонов с медленными процессорами
Если вы являетесь бэкенд-разработчиком, или разработчиком полного цикла, вы представляете себе, какой процессор, дисковое пространство и сетевые возможности можно получить за определённую цену.
Учитывая то, что мы создаём сайты, которые всё сильнее и сильнее полагаются на JavaScript, мы иногда платим за те неоправданно большие материалы, которые отправляем пользователям, причём так, что эти расходы не всегда можно чётко распознать.
Уменьшение объёмов JavaScript-кода, отправляемого пользователям
Здесь нам подойдёт всё, что позволяет уменьшить объёмы JS-кода, отправляемого пользователям, сохранив при этом удобства, которые даёт им сайт. Один из вариантов, который делает такой сценарий возможным — это разделение кода (code splitting).
Разделение больших, монолитных JS-бандлов можно выполнять, основываясь на том, какой код необходим для вывода страницы, маршрута или компонента. Особенно хорошо, если разделение кода изначально поддерживается в используемом вами наборе инструментов.
Разделение кода — это хорошо
Идею разделения кода можно сравнить с тем, что вместо того, чтобы отправлять пользователям целую огромную пиццу, роль которой тут играет большой JS-бандл, вы отправляете им эту пиццу кусочками. Каждый такой кусочек кода содержит исключительно то, что нужно для работы текущей страницы.
Разделение кода хорошо поддерживают многие современные библиотеки и фреймворки благодаря бандлерам вроде webpack и Parcel. Руководства по выполнению подобных операций имеются для React, Vue.js и Angular.
Разделение кода в React
Рассмотрим пример добавления возможностей по разделению кода в React-приложении с использованием React loadable — компонента высшего порядка, который оборачивает динамические команды импорта в API, с которым удобно работать в React, тем самым добавляя в приложение возможности по разделению кода в конкретном компоненте.
Вот текст программы до добавления возможностей по разделению кода.
import OtherComponent from './OtherComponent';
const MyComponent = () => (
);
Вот изменённый код.
import Loadable from 'react-loadable';
const LoadableOtherComponent = Loadable({
loader: () => import('./OtherComponent'),
loading: () => Loading...,
});
const MyComponent = () => (
);
Результаты внедрения систем разделения кода
Многие крупные проекты уже ощутили на себе преимущества внедрения систем разделения кода.
После внедрения технологи