PageSpeed Insights от Google стал стандартом для измерения и оценки производительности веб-сайта. Этот метод позволяет измерить производительность вашего сайта и время загрузки по шкале 0-100, с обзором ключевых показателей и рекомендациями по их улучшению.
- 🤔 Почему показатель PageSpeed так важен?
- 1. SEO
- 2. UX
- 3. Объявления
- 📐 Наша текущая архитектура сайта
- 🚧 Проблема с настройкой
- 🚀 Решение
- Проверьте конфигурацию Cloudflare
- Кэширование
- Производительность
- Оптимизация CSS
- Используйте CSS-фреймворк, ориентированный на утилиты
- Очистка неиспользуемого CSS
- Оптимизируйте JS Bundle
- Разделение фрагментов с помощью webpack
- Проверьте зависимости вашего сайта
- Используйте асинхронные компоненты
- Внешняя и ленивая загрузка всех SVG
- Оптимизируйте все изображения
- Задержка гидратации Nuxt.js
- 💯 Результат
- ✔️ Заключение
🤔 Почему показатель PageSpeed так важен?
Естественно, было много дискуссий о полезности этого показателя и о том, насколько он отражает реальный пользовательский опыт.
Должны признаться, что мы убедились в том, что общий показатель вашей страницы имеет большое значение, на собственном опыте, когда наши рекламные бюджеты стали распределяться не так эффективно, как раньше, из-за внезапного падения показателей. Но это не просто расходы на рекламу, и ниже перечислены три основные причины.
1. SEO
С 2010 года PageSpeed был фактором ранжирования при поиске на настольных компьютерах. В 2018 году Google объявил, что он будет учитываться и в мобильном поиске. Это решение делает ранжирование в SERP напрямую связанным с показателями PageSpeed и делает его неотъемлемой частью поисковой оптимизации.
2. UX
Более быстрые веб-сайты означают лучший пользовательский опыт и более счастливых пользователей в целом. Существует множество исследований о том, как скорость страницы влияет на доход (вот это или это).
От того, что сайты работают быстрее, выигрывают и пользователи, и бизнес.
Для борьбы с возражениями по поводу того, насколько точно показатель PageSpeed отражает воспринимаемую производительность, Google теперь измеряет фактическую производительность на устройствах пользователей и использует агрегированный показатель за определенный период времени.
3. Объявления
В том же объявлении в 2018 году Google также упомянул, что скорость страницы теперь является еще одним фактором для определения QualityScore как для десктопных, так и для мобильных целевых страниц. Это означает, что страницы с низкими показателями теперь будут снижать CTR вашего объявления, а также увеличивать CPC!
Объявления конкурентов с большей вероятностью будут показываться вместо ваших, чего никто не хочет. Проще говоря, чтобы оптимизировать свой маркетинговый бюджет, оптимизируйте и PageSpeed.
📐 Наша текущая архитектура сайта
Как следует из названия, мы используем фреймворк Nuxt.js для всего сайта, предназначенного для публичного доступа.
Каждая страница построена из общих компонентов, которые мы используем во всей нашей кодовой базе, а также являются основной зависимостью нашего приложения, плагинов и т.д. Мы используем Tailwind CSS для ускорения разработки и создания согласованных визуальных эффектов на всей платформе.
Контент сайта затем берется из различных источников, включая платформу Directus и блог Ghost.
Весь сайт развертывается в статическом режиме, то есть все страницы предварительно генерируются и предоставляются в виде статических HTML-файлов, поэтому не требуется время работы сервера. Затем все загружается в несколько копий, кэшируется и распространяется через CDN Cloudflare, что делает сайт невероятно легким и устойчивым, поскольку он требует незначительных вычислительных ресурсов.
🚧 Проблема с настройкой
Несмотря на то, что архитектура сайта выглядит очень масштабируемой и имеет потенциал для обслуживания миллионов пользователей ежедневно, мы не получали ожидаемых результатов в плане PageSpeed.
Основными выявленными проблемами были:
- Большой размер пакета JS (загруженного и разобранного), в основном из-за сторонних зависимостей
- Большой размер страницы в целом, включая статические ресурсы
- Большое время блокировки рендера
🚀 Решение
Существует множество статей о веб-производительности, в которых даются советы, как ускорить работу сайта, но когда дело доходит до практических примеров, они встречаются редко. Поэтому я решил представить полный список шагов, которые мы предприняли для улучшения нашего показателя PageSpeed. Некоторые из них специфичны для нашей архитектуры, описанной ранее, и должны быть адаптированы к вашей конфигурации.
Проверьте конфигурацию Cloudflare
Многие из вас, вероятно, используют Cloudflare для управления конфигурацией DNS. Это фантастический сервис с множеством опций для повышения безопасности, отказоустойчивости и производительности вашего сайта. Однако большинство сайтов просто выполняют первоначальную настройку и редко обращаются к ней в дальнейшем. Мы пользуемся платным тарифным планом, поэтому у нас может быть больше настроек, но большинство из этих опций доступны и в бесплатном тарифе.
Кэширование
Кэширование Cloudflare — это мощный сервис. Оно распределяет ваши ресурсы по CDN и может значительно сократить время загрузки, особенно для глобальной аудитории. Вот несколько шагов, которые вы можете сделать немедленно:
Увеличьте TTL кэша браузера в разделе **Кэширование **. Это поможет клиентам кэшировать ваши файлы в течение более длительного времени. Рекомендуемое значение — один год.
Установите правило страницы для соответствия всем статическим активам. По умолчанию Cloudflare кэширует только статические активы с указанными расширениями. Создайте правило страницы для ваших активов, чтобы кэшировать все.
Производительность
Включите функцию автоматического минимизации для ваших ресурсов. Все в выходном пакете Nuxt.js минифицируется по умолчанию, но на вашем сайте могут быть сторонние ресурсы, которые нуждаются в оптимизации. Полезно держать эту настройку включенной.
Включите сжатие Brotli, чтобы уменьшить объем данных, которые необходимо передавать по сети.
Включите приоритезацию HTTP/2, которая позволяет лучше распараллелить загрузку ресурсов. HTTP/2 включен по умолчанию.
⚠️ Внимание: Вы также можете включить Mirage и Rocket Loader™. Эти две настройки могут ускорить начальную загрузку страницы на настольных и мобильных компьютерах, но используйте их осторожно, поскольку они могут вызвать неожиданное поведение — например, полностью пустые страницы в некоторых браузерах и т.д. Эта настройка работает лучше всего.
Оптимизация CSS
Используйте CSS-фреймворк, ориентированный на утилиты
Мы используем Tailwind CSS во всей нашей кодовой базе. Библиотеки, подобные Tailwind, значительно повышают производительность, поскольку вам не нужно писать новые правила CSS. Вы можете использовать уже имеющиеся классы, и ваши таблицы стилей не будут сильно разрастаться со временем.
Tailwind поддерживает минимальный объем CSS на выходе, генерируя только те утилиты, которые вы действительно используете. Он не раздувает ваши таблицы стилей всеми доступными утилитами, как это делает, например, Bootstrap.
Очистка неиспользуемого CSS
Очистка CSS — еще один отличный способ сохранить размер таблицы стилей и увеличить показатель PageSpeed. Она особенно полезна, если вы импортируете сторонние таблицы стилей и хотите использовать только то, что необходимо. Для правильной настройки обычно требуется немного повозиться, но это определенно стоит усилий.
Оптимизируйте JS Bundle
Чтобы быстро просмотреть дерево зависимостей и выявить некоторые потенциальные проблемы, вы можете запустить команду nuxt build
с флагом --analyze
.
Добавьте эту команду в раздел "scripts"
в вашем package.json
и запустите ее как npm run analyze
.
"scripts":{
"analyze": "nuxt build --analyze",
}
Разделение фрагментов с помощью webpack
Благодаря HTTP/2 загрузка нескольких небольших пакетов происходит быстрее, чем загрузка одного файла. Попробуйте добавить maxSize
в ваш nuxt.config.js
, чтобы заставить webpack разделить ваш пакет на более мелкие куски. Но не пытайтесь установить слишком низкое число, так как слишком много маленьких пакетов все равно будут создавать накладные расходы. Вам придется немного поэкспериментировать, чтобы найти баланс.
optimization: {
splitChunks: {
maxSize: 300000
}
}
Проверьте зависимости вашего сайта
Проверьте, какие библиотеки вы импортируете в свой код и насколько они велики. Действительно ли вам нужна библиотека размером 30 кБ только для того, чтобы получить более удобный способ установки cookie? Есть ли более легкое альтернативное решение? Помните, что эти цифры быстро складываются.
При добавлении библиотеки убедитесь, что она использует модули ES6. Webpack, бандлер, поставляемый с Nuxt.js, может создавать высокооптимизированные бандлы для каждой страницы и древовидно расщеплять неиспользуемый код.
Если библиотека, с другой стороны, использует модули CommonJS или UMD, она будет встроена непосредственно в пакет chunk-vendors.js
вместе с остальными зависимостями и должна быть загружена на всех страницах! И поверьте мне, chunk-vendors.js
может стать очень громоздким. 🤭
Хорошим примером является популярная библиотека lodash, которая не является tree-shakeable в оригинальной версии. (Она предназначена для использования в среде Node.js). Однако существует версия ES6 под названием lodash-es, которая должна использоваться по умолчанию вместе со всеми современными бандлерами.
Используйте асинхронные компоненты
В Nuxt.js есть простой способ указать Webpack, где он должен разделить ваш код. Он называется «асинхронные компоненты» и использует специальный синтаксис import
.
const MyComponent = await import('@/modules/common/MyComponent.vue');
Затем вы можете зарегистрировать компонент в своем .vue-файле, как обычно.
components: {
MyComponent,
}
Всякий раз, когда webpack встречает асинхронный компонент в вашем коде, он создает отдельный чанк для вашего компонента и его зависимостей. В дальнейшем этот чанк загружается асинхронно по требованию. Таким образом вы не только экономите пропускную способность, но и сокращаете время на разбор и оценку вашего кода во время первоначальной загрузки страницы.
Эта техника особенно удобна при загрузке компонентов, требующих интенсивного взаимодействия, или анимации.
Внешняя и ленивая загрузка всех SVG
Загрузка внешних SVG-иконок при сохранении гибкости формата — непростая задача. В конце концов, единственным надежным методом является вставка их непосредственно в HTML. Как и следовало ожидать, это может быстро выйти из-под контроля, и с каждой новой иконкой увеличивается размер JS или HTML.
А что если хранить SVG во внешнем пространстве и вставлять их позже с помощью скрипта? Именно это и делает библиотека external-svg-loader, которую мы используем в нашем компоненте многоразовых иконок.
Все иконки теперь хранятся в CDN и лениво загружаются, когда это необходимо. Большинство из них также кэшируются локально, поэтому их даже не нужно загружать большую часть времени.
Оптимизируйте все изображения
Оптимизация изображений могла бы занять целую статью, поскольку существует слишком много вещей, которые можно сделать. Тем не менее, вы можете попытаться дотянуться до «низко висящих плодов», установив некоторую конфигурацию по умолчанию для всех изображений и оптимизируя их оттуда.
Обязательно попробуйте модуль NuxtImage. Он имеет множество опций и даже встроенную библиотеку для оптимизации изображений во время сборки.
Мы предпочитаем хранить все изображения на нашем сайте во внешнем хранилище для более простого управления, как можно ближе к реальному содержанию. Мы используем Directus CMS, которая включает собственное управление активами с интегрированной оптимизацией изображений, но любая другая CMS должна работать аналогичным образом.
Используя пользовательские провайдеры, мы можем просто подключить опции оптимизации изображений Directus к модулю nuxt-image. Упрощенный код провайдера выглядит следующим образом:
export function getImage(src, {}, { options}) {
const { transform } = options;
const query = '?key=quality-90&format=webp';
return {
url: withoutTrailingSlash(joinURL(fileUrl(src), query))
};
}
Вам необходимо зарегистрировать провайдер в вашем nuxt.config.js
:
image: {
providers: {
directus: {
name: 'directus',
provider: '~plugins/directus-image-provider'
}
}
Затем, для каждого изображения в вашей кодовой базе, просто используйте <nuxt-image>
вместо <img>
.
Существенным преимуществом этого подхода является то, что вы можете быстро применить его глобально.
СОВЕТ: Обязательно проверьте все опции модуля, так как это позволит вам легко указать разные размеры изображений на разных экранах и дополнительно улучшить производительность на мобильных.
Задержка гидратации Nuxt.js
Чтобы понять эту оптимизацию, важно знать, как работает жизненный цикл страницы Nuxt.js.
В режиме статической генерации возвращается полностью отрисованная статическая HTML-страница.
На начальном этапе Nuxt.js присоединяется к DOM и наполняет статическую страницу javascript, делая ее полностью интерактивной. (Для более подробной информации смотрите диаграмму жизненного цикла Nuxt).
Благодаря такому подходу, вы можете отключить JavaScript, и страница все равно загрузит все свое предварительно отрендеренное содержимое.
Модуль @nuxt/delay-hydration использует преимущества этой концепции и задерживает этот процесс после того, как страница загрузится и будет простаивать. Это значительно сокращает время блокировки страницы и откладывает ненужные скрипты на потом, когда они понадобятся.
Модуль хорошо настраивается и работает в различных режимах, где вы можете задержать все, только некритичный код, или позволяет вам выбирать части вашей страницы вручную.
💯 Результат
После внедрения всех этих изменений на нашем сайте показатель PageSpeed подскочил с 23 до 97. Чтобы убедиться, что показатели не упадут со временем, я бы рекомендовал настроить проверку https://unlighthouse.dev для вашего CI/CD.
✔️ Заключение
Обратите внимание, что это не исчерпывающий список вариантов. Некоторые шаги могут быть более эффективными, чем те, что перечислены здесь, в зависимости от вашего контекста. Обязательно проверьте калькулятор Lighthouse Score, чтобы определить, какие параметры оказывают наиболее значительное влияние на ваш балл и на каких областях вам следует сосредоточиться.
Знаете ли вы другие приемы и советы по улучшению показателей PageSpeed с помощью Nuxt.js? Поделитесь своими мыслями в комментариях!