В этой статье я описал множество способов и приемов которыми можно оптимизировать скорость загрузки и отрисовки страницы. С помощью них вы сможете добиться высоких показателей в Google Page Speed Insights, Lighthouse и других тестах.
- Валидация HTML и CSS
- Веб-шрифты формата woff2. Отказ от Google Fonts
- Предварительная загрузка шрифтов и других ресурсов
- Сжатие jpg и png графики
- Сжатие svg графики
- Использование webp и других современных форматов графики
- inline код для svg графики
- Удаление лишнего CSS кода
- Отключение sourcemaps в CSS и JS
- Сжатие (минификация) CSS, JS, HTML кода
- Объединение CSS, JS файлов
- Вынесение критической части CSS кода в inline
- Отложенная загрузка для изображений
- Отложенная загрузка для iframe
- Разделение на модули и отложенный запуск JavaScript кода
- Включить кэширование ресурсов на стороне клиента
- gZip или другой способ сжатия данных сайта
- Включить протокол HTTP/2
- SSL сертификат
- Accessibility — доступность
- Размеры для изображений
- Атрибут aria-label для тегов button
- Теги label c описанием элементов формы
- Заключение
Валидация HTML и CSS
Перед тем как оптимизировать скорость загрузки и отрисовки страницы необходимо убедиться что в коде страницы нет ошибок. Для проверки используем сервисы для валидации HTML и валидации CSS кода.
Валидатор HTML: https://validator.w3.org/
Валидатор CSS: https://jigsaw.w3.org/css-validator/
Веб-шрифты формата woff2. Отказ от Google Fonts
Для оптимизации скорости загрузки лучше разместить веб-шрифты в проекте. На сегодняшний день можно смело использовать формат woff2 – он современный, оптимизированный по весу, поддерживается всеми браузерами, кроме IE и Opera mini. Сам сервис Google Fonts использует только его, отказавшись от всех остальных форматов.
Скачать шрифт в формате ttf для конвертации в woff2 можно на том же Google Fonts. Сервисы для конвертации в woff2: transfonter.org или fontsquirrel.com
При конвертации, или при описании директивы @font-face не забудьте указать в ней CSS свойство font-display: swap;
это позволит не задерживать отображение текста, пока загружается веб-шрифт.
К тому же при использовании Google Fonts браузер делает запросы на два разных сервера. CSS файл с описанием шрифта находится на одном домене, а сами шрифты на другом.
Предварительная загрузка шрифтов и других ресурсов
Одной из рекомендация от Lighthouse является предварительная загрузка ресурсов которые могут понадобиться на странице.
Так можно указать предварительную загрузку шрифтов которые используются на всем сайте или только в области первого экрана. Можно указать предварительную загрузку фонового изображения для шапки сайта. Тут все зависит от конкретного сайта.
Делается это тегом link
внутри тега head
. Пример предварительной загрузки шрифтов:
<link rel="preload" href="./fonts/montserrat/Montserrat-Bold.woff2" as="font" crossorigin="anonymous"> <link rel="preload" href="./fonts/montserrat/Montserrat-ExtraBold.woff2" as="font" crossorigin="anonymous"> <link rel="preload" href="./fonts/montserrat/Montserrat-Medium.woff2" as="font" crossorigin="anonymous">
Данной инструкцией на предварительную загрузку можно ускорить отрисовку контента на странице, либо навредить если указать в нем слишком много ресурсов, которые будут лишними в первые секунды загрузки сайта.
Сжатие jpg и png графики
После экспорта jpg и png графики из макета, она зачастую весит больше, чем могла бы. Это зависит от алгоритмов и степени сжатия. Для оптимизации веса рекомендую использовать специальные сервисы.
Сервис tinypng позволяет значительно сократить вес jpg и png файлов. Порой получается сэкономить до 90% от исходного веса файла.
Сжатие jpg и png графики: https://tinypng.com/
Сжатие svg графики
SVG — это векторный формат, который полностью описан через код и формулы. Но несмотря на это и его можно сжать, значительно сократив количество кода и выиграв в весе изображений. Сжатие SVG зачастую не дадут под сотни сэкономленных килобайт, как это может быть с jpg форматом, однако иногда это может быть полезно и позволит сократить вес svg файла на 20-30%.
Сжатие svg графики: https://vecta.io/nano
Использование webp и других современных форматов графики
webp
может составить хорошую конкуренцию png и jpeg (зависит от метода сжатия jpeg) форматам, без особой потери качества. Если на вашем сайте много оформительской png графики, то можно рассмотреть её конвертацию в webp.
У webp есть один минус — он не поддерживается в Safari, поэтому нужно будет помещать его в тег picture и делать fallback до jpeg формата. На nginx серверах есть возможность настроить автоматическую отдачу webp формата тем браузерам которые его поддерживают, чтобы настроить это — обратитесь к вашему системному администратору.
Для ручной подготовки webp графики, можно воспользоваться сервисом squoosh.app чтобы оптимизировать графику не только в webp но и в более компактный, по сравнению с обычным, jpeg формат (например используя метод сжатия MozJPEG).
inline код для svg графики
Вставив svg графику через inline код в html разметку страницы, мы уменьшаем количество запросов к файлам. Меньше подключений файлов, означает меньше запросов, это напрямую влияет на скорость загрузки страницы. Делать inline вставку svg графики стоит аккуратно. Если подразумевается что эта графика будет редактироваться через CMS, то от inline способа стоит отказаться. Если это верстка элемента интерфейса, который не является изменяемым контентом через CMS — то inline способ будет подходящим решением.
Удаление лишнего CSS кода
Стоит позаботиться о том чтобы в CSS файле не было селекторов с стилями которые не используются в проекте. Тут нужно либо внимательно писать стили, не создавая селекторы которые не используются, либо проверять себя через сервисы которые помогут найти неиспользуемый CSS в проекте. Также посмотреть неиспользуемый CSS можно через DevTools в Chrome браузере. Используя Gulp сборку можно воспользоваться gulp-плагинами, которые налету будут удалять ненужный CSS код и он не будет попадать в итоговый CSS файл.
Сервисы по поиску неиспользуемого CSS:
Плагин для Gulp и не только: purge.css
Отключение sourcemaps в CSS и JS
Исходные карты полезный инструмент во время разработки. С помощью них мы понимаем где изначально описан тот или иной селектор или JS код. Но файлы sourcemaps порой весят больше чем сам CSS файл, поэтому при оптимизации скорости загрузки — от них стоит отказаться. Они нужны только при разработке и отладке, но не на продакшене.
Сжатие (минификация) CSS, JS, HTML кода
На CSS файлах можно сэкономить несколько десятков КБ, это конечно зависит от размеров проекта. Для этого в CSS стоит минифицировать. Это такое сжатие CSS кода, когда из него удаляются все символы которые можно удалить, при этом оставив файл работоспособным. К ним относятся пробелы, переносы строки, точки с запятой после последнего свойства в селекторе. Визуально такой файт становится нечитаемым, зато за счёт такой чистки — его вес может уменьшится на 30%
Также подобное сжатие можно проводить для HTML и JS кода. Такая операция позволит сократить вес проекта на несколько десятков килобайт.
Объединение CSS, JS файлов
Если стили для проекта написаны в нескольких файлах и подгружаются отдельными тегами link, то имеет смысл объединить их в единый файл. Тоже самое стоит сделать и с JS скриптами. Таким образом мы уменьшим количество запросов на сервер.
Вынесение критической части CSS кода в inline
Если CSS файл имеет вес более 100Кб то можно вынести из него стили которые нужны для загрузки первого экрана страницы — который видит пользователь. Эти стили минифицуируются и размещаются inline кодом через тег style внутри тега head.
Таким образом при загрузке страницы браузер сразу получает необходимые стили, без запроса к отдельному CSS файлу и его загрузки, и начинает их применять, отрисовывая первый экран. И только после этого загружаются остальные стили из CSS файла.
Здесь преследуется цель — отрисовать первый экран сайта как можно быстрее, счет идет на миллисекунды.
Отложенная загрузка для изображений
Если на сайте большое количество изображений, то имеет смысл установить скрипт lazy load загрузки. С таким скриптом изображения будут загружаться только в тот момент когда попадают в область видимости в браузере, и не будут блокировать загрузку всего сайта, загружаясь когда они еще не нужны.
Отложенная загрузка для iframe
Карты Yandex и Google Maps, iframe блоки для видео с Youtube и другого контента. Если они не нужны мгновенно при открытии сайта, то стоит сделать для них отложенную загрузку.
Разделение на модули и отложенный запуск JavaScript кода
Если на проекте есть много JS кода, то возможно эффективным будет разделение кода на отдельные файлы, и отложенный запуск.
Например в проекте используется библиотека карусели, которая работает на библиотеке jQuery. Также на сайте есть скрипты для открытия навигационного меню и прочие небольшие интерактивные вещи написанные отдельными скриптами на нативном JS.
В нашем примере скрипты на чистом JS присутствуют уже в шапке сайта и на первом экране. А карусель которая требует jQuery находится в самом низу сайта, и чтобы до неё добраться нужно скроллить несколько экранов.
В таком случае, можно изначально загрузить только файл с нативными JS скриптами. А после по скроллу, при приближении к слайдеру — начать загружать библиотеку jQuery, библиотеку карусели и его инициализацию на странице. Для этого можно написать специальные JS функции.
Также может пригодиться setTimeout
для отложенного запуска скриптов, чтобы они запускались спустя определенное время, это может быть от 100 до 300 миллисекунд, не блокируя и не замедляя отрисовку первого экрана сайта.
Включить кэширование ресурсов на стороне клиента
Сделать это можно отправив браузеру заголовки с инструкцией на какое время стоит кэшировать те или иные ресурсы полученные с сайта. Это разные форматы изображений, стили, скрипты, шрифты и так далее.
Для хостингов с использованием сервера Apache сделать это можно настройкой в файле .htaccess. Для оптимизации под Google Page Speed 1-го месяца кэширования порой недостаточно. Поэтому предлагаю ниже вариант файла .htaccess c установкой срока кэширования в 1 год.
Пример .htaccess
файла с настройками для кэширования:
<ifModule mod_expires.c> # Add correct content-type for fonts & SVG AddType application/font-woff2 .woff2 AddType image/svg+xml .svg ExpiresActive On ExpiresDefault "access plus 12 month" # Cache Images ExpiresByType image/x-icon "access plus 12 month" ExpiresByType image/jpeg "access plus 12 month" ExpiresByType image/png "access plus 12 month" ExpiresByType image/gif "access plus 12 month" ExpiresByType image/svg+xml "access plus 12 month" # Cache Fonts ExpiresByType application/font-woff2 "access plus 12 month" ExpiresByType image/svg+xml "access plus 12 month" # Cache other content types (CSS, JS, HTML, XML) ExpiresByType text/css "access plus 12 month" ExpiresByType text/javascript "access plus 12 month" ExpiresByType application/javascript "access plus 12 month" ExpiresByType application/x-javascript "access plus 12 month" ExpiresByType text/html "access plus 12 month" ExpiresByType application/xhtml+xml "access plus 12 month" </ifModule> <ifModule mod_deflate.c> AddOutputFilterByType DEFLATE text/html text/plain text/xml application/xml application/xhtml+xml text/css text/javascript application/javascript application/x-javascript application/font-woff2 image/svg+xml </ifModule>
Статья по теме про настройку сайта через .htaccess
, в том числе и про кэширование: https://habr.com/ru/post/154643/
gZip или другой способ сжатия данных сайта
Рекомендуется включить на сервере сжатие данных перед их отправкой клиенту. Так можно уменьшить размер текстовых ресурсов, следовательно ускорить загрузку сайта.
Проверить включено ли на вашем сайт gZip сжатие можно на сервисе: gidnetwork.com/tools/
Если вы хотите узнать применяется ли вообще какая либо технология сжатия, то можно проверить сайт на сервисе: whatsmyip.org/http-compression-test/
Если сжатие выключено, и нет возможности включить его настройками на хостинге, то можно сделать это внеся инструкции в .htaccess
Пример .htaccess
файла с настройками для gZip сжатия:
<IfModule mod_deflate.c> # Compress HTML, CSS, JavaScript, Text, XML and fonts AddOutputFilterByType DEFLATE application/javascript AddOutputFilterByType DEFLATE application/rss+xml AddOutputFilterByType DEFLATE application/vnd.ms-fontobject AddOutputFilterByType DEFLATE application/x-font AddOutputFilterByType DEFLATE application/x-font-opentype AddOutputFilterByType DEFLATE application/x-font-otf AddOutputFilterByType DEFLATE application/x-font-truetype AddOutputFilterByType DEFLATE application/x-font-ttf AddOutputFilterByType DEFLATE application/x-javascript AddOutputFilterByType DEFLATE application/xhtml+xml AddOutputFilterByType DEFLATE application/xml AddOutputFilterByType DEFLATE font/opentype AddOutputFilterByType DEFLATE font/otf AddOutputFilterByType DEFLATE font/ttf AddOutputFilterByType DEFLATE image/svg+xml AddOutputFilterByType DEFLATE image/x-icon AddOutputFilterByType DEFLATE text/css AddOutputFilterByType DEFLATE text/html AddOutputFilterByType DEFLATE text/javascript AddOutputFilterByType DEFLATE text/plain AddOutputFilterByType DEFLATE text/xml # Remove browser bugs (only needed for really old browsers) BrowserMatch ^Mozilla/4 gzip-only-text/html BrowserMatch ^Mozilla/4\.0[678] no-gzip BrowserMatch \bMSIE !no-gzip !gzip-only-text/html Header append Vary User-Agent </IfModule>
Включить протокол HTTP/2
Для наших задач протокол HTTP/2 хорош тем что позволяет сразу передавать несколько файлов от сервера к клиенту, избегая длинных очередей. С HTTP/1 это было невозможным. Включив HTTP/2 вы сразу значительно ускорите загрузку сайта.
SSL сертификат
SSL сертификат необходим для сайта чтобы включить HTTP/2 протокол. Можно приобрести платный либо воспользоваться бесплатным Lets Encrypt SSL сертификатом.
Сервисы бесплатных SSL сертификатов:
Accessibility — доступность
Доступность это не про скорость, но это про прохождения тестов на PageSpedd и Lighthouse. По доступности хочу дать несколько рекомендаций, который помогут вам изначально делать правильную верстку.
Размеры для изображений
При отрисовке страницы браузеру важно понимать размеры изображения, чтобы зарезервировать под него место.
Если этого не производить то происходит смещение контента, когда при открытии сайта мы видим как контент «прыгает» по странице, обычно смещаясь вниз, после подгрузки изображений, которые идет перед ним.
Чтобы такого не происходило стоит указать ширину изображений в тегах img
через атрибуты width
и height
. Тогда браузер будет заранее резервировать место под них, и смещение контента не произойдет.
Наверняка вы сталкивались с таким поведением сайтов, когда сразу после открытия нажимаем на кнопку, но в момент клика происходит подгрузка контента над кнопкой и сама кнопка смещается вниз под курсор, либо на ее месте оказывается другая, и мы кликаем по ней, совершая совсем другое действие, которое не хотели.
Атрибут aria-label для тегов button
Для устройств чтения с экрана необходимо сообщить названия кнопок, согласно тому какое действие будет происходить при их нажатии.
Пример использования атрибута aria-label
:
<button aria-label="Navigation" id="openNav" > Open navigation </button>
Теги label c описанием элементов формы
Для скрин-ридеров необходимо добавлять теги label c описанием для каждого элемента формы. Даже если такой тег отсутствует по дизайну, его стоит разместить и скрыть через CSS.
Пример html:
<label for="searchInput" class="visually-hidden">Поиск на сайте</label> <input type="text" class="search__input" placeholder="Введите текст для поиска" id="searchInput">
Стили для скрытия тег label
:
.visually-hidden { width: 1px; height: 1px; position: absolute; left: -6000px; }
Заключение
При оптимизации сайта под Google Page Speed и Lighthouse — стоит понимать что главным приоритетом должно оставаться удобство пользования сайтом и скорость его работы, а не нарисованные синтетические баллы.
Некоторые приемы оптимизации могут быть неудобны с точки зрения разработки при частом обновлении проекта.
Не все перечисленные методы являются необходимыми для применения для выхода в зеленую зону оценки. Порой достичь зелёной зоны можно внедрив лишь часть рекомендаций.
В этой статье рассмотрены только аспекты HTML верстки. Если проект работает на CMS или фреймворке, то также стоит оптимизировать работу сервера и бэкенда.