15 апреля 2020

Ускоряем загрузку сайта с помощью Chrome DevTools

Пишу, перевожу и иллюстрирую IT-статьи. На proglib написал 140 материалов. Увлекаюсь Python, вебом и Data Science. Открыт к диалогу – ссылки на соцсети и мессенджеры: https://matyushkin.github.io/links/ Если понравился стиль изложения, упорядоченный список публикаций — https://github.com/matyushkin/lessons
В этом подробном туториале показываем, как применить возможности Chrome DevTools, чтобы ускорить загрузку сайта, используя вкладки Audits, Network и Performance.
Ускоряем загрузку сайта с помощью Chrome DevTools

Знакомьтесь, это Тони – звезда сообщества кошек. Поклонники обожают Тони, им интересно знать, какие у него любимые блюда, так что Тони создал веб-сайт. Фанатам сайт нравится, но кроме комплиментов Тони получает жалобы, что сайт медленно грузится. Тони попросил вас помочь ускорить работу сайта.

Рис. 1. Тони
Рис. 1. Тони

Шаг 1. Проводим аудит сайта

Когда необходимо улучшить производительность, мы начинаем с аудита:

  1. У нас будет базисная линия, с которой можно будет проводить сравнение.
  2. Мы получаем практические советы о том, какие изменения внесут наибольшее влияние.

Подготовимся

Ваша версия может отличаться от этого руководства, так что некоторые функции могут выглядеть иначе или быть недоступными. У нас с Тони, например, это версия 80.0, а свою вы можете узнать, набрав в адресной строке chrome://version/. Ничего страшного – просто имейте в виду, что ваш пользовательский интерфейс может отличаться от приведённых снимков. Сама методология давно укоренилась, так что она вряд ли поменятся в один миг.

Тони создал свой сайт на glitch.com. Вот как выглядит вкладка с редактором кода:

Рис. 2. Вкладка редактора
Рис. 2. Вкладка редактора

Нажмите tony. Появится меню.

Рис. 3. Меню, которое появляется после нажатия <code class="inline-code">tony</code>
Рис. 3. Меню, которое появляется после нажатия tony

Кликните Remix Project. Название проекта сменится на случайно сгенерированное имя. Создалась редактируемая копия кода, В этот код позже мы внесём изменения.

Нажмите Show, а затем – In a New Window. В новой вкладке откроется демо. Эту вкладку мы будем именовать демонстрационной. Загрузка сайта займёт некоторое время – поклонники Тони не зря жаловались.

Рис. 4. Демонстрационная вкладка
Рис. 4. Демонстрационная вкладка

Нажмите Ctrl+ Shift+J (Windows, Linux) или Cmd+Option+J (Mac). Вместе с демо откроется Chrome DevTools.

Рис. 5. Демо-страница и открытая панель DevTools
Рис. 5. Демо-страница и открытая панель DevTools

Определим базис

Прежде чем мы начнём работать над улучшением производительности, посмотрим, как сайт работает сейчас. Найдём вкладку Audits. Скорее всего она прячется внутри списка, раскрывающегося по кнопке >>. На этой панели вы увидите изображение маяка – проект, лежащий в основе панели Audits, называется Lighthouse.

Рис. 6. Панель Audits
Рис. 6. Панель Audits

Выставим настройки для аудита, как на Рис. 6.

Device. Параметр Mobile изменяет описание пользовательского агента, имитируя мобильный экран. Выбор Desktop просто отключает эти настройки.

Categories. Мы с Тони отключили здесь все разделы, кроме Performance, чтобы не вставлять в отчёт ненужные проверки и не тратить лишнее время. Но вы можете их отметить, чтобы увидеть другие типы рекомендаций.

Кликаем Generate report. Через 10–30 секунд на панели Audits появится отчёт о работе сайта.

Рис. 7. Отчёт по результатам аудита сайта
Рис. 7. Отчёт по результатам аудита сайта

Если в отчёте панели Audits появится ошибка, и в кружке рядом с Performance вы видите вместо числа знак вопроса, запустите демонстрационную вкладку в новом окне в режиме инкогнито. Процессу аудита часто мешают расширения Chrome.

Разбираемся в отчёте

Число в верхней части отчёта – общий показатель эффективности сайта. Для сайта Тони у вас наверняка получилось число 0. По мере внесения улучшений это число должно расти.

Рис. 8. Общий показатель эффективности и раздел Metrics
Рис. 8. Общий показатель эффективности и раздел Metrics

В разделе Metrics представлены количественные показатели производительности сайта. Каждый параметр отвечает за определённый аспект производительности. Например, First Contentful Paint сообщает, через какое время контент начал отображаться на экране – важный параметр для восприятия пользователем загрузки страницы. Time to Interactive отмечает точку, когда страница стала достаточно готова, чтобы с ней можно было взаимодействовать. Развёрнутое описание каждой метрики можно получить при нажатии переключателя списков.

После метрик идёт лента скриншотов, показывающих как страница выглядела в процессе загрузки.

Рис. 9. Панель скриншотов почти пуста – большую часть времени загрузки на сайте ничего не отображалось
Рис. 9. Панель скриншотов почти пуста – большую часть времени загрузки на сайте ничего не отображалось

Раздел Opportunities (англ. «возможности») содержит советы о том, как улучшить загрузку сайта и связанный с ней код. Каждый совет можно раскрыть, нажать Learn more и прочитать документацию на web.dev о том, почему это важно.

Рис. 10. Раздел <code class="inline-code">Opportunities</code>
Рис. 10. Раздел Opportunities

Раздел Diagnostics содержит дополнительную информацию о факторах, влияющих на скорость загрузки страницы.

Рис. 11. Раздел <code class="inline-code">Diagnostics</code>
Рис. 11. Раздел Diagnostics

Наконец, в разделе Passed audits перечислено то, что сайт делает правильно. Обычно раздел находится в свёрнутом состоянии – нажмите, чтобы его развернуть.

Рис. 12. Раздел <code class="inline-code">Passed audits</code>
Рис. 12. Раздел Passed audits

Как ни странно, иногда этот раздел может работать некорректно, так что и эти пункты нужно внимательно рассмотреть. Например, мы скоро увидим, что сайт Тони не сжимает текст (enable text compression) и использует слишком большие изображения (properly size images)

Шаг 2. Экспериментируем

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

Сжатие текста

Перед отправкой по сети текстового файла, даже файла с программным кодом, полезно применить процедуру сжатия. Чтобы проверить, работает ли сжатие текстовых ресурсов, перейдём на вкладку Network.

Рис. 13. Вкладка <code class="inline-code">Network</code>
Рис. 13. Вкладка Network

В настройках вкладки (шестерёнка в правом верхнем углу) отметим пункт Use large request tows. Высота строк в таблице сетевых запросов увеличится.

Рис. 14. Измененное отображение вкладки <code class="inline-code">Network</code>
Рис. 14. Измененное отображение вкладки Network

Каждая ячейка Size теперь показывает два значения. Верхнее – размер загружаемого ресурса. Нижнее значение соответствует размеру несжатого ресурса. Если оба значения одинаковы, файл при отправке по сети не сжимается. Например, на рисунке, значения для bundle.js в обоих случаях составляют 1.2 Мб.

Наличие сжатия также отображается в свойствах элемента. Если кликнуть на любой объект из списка, например, на тот же bundle.js, и перейти в раздел Headers, вы должны увидеть описание ресурса. Если среди параметров нет заголовка content-encoding, сжатие не используется.

Перейдем на вкладку редактора, с которого мы начали наш рассказ, обратимся к server.js. После строки const fs = require('fs'); вставим две следующие строчки:

        const compression = require('compression');
app.use(compression());
    
Рис. 15. Внешний вид редактора после вставки
Рис. 15. Внешний вид редактора после вставки

Некоторая время займёт перестройка структуры сайта. Перезагрузите демонстрационную страницу. В столбце Size теперь будут отображаться два различных значения для текстовых ресурсов. Например, bundle.js сжимается до 256 Кб.

Рис. 16. Обратите внимание на изменения в столбце <code class="inline-code">Size</code>
Рис. 16. Обратите внимание на изменения в столбце Size

Повторим аудит – переходом на вкладку Audits. нажимаем знак +, оставляем прежние настройки, кликаем Generate report.

Рис. 17. Показатель производительности вырос с 0 до 10 после сжатия
Рис. 17. Показатель производительности вырос с 0 до 10 после сжатия

Похоже на прогресс! Общая оценка эффективности выросла, сайт действительно стал загружаться быстрее, Тони довольно замурчал.

Изменение размера изображений

Изменение размера изображений помогает ускорить загрузку сайта за счет уменьшения размера файла изображений. Если ваш пользователь просматривает изображения на экране мобильного устройства шириной 500 пикселей, не имеет смысла отправлять изображение шириной 1500 пикселей.

Вернёмся на вкладку редактора, откроем src/model.js и заменим const dir = 'big' на const dir = 'small'. Этот каталог содержит копии тех же изображений, размер которых был изменен. После обновления страницы повторим процедуру аудита.

Рис. 18. Показатель производительности вырос с 10 до 12 после оптимизации изображений
Рис. 18. Показатель производительности вырос с 10 до 12 после оптимизации изображений

Похоже, что изменение имеет незначительное влияние на общую производительность. Тем не менее вы сохраняете травфик пользователей. Общий размер старых фотографий составлял около 5,3 Мб, а сейчас всего лишь около 0,18 Мб.

Устранение ресурсов, блокирующих загрузку сайта

Среди главных замечаний в отчете значится Eliminate render-blocking resources (устранить ресурсы, блокирующие рендеринг). Таким ресурсом, могут являться внешние файлы JavaScript и CSS, которые браузер должен загрузить, проанализировать и выполнить, прежде чем отобразить страницу.

Первая задача – найти код, который не нужно выполнять при загрузке страницы. Чтобы посмотреть блокирующие ресурсы, развернём в отчёте аудита указанный совет. Среди ресурсов видим lodah.js и jquery.js.

Рис. 19. Подробная информация о блокирующих ресурсах
Рис. 19. Подробная информация о блокирующих ресурсах

Нажмём сочетание клавиш Ctrl+Shift+P (Windows, Linux) или Cmd+Option+P (Mac). В открывшемся меню команд начнём печать слово Coverage и выберем Show Coverage.

Рис. 20. Открытие командного меню для поиска команды
Рис. 20. Открытие командного меню для поиска команды

Нажимаем кнопку для перезагрузки страницы. Вкладка Coverage обеспечивает обзор того, как выполняется код в bundle.js, jquery.js и lodash.js во время загрузки страницы. На Рис. 21 показано, что около 74% jQuery и 30% Lodash не используются.

Рис. 21. Отчёт о покрытии (англ. coverage)
Рис. 21. Отчёт о покрытии (англ. coverage)

Нажмём на строку jquery.js. DevTools откроет файл в панели источников. Если рядом со строкой кода есть зелёная полоска, то эта строка выполнялась. Красная полоска означает, что эти строки не были выполнены и не нужны при загрузке страницы. Если прокрутить код ниже, можно заметить, что некоторые из «исполняемых» строк представляют собой просто комментарии. Прогонка кода через минификатор, удаляющий комментарии – ещё один способ уменьшить размер файла.

Вкладка Coverage помогает анализировать код построчно и отправлять только то, что необходимо для загрузки страницы. Давайте проверим, необходимы ли вообще файлы jquery.js и lodash.js. С помощью Ctrl+Shift+P (Windows, Linux) или Cmd+Option+P (Mac) добавим вкладку Request blocking (Show Request Blocking). На открывшейся панели нажмём кнопку Add pattern. Введём строку /libs/*, чтобы блокировать ресурсы из папки libs.

Рис. 22. Добавление шаблона для блокировки любого запроса к каталогу <code class="inline-code">libs</code>
Рис. 22. Добавление шаблона для блокировки любого запроса к каталогу libs

Перезагрузим страницу. Оба скрипта выделены красным цветом на вкладке Network и не отображаются в Coverage.

Рис. 23. Панель Network показывает, что запросы были заблокированы
Рис. 23. Панель Network показывает, что запросы были заблокированы

При этом страница загружается и является интерактивной – похоже, отключенные ресурсы вообще не нужны!

Вкладка Request blocking полезна для имитации поведения страницы, когда какой-либо ресурс недоступен.

Удалим шаблон блокировки из Request blocking. Вернёмся на вкладку редактора и откроем template.html. Удалим строки <script src="/libs/lodash.js"> и <script src="/libs/jquery.js"></script>. Перезагрузим страницу и вновь проведём аудит.

Рис. 24. Результаты отчёта после удаления ссылок на ресурсы, блокирующие рендеринг
Рис. 24. Результаты отчёта после удаления ссылок на ресурсы, блокирующие рендеринг

Вы можете ускорить загрузку сайта, отправляя во время загрузки страницы, только критический код, а затем подгружая всё остальное. Многие скрипты можно запрашивать не во время загрузки страницы, а асинхронно.

Если вы используете фреймворк, проверьте, есть ли у него production mode. Такой режим позволяет использовать функцию tree shaking, чтобы исключить ненужный код, блокирующий рендеринг.

Минимизируем работу в основном потоке браузера

Среди пунктов, отмеченных в Diagnostics, присутствует совет Minimize main thread work. Основной поток – это то, где браузер выполняет большую часть работы, необходимой для отображения страницы – анализ и выполнение HTML, CSS и JavaScript. Для анализа основного потока используется панель Performance.

Чтобы провести испытания в «полевых условиях», полезно имитировать устройства с медленным интернетом и аппаратными ограничениями. Для этого в настройках панели выставим в выпадающем списке Network Slow 3G, а в списке CPU 6x slowdown. Перезагрузим страницу для профилирования. DevTools отобразит развёртку загрузки страницы во времени – эта визуализация в DevTools носит название trace.

Рис. 25. Панель <code class="inline-code">Performance</code> отслеживает загрузку сайта
Рис. 25. Панель Performance отслеживает загрузку сайта

В trace показывается активность в хронологическом порядке слева направо. Диаграммы FPS, CPU и NET в верхней части дают обзор соответствующих видов активности. Жёлтые области показывают, когда процессор был полностью занят выполнением скрипта. Изучим внимательнее выделенную область – раскроем раздел Timings:

Рис. 26. Раздел Timings на вкладке <code class="inline-code">Performance</code>
Рис. 26. Раздел Timings на вкладке Performance

Мы видим здесь несколько измерений для React. Похоже, приложение Тони использует режим разработки (development mode). Переключение на производственный режим (production mode) даст быстрый выигрыш в производительности. Чтобы это сделать, перейдем в редактор, найдём webpack.config.js и заменим "mode":"development" на "mode":"production". Дождёмся развёртывания новой сборки, и проведём аудит. Действительно, производительность выросла.

Рис. 27. Рост производительности при переходе на <code class="inline-code">production mode</code>
Рис. 27. Рост производительности при переходе на production mode

Однако что-то до сих пор сильно тормозит загрузку сайта. Вернёмся к разделу Perfromance. Свернём Timings и обратимся к разделу Main (его начало видно на Рис. 25). Здесь расположен хронологический журнал активностей основного потока с указанием причинно-следственных связей: событие Evaluate Script вызвало анонимную функцию, та вызвала _webpack_require__ и т. д. Прокрутим вниз к концу раздела Main.

Рис. 28. <code class="inline-code">App</code> делает множество вызовов к функции Bitcoin
Рис. 28. App делает множество вызовов к функции Bitcoin

Приложение App многократно вызывает функцию mineBitcoin. Похоже, Тони не так-то прост и использовал устройства поклонников для майнинга криптовалюты...

В нижней части Performance нажмём на вкладку Bottom-Up. В этом разделе отображается информация о выделенном объекте. Например, если мы кликнем на одно из действий mineBitcoin, в разделе Bottom-Up отобразится информация для этого действия.

Рис. 29. Раздел <code class="inline-code">Main</code> и вкладка <code class="inline-code">Bottom-Up</code> в случае выбора <code class="inline-code">Evaluate Script</code>
Рис. 29. Раздел Main и вкладка Bottom-Up в случае выбора Evaluate Script

Столбец Self Time показывает, сколько времени было потрачено непосредственно для каждого блока. Видно, что 87.4% времени уходит на работу с функцией mineBitcoin. Ох уж этот Тони!

Снизим активность JavaScript, удалив вызовы mineBitcoin. Перейдём в редакторе в src/App.jsx и закомментируем вызов this.mineBitcoin(1500). Проведём заключительный аудит страницы.

Рис. 30. Отчёт после удаления лишних обращений JavaScript
Рис. 30. Отчёт после удаления лишних обращений JavaScript

Это последнее изменение вызвало огромный скачок в производительности!

Панель Performance – наиболее распространённый способ понять, какую активность выполняет сайт во время загрузки, и найти способы удалить ненужные действия. Если вы предпочитаете визуальному подходу логирование результатов, изучите User Timing API.

Отдельное спасибо от Тони

Поклонникам Тони нравится, как быстро сайт теперь загружается сайт, и Тони очень благодарен за вашу помощь (функцию mineBitcoin он создал для баловства и уже забыл о ней). Нажмите «Получить подарок» ниже, чтобы получить специальный подарок от Тони.

Получить подарок

Резюме

  • Всякий раз, когда вы намереваетесь оптимизировать загрузку сайта, всегда начинайте с аудита. Вам будет с чем сравнить результат, и вы получите советы по улучшению.
  • Вносите одно изменение за раз и проверяйте страницу после каждого изменения, чтобы увидеть, как новое изменение влияет на производительность. Основной инструмент для анализа – вкладка Performance. Здесь мы дали лишь краткое введение относительно этой панели – больше информации вы найдете в справочнике по анализу производительности.

Источники

МЕРОПРИЯТИЯ

Комментарии

ВАКАНСИИ

Добавить вакансию
Разработчик C++
Москва, по итогам собеседования

ЛУЧШИЕ СТАТЬИ ПО ТЕМЕ