Оптимизация ресурсов JavaScript для скорости страницы
Опубликовано: 2020-05-05Пример ниже взят с большого сложного новостного веб-сайта. Они годами теряют органический трафик. Время их события DOMContentLoaded составляет 2615,2 мс. Вы можете подумать, что размер их DOM чрезвычайно огромен, но нет…
Это почти то же самое, что рекомендует Google, и в этом документе существует только 1230 узлов HTML.
Вы можете рассчитать время события domContentLoaded, обработать и сравнить его с результатами ваших конкурентов с помощью DevTools.
Изучение этого примера показывает, что размер DOM не обязательно является критической точкой. Здесь основная проблема заключается в порядке ресурсов : синие части в «Главной вкладке» предназначены для синтаксического анализа HTML. Однако этот веб-сайт прерывает работу браузера с помощью рендеринга JavaScript до завершения процесса анализа HTML.
(Вы также можете использовать раздел «Дерево вызовов», чтобы найти похожие ошибки для вашей ИТ-команды.)
Этот пример ясно иллюстрирует важность оптимизации ресурсов JavaScript и то, что может пойти не так, если вы пренебрегаете JavaScript при оптимизации скорости страницы.
Это третья статья из серии из четырех. Чтобы лучше понять эту статью, вы можете прочитать первые две статьи серии:
- Рендеринг Javascript и скорость страницы тесно связаны с тем, как механизм рендеринга браузера создает веб-страницу.
- Вы также должны понимать расширенные показатели скорости страницы, прежде чем переходить к этой статье.
Я буду использовать несколько примеров из первых двух статей, чтобы обеспечить контекст в этой.
Что такое рендеринг Javascript и как он влияет на скорость вашей страницы?
Рендеринг Javascript — это последний раздел загрузки страницы, который может интерактивно изменять структуру, созданную с помощью DOM и CSSOM. Любой элемент страницы можно изменить в формате, запускаемом пользователем, или отобразить как обычно. Любой элемент со свойством display:none, к которому не может получить доступ дерево рендеринга, может быть отображен с помощью JavaScript или внедрен через другие элементы HTML в DOM.
JavaScript прерывает DOM и CSSOM, потому что он изменяет DOM и CSSOM во время их чтения браузером. Поэтому, чтобы предотвратить негативное влияние времени и скорости загрузки страницы, необходимо изучить взаимосвязь между DOM, CSSOM и рендерингом JavaScript.
Выше приведен пример дерева рендеринга. Все взаимосвязанные фрагменты кода в узлах CSSOM и HTML имеют семантические эквиваленты в дереве рендеринга. Если вы посмотрите внимательно, то заметите, что узла HTML «Кнопка действия» нет в дереве рендеринга. Основная причина этого — «display: none;» Свойство CSS. Из-за этой команды невидимости она не включается в дерево рендеринга. Чтобы увидеть, как были построены элементы в этом дереве, вы можете прочитать первую статью в этой серии.
Если у вас есть много элементов страницы, которые не появятся при первой загрузке, потому что они зависят от поведения пользователя, в порядке загрузки ресурса вам придется отделить эти элементы и поместить их в последнюю строку. На данный момент лучше использовать теневой DOM или виртуальный DOM.
Отложенные и асинхронные атрибуты для ресурсов JavaScript
Если вы поместите свои JS-файлы в раздел и не используете атрибуты «отложить» или «асинхронный», это, вероятно, задержит время загрузки DOMContentLoaded. Чтобы предотвратить эту ситуацию, мы можем использовать эти два атрибута. Отложить — отложить процесс загрузки файла JS, а «Асинхронный» — загрузить JS и другие источники параллельно. Оба имеют преимущества и недостатки. Здесь мы расскажем только об основных.
- Если вы используете отсрочку для основного JS-файла, вы, вероятно, не увидите его эффектов «инициатора», пока он не будет установлен.
- Если вы используете отсрочку слишком часто, вы можете вызвать узкое место процессора в конце загрузки страницы.
С момента написания этой статьи было выпущено обновление Chrome 80. В столбце Инициатор теперь намного проще увидеть, какой ресурс каким ресурсом вызывается. Например, вы можете увидеть изображение или файл CSS, вызываемый JS. Если вы прокручиваете ресурсы, удерживая нажатой клавишу Shift, вы также увидите, какой ресурс нельзя использовать без загрузки других ресурсов.
Прокрутка с зажатой клавишей Shift: красный цвет указывает на условный ресурс для ресурса, выделенного зеленым.
Вы также можете использовать новый раздел «Инициатор» в Chrome для получения более подробной информации о порядке загрузки ресурсов, инициаторе и проверке приоритетов. Это позволяет вам обнаруживать чрезвычайно длинные и дорогостоящие цепочки вызовов JS, такие как приведенная ниже.
Пример длинной и затратной цепочки вызовов JS с того же сайта. Над выбранным ресурсом находятся его инициаторы. В следующей части показаны ресурсы, инициированные выбранным ресурсом.
- Отложенные файлы JS загружаются после события domInteractive, поэтому вам нужно выбрать их в соответствии с вашими файлами CSS и изображениями.
- Если вы отложите некоторые сторонние файлы JS для отслеживания пользователей, вы не сможете отслеживать поведение определенных пользователей.
- Defer обычно не блокирует процесс DOM, но Async блокирует. Файлы JS с асинхронными атрибутами загружаются браузером во время анализа HTML и обработки CSSOM.
- Если вы слишком часто используете асинхронный атрибут, возможно, вы создадите узкое место в процессоре, а также замедлите процессы DOM и CSSOM. Вам нужно тщательно выбирать, что откладывать, а что асинхронно.
Вот пример схемы для атрибутов async и defer. Первый загружается перед domContentLoaded без разделения HTML-разбора во время выборки. Во втором извлеченный файл JS не выполняется до завершения синтаксического анализа HTML.
Предложения и советы по рендерингу и производительности Javascript
Прежде чем перейти к практическим примерам, вот несколько советов по улучшению производительности рендеринга JavaScript. Это также может помочь лучше понять скорость страницы и работу браузера.
Не используйте ненужные переменные.
Если вы занимаетесь SEO, вы можете заметить ненужные или неиспользуемые переменные в файле JavaScript. Существует множество инструментов, которые можно использовать для обнаружения такого рода ошибок. Ниже вы найдете два основных примера неиспользуемых и ненужных переменных.
var carName= марка+ ” ” + год;
document.getElementById("демо").innerHTML = carName;
Здесь переменная «carName» не нужна. Можно предложить следующую модификацию:
document.getElementById("демо").innerHTML = бренд+ " " + год
Или:
[a, b, c, d, e].forEach(функция (значение, индекс) {
console.log(индекс);
});
Здесь параметр «значение» не нужен, потому что он не используется. Вы можете удалить его:
[a, b, c, d, e].forEach(функция (индекс) {
console.log(индекс);
});
С правой стороны вы можете увидеть более длительное время соединения (белые линии), а файлы CSS и JS загружаются в асимметричном порядке благодаря «асинхронным» Javascripts.
С левой стороны время подключения меньше, а файлы CSS и JS не смешиваются, поскольку каждый источник загружается по строкам. Асинхронные атрибуты могут уменьшить ваш индекс скорости, поскольку они могут увеличить время TBT, поэтому вам необходимо провести расследование и сообщить об этом своей команде разработчиков для получения файлов JS для отслеживания производительности на вкладке производительности, или вы можете провести некоторые эксперименты самостоятельно.
Используйте инструменты для сложных задач
Новичку в кодировании может быть сложно найти ненужные или неиспользуемые переменные. Вы можете использовать некоторые инструменты для этих задач, такие как Chrome DevTools или пакеты Node.js, такие как Unused (Kami/node-unused: модуль, который сообщает об определенных, но неиспользуемых переменных в вашем коде или для большего количества неиспользуемых переменных). Если вы обнаружите даже небольшие ошибки, я уверен, что ваша ИТ-команда прислушается к вам, чтобы улучшить ваши файлы JavaScript.
Использование отчета о покрытии Chrome DevTools для поиска неиспользуемого кода JavaScript
Отчет о покрытии Chrome DevTools показывает неиспользуемые фрагменты кода JavaScript, но это не очень практично. Вы можете подумать, что можете удалить каждую красную часть кода, но это не так… Вместо этого вы должны найти совершенно неиспользуемые функции или переменные для большого количества страниц категорий. Таким образом, ваша команда разработчиков может быть убеждена в необходимости использования процесса TreeShaking.
TreeShaking означает удаление мертвого кода из файлов. Я рекомендую учиться, используя неиспользуемые пакеты поиска переменных и функций JS, чтобы выиграть время.
Меньший размер DOM также поможет с рендерингом JavaScript. Каждая команда (getElementsByTagName) будет сканировать ваш DOM. Меньший размер DOM потребует меньше ресурсов вашего браузера и процессора/сети вашего устройства при рендеринге JavaScript.
С новым обновлением Chrome 80 отчет о покрытии также претерпел изменения. Они добавили необязательные варианты «За функцию» и «За блок». Per Block здесь является значением по умолчанию.
Если вы выберете Per Function, вы увидите большую разницу в своем отчете. Основная причина такой ситуации заключается в том, что представление «По функциям» проверяет, используются ли все функции или нет. Если используется 95 % функции, параметр «На функцию» определит ее как неиспользуемый код, поскольку 5 % кода не используется, хотя основная часть функции используется.
Сжимайте, уменьшайте или уменьшайте ваши JS-файлы.
Это можно сделать двумя способами. Во-первых, удалите пробелы и ненужные комментарии. Во-вторых, используйте улучшенные операторы JavaScript для ваших файлов JS и изменяйте имена, переменные, функции с помощью готовых технологий.
Вы должны знать о стрелочных функциях для такого сжатия. Например, вместо этого 84-символьного примера:
функция стрелка Ислева (а, б) {
console.log (а + б);
}
стрелка Фонксиён (5, 6);
Вы можете сжать его до 50 символов с помощью стрелочных функций =>
const ab = (a, b) => b + a;
console.log(аб (5, 6));
Другой метод сокращения/сжатия действителен для операторов If. Вместо этого фрагмента кода с 63 символами:
если (а<б) {
console.log(аб);
}
еще {
console.log(а+б);
Вы можете использовать тот, у которого 43 символа ниже:
(а<б) ? console.log(ab): console.log(a+b);
Вы также можете предложить своей ИТ-команде использовать знаки $ и _ для сжатия. Большинство файлов JavaScript работают для переинтерпретации DOM. Для этого вы можете увидеть множество document.getElementById(x); фрагменты кода в файлах. Вы можете использовать знак $ для этой задачи. Это избавит вас от огромной кучи бесполезного размера.
Большинство библиотек JavaScript используют $ по умолчанию для определения функции, но не все, потому что $ также является символом алфавита.
В этой ситуации вы можете предложить вашей ИТ-команде использовать:
функция $(x) {return document.getElementById(x);} .
Используйте подходящий тип рендеринга
Типы рендеринга JavaScript и веб-страниц с точки зрения совместимости с SEO.
Гидратация SSR означает, что некоторые компоненты JS будут отображаться с использованием рендеринга на стороне клиента. Это полезно для FP и FMP, но могут быть некоторые недостатки для показателей TTI и индекса скорости.
Источник изображения: Notprovided.eu
Рекомендации по написанию кода для повышения производительности рендеринга JavaScript
- Еще одним важным вкладом в сжатие будет использование «_». Вы можете использовать «underscore.js» для улучшения форматов и функций написания JavaScript. Таким образом, вы будете создавать меньшие файлы JS, манипулируя списками и коллекциями с помощью более коротких функций JS без встроенных функций JS.
- Использование большого количества длинных и утомительных изменений переменных и загрязнение глобальных переменных также являются причинами медленного рендеринга. Вы должны определить общий выбор области действия ваших функций и типы глобальных переменных/длинных переменных. Использование локальных переменных с параметром «Let» лучше подходит для рендеринга. Из-за локальных переменных браузеры не будут проверять другие глобальные функции-переменные для следующего изменения.
Для имитации более реалистичного исследования производительности, например того, что вы можете увидеть на недорогих мобильных телефонах, вы должны использовать настройки CPU Throttling и Fast/Slow 3G Connection в Chrome DevTools.
Источник изображения: Эдди Османи
- Использование небольших функций JS и цепочек переменных повысит производительность рендеринга. Кроме того, лучше использовать селектор «этот» вместо селектора «с». «Этот» селектор в Javascript является локальным функционирующим кодом, в отличие от «with», здесь действует та же логика, что и с let и var.
- Если вы используете свои операторы во фрагментах кода цикла For, это также немного снизит скорость рендеринга. Потому что ваш оператор функции будет перебирать каждый элемент цикла. Вы можете просто создать новую переменную для элементов цикла и вызвать эти элементы с помощью функции, находящейся вне цикла For.
- Если вы хотите получить доступ к элементу HTML несколько раз, вы можете создать для него переменную и вызывать ее с помощью нужных вам функций. Достижение HTML-элемента с помощью JavaScript — не быстрый процесс. Вы можете просто увеличить нагрузку на свой браузер.
Еще один способ улучшить производительность рендеринга Javascript — это тризоморфный рендеринг с помощью сервис-воркеров. Вы можете поместить некоторые из ваших JS-файлов в память браузера клиента для будущих сеансов. Таким образом, вы можете заставить свой сайт работать в автономном режиме.
Вы можете найти простую демонстрацию для лучшего понимания и возможности попрактиковаться с сервисными работниками здесь.
Связываем это: как оптимизация JavaScript и скорость страницы влияют на SEO
Чтобы ресурсы JavaScript не саботировали скорость вашей страницы, мы увидели, как отсрочка и асинхронность могут иметь огромное значение. Мы также рассмотрели несколько стратегий «отладки» и советы по кодированию, которые могут помочь вам повысить скорость ваших страниц с помощью ресурсов JavaScript.
Теперь, когда мы увидели, как браузеры создают веб-страницы, как измеряется и влияет на скорость страницы, а также роль, которую оптимизация JavaScript играет во времени загрузки страницы, в следующей статье будет показано, как порядок загрузки ресурсов влияет на скорость страницы и краулинговый бюджет.
Если вам интересно ознакомиться с предыдущими статьями из этой серии из четырех статей, вы можете найти их здесь:
- «Как браузер создает веб-страницу»
- «Расширенные показатели скорости страницы».