Как ускорить сайт?

Как ускорить сайт и зачем

Как ускорить сайт по PageSpeed Insights by Google

Опубликовано:

Как ускорить сайт? Зачем ускорять сайт? Если вы уже задавались этими вопросами, то добро пожаловать! В данной статье мы разберемся как ускорить сайт на WordPress, но также большинство примеров подойдет для Bitrix, OpenCart, Modx. Приятного чтения 🙂

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

В 2019 году критерии, по которым определяется насколько быстро работает ваш сайт сильно изменились. В первую очередь это связано с тем, что большая часть трафика — это смартфоны. Смартфоны стали более доступным устройством. Все больше людей могут позволить себе карманный компьютер с доступом в интернет (да, в наше время всё еще около 1/3 всего населения не имеют устройств с доступом интернет), а так как мобильный интернет работает в разы медленнее, чем компьютер с подключенным кабелем, то отсюда и можно понять почему требования к скорости так растут.


В первую очередь эта статья рассчитана на разработчиков, которые смогут найти для себя ответы с примерами кода. Однако, если вы заказчик, который задается этим вопросом — вы можете связаться со мной любым удобным способом и мы сможем пообщаться на эту тему отдельно. И как совет, проверьте на скорость сайт компании, у которой хотите заказать ускорение 🙂

Итак, в этой статье мы рассмотрим следующие вопросы:

Зачем нужно ускорять сайт?

На сегодняшний день в интернете вы можете найти множество исследований о том, как скорость сайта влияет на конверсию, из чего следует простой вывод: свой сайт нужно поддерживать и развивать, дабы не терять актуальность на рынке.

Как проверить насколько быстро работает сайт?

Здесь все очень просто. Существует приложение от Google и называется оно PageSpeed Insights. Достаточно перейти по ссылке, ввести в поле ввода сайт и нажать «Анализировать». Примерно то, что вы должны там увидеть:

ускорение сайта

Всего вам выставляется две оценки: для мобильных устройств и для компьютеров. На мой взгляд, так как мобильный интернет сейчас преобладает, да и требования к мобильным версиям в разы жестче, лучше ориентироваться по оценке для мобильных устройств. Оценка выставляется от 0 до 100, где 0 — 49 — это низкая скорость, 50 — 89 — средняя скорость и 90 — 100 — высокая скорость. Если после проверки вы видите оценку от 90 и выше — смело закрывайте эту статью 🙂

По каким критериям измеряется быстрота работы?

Если максимально упрощенно, то основными критериями являются время ответа сервера, общий вес сайта и вес отдельных его элементов, количество запросов к серверу.

Время ответа сервера — это такое время, которое ожидает пользователь с момента перехода на ваш сайт до получения первых данных. Здесь влияет оптимизация кода на backend’e и много всего другого.

Пункт общий вес сайта и отдельных его элементов говорит сам за себя

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

Логично, что если ваш сайт будет весить мало, а сервер быстро отвечать на запросы клиента — все будет хорошо 🙂

Как ускорить сайт?

Безусловно реализация ускорения сайта будет изменяться в зависимости от того, какие технологии он использует. В качестве примера мы возьмем популярный стек — сайт на WordPress + jQuery. Ориентироваться будем на все тот же Google PageSpeed Insights, изучаем его рекомендации и разбираемся что с ними делать:

Уменьшите размер кода CSS и Уменьшите размер кода JavaScript

Проблема возникает когда в CSS или JS файлах присутствуют лишние символы: пробел, табуляция, возврат каретки, новая линия. Так как символы не влияют на интерпретацию кода браузером, а просто присутствуют в файле, следовательно, занимают место — их нужно удалить. Также это может сигнализировать о том, что в коде есть дублирование (к примеру дважды написанный media запрос в CSS). Обычно Google PageSpeed Insights находя такие файлы оптимизирует их сам и предлагает скачать, остается только подменить старые файлы новыми. Но, лучше конечно использовать gulp, webpack или другие инструменты, чтобы после каждого изменения не приходилось повторять эту процедуру.

Сложность: легко.

Включите сжатие текста

Необходимо включить сжатие при передаче данных от сервера к клиенту. Делается это в настройках сервера путем добавления дополнительной конфигурации.

Сложность: легко.

Apache .htaccess
<IfModule mod_deflate.c>
    <IfModule mod_filter.c>
        AddOutputFilterByType DEFLATE text/html text/plain text/xml
        AddOutputFilterByType DEFLATE text/css
        AddOutputFilterByType DEFLATE application/x-javascript application/javascript application/ecmascript
        AddOutputFilterByType DEFLATE application/rss+xml
        AddOutputFilterByType DEFLATE application/xml
    </IfModule>
</IfModule>
Nginx nginx.conf
server {
    gzip on;
    gzip_disable "msie6";
    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 6;
    gzip_buffers 16 8k;
    gzip_http_version 1.1;
    gzip_min_length 256;
    gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/vnd.ms-fontobject application/x-font-ttf font/opentype image/svg+xml image/x-icon;
}

Устраните ресурсы, блокирующие отображение

Первоначальной отрисовке контента мешают файлы, загружаемые в теге <head> , в основном это статические файлы стилей, шрифтов и скриптов. Решается это переносом из <head> в конец тега <body>. Здесь может возникнуть логичный вопрос: если переместить CSS ниже, то будет ли отрисовка HTML без стилей?. Будет, но для этого применяют специальный прием - Critical CSS, где основные правила выносят в тег <style> внутри <head>, а остальные стили переносят вниз. Лучшим решением будет автоматизация процесса через gulp или webpack.

Сложность: средне.

Настройте подходящий размер изображений

Если ваш сайт предназначен для смартфонов, то необходимо позаботиться о том, чтобы на этих устройствах не загружались изображения c большим разрешением. Незачем загружать большие изображения там, где они не нужны. Для этого внутри WordPress есть механизм thumbnails а на клиенте можно использовать srcset с media запросами.

Сложность: сложно.

Srcset example
<picture>
    <source media="(max-width: 767px)" srcset="thumbnail-mobile.jpg">
    <source media="(min-width: 769px) and (max-width: 960px)" srcset="thumbnail-tablet.jpg">
    <source media="(min-width: 961px)" srcset="thumbnail-desktop.jpg">
    <img src="thumbnail-desktop.jpg" srcset="thumbnail-desktop.jpg">
</picture>

Отложите загрузку скрытых изображений

Также не стоит загружать изображения, которые пользователь еще не видит. Поэтому в изображениях, которые находятся не в зоне первой отрисовки нужно заменить атрибут src, на data-src и позже, с помощью JavaScript, по мере приближения пользователя к картинке, заменить data-src на src.

Сложность: средне.

LazyLoad.js
var LazyLoad = {
  images: [],

  init: function () {
    this.initOnLoad();
    this.initOnScroll();
  },

  initOnLoad: function () {
    var that = this;
    $(window).on('load', function () {
      that.prepareImagesCollection();
      that.checkImages();
    });
    return false;
  },

  prepareImagesCollection: function () {
    var that = this;

    $('img[data-src]').each(function () {
      var image = {
        object: $(this),
        offset: $(this).offset().top,
        srcset: $(this).attr('data-srcset') ? $(this).attr('data-srcset') : null,
        src: $(this).attr('data-src') ? $(this).attr('data-src') : null,
        loaded: false
      };

      that.images.push(image);
    });
    return false;
  },

  checkImages: function () {
    var that = this;
    for (var i = 0; i < that.images.length; i++) {
      var image = that.images[i];
      if (image.loaded === false && image.offset < ($(window).scrollTop() + $(window).height() + 300)) {
        that.loadImage(image);
        image.loaded = true;
      }
    }
    return false;
  },

  loadImage: function (image) {
    image.object.attr('srcset', image.srcset)
      .attr('src', image.src)
      .removeAttr('data-srcset')
      .removeAttr('data-src');
    return false;
  },

  initOnScroll: function () {
    var that = this;
    $(window).on('scroll', function () {
      that.checkImages();
    });
    return false;
  }
};

LazyLoad.init();

Отложите загрузку неиспользуемого контента CSS

В основном проявляется когда в стилях много лишних правил, которые не используются. Требует полного рефакторинга кода, что может затянуться надолго.

Сложность: сложно.

Настройте эффективную кодировку изображений

Google очень не любит картинки, а особенно плохо оптимизированные, поэтому здесь нужно решить вопрос с оптимизацией картинок. На WordPress это делается с помощью плагинов и практически все они платные. Вот список, которыми пользовался я и мог бы рекомендовать вам:

Сложность: сложно, потому что платно 😀

Используйте современные форматы изображений

Как я упоминал выше - отношение Google к картинкам оставляет желать лучшего, и, на самом деле, для этого есть все основания. Растровые изображения есть практически на каждом сайте и в среднем составляют более 50% от общего веса, решением этой проблемы стали прогрессивные форматы, в которых используется более эффективное сжатие: WEBP, JPEG 2000, JPEG XR. Правда поддерживаются они не всеми браузерами, поэтому оценку не особо высоко поднимает. Решается это также плагинами, которые конвертируют изображения в WEBP и корректной настройкой сервера. Я использую EWWW Image Optimizer.

Сложность: средне.

Apache .htaccess
<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{HTTP_ACCEPT} image/webp
    RewriteCond %{REQUEST_FILENAME} (.*)\.(jpe?g|png)$
    RewriteCond %{REQUEST_FILENAME}\.webp -f
    RewriteCond %{QUERY_STRING} !type=original
    RewriteRule (.+)\.(jpe?g|png)$ %{REQUEST_FILENAME}.webp [T=image/webp,E=accept:1,L]
</IfModule>
<IfModule mod_headers.c>
    Header append Vary Accept env=REDIRECT_accept
</IfModule>
    AddType image/webp .webp
Nginx nginx.conf
location ~* /wp-content/uploads/.+\.(png|jpe?g)$ {
  try_files $uri.webp $uri /index.php?$args;
}

Используйте видеоформаты для анимированного контента

Формат анимации .GIF слишком "тяжелый", поэтому рекомендуется конвертировать все .GIF в .MP4

Предотвратите чрезмерную нагрузку на сеть

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

Сложность: легко. Не требует внимания.


Задайте правила эффективного использования кеша для статических объектов

Корректно настраиваем сервер, кешируя все статические файлы на 1 год, включая файлы CSS и JS. Здесь может возникнуть логичный вопрос: как быть, если CSS и JS будет изменяться, а у пользователя он будет закеширован? Ответ простой: необходимо воспользоваться приемом Cache Busting, добавляя к каждому CSS и JS файлу после его изменения GET параметр.

Сложность: легко.

Apache .htaccess
<filesMatch ".(jpg|jpeg|gif|png|svg|js|css|mp3|ogg|mpe?g|avi|zip|gz|bz2?|rar|swf|woff|eot|ttf|pdf|mp4|exe|doc|html|flv|ico|xml|txt|css|ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|rss|atom|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)$">
  Header set Cache-Control "max-age=31536000, public"
</filesMatch>
Nginx nginx.conf
location ~* .(jpg|jpeg|gif|png|svg|js|css|mp3|ogg|mpe?g|avi|zip|gz|bz2?|rar|swf|woff|eot|ttf|pdf|mp4|exe|doc|html|flv|ico|xml|txt|css|ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|rss|atom|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)$ {
  expires 365d;
}
Wordpress functions.php
<?php
// Четвертым параметром в функции передается его версия.

wp_enqueue_script('my-script', '/js/all.min.js', [], 'version1.0');
Cache busting
<!-- Дополняя GET параметром реализуем cache busting -->

<link href="/styles/style.min.css?v=1.0" as="style">
<link href="/js/all.min.js?v=1.0" as="script">

Сократите время выполнения кода JavaScript / Минимизируйте работу в основном потоке

Достаточно сложные пункты, так как предполагают полный рефакторинг JavaScript кода для оптимизации.

Сложность: сложно.

Сократите размер структуры DOM

Большое количество узлов DOM дерева негативно влияет на производительность, поэтому решается только сокращением узлов и вложенности.

Сложность: средне.

Сократите время ответа сервера (время до получения первого байта)

Самый непостоянный пункт, так как здесь много чего зависит не от нас. Тем не менее с нашей стороны тоже есть действия: нужно кешировать ответы сервера. Незачем доставать все данные из базы и снова генерировать страницу, если ничего не изменилось. Поэтому используем плагины для кеширования. Несколько примеров:

Сложность: легко.

Сократите глубину вложенности критических запросов

Стоит избегать цепочек запросов. Пример цепочки: браузер получает HTML файл, видит, что в нем есть CSS файл, обрабатывает его и тут обнаружилось, что нужны еще шрифты и браузер снова отправляет запросы на шрифты. Было бы лучше, если бы браузер знал о них сразу, верно? Пользуемся механизмом preload, говорим браузеру о том, что вот есть такие файлы, которые тоже нужно вскоре загрузить.

Сложность: легко.

Preload
<link rel="preload" href="/styles/style.min.css" as="style">
<link rel="preload" href="/js/all.min.js" as="script">
<link rel="preload" href="/fonts/Exo2-Regular.woff2" as="font" crossorigin="anonymous">

Заключение

Надеюсь в данной статье вы нашли ответы на вопросы: как ускорить сайт? зачем ускорять сайт? Если у вас появились какие-то вопросы или вас интересует ускорение сайта - обращайтесь ко мне используя удобные для вас способы связи. Спасибо!