Останні роботи




Оптимизация и ускорение загрузки страницы товара сайта codan.com.ua (Opencart) техническая часть
Продолжение статьи “Оптимизация и ускорение загрузки страницы товара сайта codan.com.ua (Opencart)”.
Техническая часть
Продолжим, для тех, кто желает технических деталей… ☺
Хочу заметить, что работы по ускорению загрузки этого сайта мной уже проводились в начале 2018 года.
На VPS-сервер мной был установлен и настроен серверный модуль от Google – mod_pagespeed. Тогда, не было упора на мобильные страницы, мы получили увеличение некоторое скорости загрузки страниц раза в 2, и на этом успокоились. Теперь этим уже не обойтись, необходима максимальная скорость загрузки страниц именно на мобильных устройствах, и это обещает сэкономить деньги на рекламе… придется переделывать верстку, логику страницы, загрузку JavaScript-библиотек, CSS стили…
Начнем работу с рекомендаций сайта-тестера Google Page Speed Insights.
Самое простое – это уменьшить трафик за счет уменьшения размера изображений в пикселях, до необходимого, на странице при мобильном разрешении.
На странице товара, в инспекторе Chrome определяем необходимый размер изображений для каждой картинки при мобильном разрешении – 360 рх:
| Нынешний размер | Необходимый размер |
|
| ||
Файл изображения | Разрешение | Размер файла (byte) | Разрешение | Размер файла (byte) | Экономия (byte) | Уменьшено в % |
Размер большого изображения товара | ||||||
14778.jpg | 800 х 800рх | 193593 | 400 х 400рх | 13006 | 180587 | 1488 |
Карусели “Ранее просмотренные товары” и “Сопутствующие товары” | ||||||
132238.jpg | 200 х 200рх | 8806 | 130 х 130рх | 4708 | 4098 | 187 |
В данной теме Opencart необходимые размеры картинок выставляются в настройках темы:
Модули ⇒ Расширения ⇒ Темы ⇒ Інтернет-магазин Кодан ⇒ Размер большого изображения товара = 400 х 400
Модули ⇒ Расширения ⇒ Темы ⇒ Інтернет-магазин Кодан ⇒ Размер дополнительных изображений товара = 80 х 80
Модули ⇒ Расширения ⇒ Темы ⇒ Інтернет-магазин Кодан ⇒ Размер изображения аналогичных товаров= 130 х 130
Остальные картинки, пока не представляют особого интереса для оптимизации, ввиду небольшого размера и последующего сжатия\конвертации модулем mod_pagespeed в .webp формат и кеширования в браузере пользователя.
Для того, чтобы еще уменьшить первоначально загружаемый объем графических файлов применил технологию Lazy Load – в этом случае загружаются только видимые на первом экране графические файлы.
В данном проекте для всех слайдеров товаров используется библиотека slick.js
Для реализации технологии Lazy Load для slick.js необходимы следующие настройки:
$('.product-full').slick({ //основное большое изображение товара
lazyLoad: 'ondemand',
slidesToShow: 1,
slidesToScroll: 1,
arrows: false,
fade: true,
asNavFor: '.product-full3'
});
Аналогичные настройки при инициализации всех остальных слайдеров и каруселей.
При выводе изображений товара в макете страницы товара используем атрибут data-lazy:
<img data-lazy="<?php echo $image['thumb']; ?>" title="<?php echo $heading_title; ?>" alt="<?php echo $heading_title; ?>" />
Аналогично выводим изображения товаров на всех остальных слайдерах и каруселях «Ранее просмотренные товары» и «Сопутствующие товары».
Применение технологии Lazy Load позволяет не только снизить объем трафика данных, а и уменьшает количество начальных запросов к серверу, что в свою очередь уменьшает TTFB страницы.
CSS
Следующим этапом будет оптимизация загрузки файлов CSS.
Огромный основной файл стилей style.css загружается около секунды, поэтому я выделил в отдельный файл style_for_head.css только стили, необходимые на первом экране мобильной страницы. Его размер в 10 раз меньше размера основного style.css. Именно его я и подключаю в первую очередь. Дополнительно, для того, что-бы модуль mod_pagespeed не объединял этот файл стилей с остальными, я его добавляю в исключения для mod_pagespeed. Приходится бороться за каждую миллисекунду… ☺
Все остальные CSS файлы будем подключать как можно позже, чтобы снизить начальный трафик и сэкономить процессорное время слабого мобильного браузера на рендеринг страницы.
Подключение файла search_an.css, а он подключался в хедере, перенес из модуля (модификатора) search_an.ocmod.xml в шаблон footer.tpl.
Следующая рекомендация Google Page Speed Insights:
Для уменьшения размера кода страницы (размер структуры Dom), возникла идея подгружать мобильное меню с категориями уже после загрузки всей страницы. Посчитал, все пункты меню(категории товаров) и получилось 70 пунктов, а если на каждый пункт используется 3-4 Dom-элемента – получится экономия 200-300 Dom-элемента…
Написал ajax функцию :
function LoadMobilMenu(){
console.log('mobil-menu');
var div = $(this);
$.ajax({
method: "POST",
url: "/index.php?route=common/header/get_mobmenu",
data: {},
cache: false,
dataType: 'json',
success: function(json) {
if (json['success']) {
$('.mob-categories li:first').before(json['content']);
}
}
})
}
Php-обработчик common/header/get_mobmenu приводить не буду, ввиду его громоздкости…
В результате требование «Сократите размер структуры Dom» исчезло…
и аудит “Сокращение размера структуры Dom” появился в успешных аудитах:
За счет этой, конечно не очень простой операции, удалось сократить структуру Dom на 1099 – 729 = 370 элементов. Дополнительно, на несколько килобайт уменьшился и размер html страницы, а это все время… ☺
И вот, чего мы достигли в результате этих действий:
А теперь облегчим работу для процессора смартфона, он хоть и 8-ми ядерный (у некоторых продвинутых моделей ☺), но не у всех. И скорей он заточен на энергосбережение, чем на производительность, и больше всего его нагружает JavaScript код, который на первой, видимой части страницы, очень редко когда нужен.
Оптимизация JavaScript
На первом видимом экране, в нашем случае, основным элементом для Google является большое изображение товара:
Этот элемент выводится слайдером товара. Поэтому нам нужно загрузить и проинициализировать этот слайдер как можно раньше.
Для этого я применил предварительную загрузку контента при помощи rel=”preload”:
<link rel="preload" href="catalog/view/js/slick.min.js" as="script">
<link rel="preload" href="catalog/view/js/slick-init.js" as="script">
Выделил из common.js эту часть кода, отвечающую за инициализацию – slick-init.js для ранней инициализации слайдера товара.
А теперь постараемся вынести весь остальной JavaScript-код в футер, или, что еще лучше, в отложенную загрузку. И чем меньше JavaScript будет в <head> части сайта, тем лучше будут показатели в Google PageSpeed.
Этот процесс самый сложный и занимает больше всего времени.
Потому, что изменение порядка чередования JavaScript файлов может полностью нарушить работоспособность какого-то функционала сайта, причем на этой, оптимизируемой странице все может работать, а например на странице оформления заказа может не работать или работать не так, как хотелось-бы ☺.
Смотрим… какие «лишние» JavaScript-файлы грузятся в самом начале и распределяем их кого куда:
Дальше все просто ☺
Находим в каком модуле, плагине загружается каждый файл и переставляем, если это возможно, загрузку его в нужное место. Нужно полностью понимать для чего нужен этот файл и к чему приведет его перестановка в другое место…
После каждого изменения кода необходимо проверить не появились ли ошибки в консоли JavaScript и не нарушилось функционирование ВСЕХ страниц сайта…
Для отложенной загрузки использовал такой код:
$(window).load(function () { //сформирована абсолютно вся страница и загружены все картинки и другие мультимедийные элементы.
setTimeout(function() {
loadJScript("./catalog/view/js/ion.js");
loadJScript("./catalog/view/javascript/cookiespolicy.js");
loadJScript("./catalog/view/javascript/inputmask.min.js");
.........
}, an_javascript_aside );
function loadJScript(src) {
let script = document.createElement('script');
script.src = src;
document.body.append(script);
}
});
Переменная an_javascript_aside вводится а административной части в настройках обновленного модуля Сервис_An и называется – Отложить загрузку некоторых JavaScript на (мСек).
В отложенную загрузку были помещены следующие JavaScript:
– cookiespolicy.js
– inputmask.min.js
– magnific-popup.min.js
– ion.js
– classie.js
Скрипт по выбору отделений Новой почты убрал из общего common.js и перенес на страницу Checkout.
Скрипт notice_an.js перенес их хедера в футер, для этого пришлось доработать модуль Notice_An.
В процессе анализа файлов был обнаружен абсолютно не нужный на странице товара файл JavaScript – ajax-product-page-loader.js. Пришлось переделать модификатор модуля An Category Product Ajax Loader by Andrey_An (2018) с целью загрузки нужных скриптов только на странице категорий.
Google Tag Manager
Это отдельная категория JavaScript файлов. Хотя они и загружаются асинхронно, но они все равно, по мнению САМОГО Google PageSpeed, почему-то сильно тормозят загрузку. Посему решено было их забросить в отложенную загрузку посредством все того-же setTimeout(function() {…
Для этого типа скриптов в админке ввел свою задержку.
Web шрифты
В данном проекте используются шрифты Open Sans и Roboto, которые грузились с внешнего ресурса fonts.googleapis.com, а это дополнительное время на соединение, скачивание… Эти шрифты были скачаны и установлены на сервер. Также, для ускорения отрисовки страницы, ко всем шрифтам был добавлен параметр swap, с помощью которого, не дожидаясь загрузки красивого и тяжёлого внешнего шрифта, показывает текст в браузере сразу, используя встроенный в этот же браузер шрифт (например sans-serif). Это сразу же убирает один из ошибок в Google Page Speed.
CLS (Cumulative Layout Shift)
Большое совокупное смещение макета(CLS) приводит к дерганию элементов страницы в процессе загрузки. За счет более раннего подключения нужных стилей, ранней инициализации слайдеров товара удалось сократить этот показатель с 0,921 до 0,068, т.е. в 13.5 раз.
Минификация файлов JavaScript и CSS
Ввиду того, что мне приходится постоянно что-то делать с сайтом, изменять \ дорабатывать файлы шаблонов, JavaScript , CSS… , то исходные файлы решил не минифицировать, а эту функцию минификации я решил возложить на модуль mod_pagespeed. Посему еще тогда был написан модуль для управления mod_pagespeed посредством оперативного изменения файла .htaccess. Этот модуль был написан ранее, еще при внедрении самого mod_pagespeed, но тогда там было минимум настроек:
Сейчас же я решил включить туда еще некоторые дополнительные настройки:
Модифицированный модуль позволяет управлять серверным модулем mod_pagespeed из админ-панели сайта:
– включить\выключить модуль mod_pagespeed;
– очистить cash модуля mod_pagespeed;
– вывод контейнера GTM можно отключить или отложить его подключение по времени;
– включить\выключить cash браузера;
– объединять JavaScript-файлы;
– minифицировать(сжимать) JavaScript-файлы;
– отложить подключение по времени некоторых JavaScript-файлов;
– объединять CSS;
– min-ифицировать(сжимать) CSS;
– конвертировать jpeg, png в webp;
– включить\выключить ленивую загрузка изображений (lazyload_images);
– не обрабатывать файлы(список файлов через ; )
Сервер
При анализе работы сервера, было обнаружено несколько узких мест:
– в файле .htaccess было Header set Cache-Control “max-age=2592003” – 30 дней
ставим 33696039 30 дней * 13 = 1 год + и еще добавил туда woff2. Аудит стал успешным;
– в файле .htaccess было обнаружено более 200 строк 301-редиректов, так понимаю это с старого, несуществующего уже сайта на нынешний. Также я выяснил, что последний раз это дело менялось почти 2 года назад – 17.10.18., а каждый запрос к серверу,а их около сотни на каждую страницу (любая картинка или файл) пробегает всю эту цепочку… Заказчик дал добро на удаление этих редиректов. Так мы сэкономили еще немного времени;
– Для дальнейшего увеличения скорости загрузки необходим протокол HTTP/2, который уже поддерживают все браузеры и который позволяет сильно ускорить обмен данными между браузером и сервером. Наш сервер был создан почти 4 года назад и имеет: Ubuntu 16 в качестве системы , Apache 2.4.18 в качестве вебсервера, PHP Version 7.0… Вообщем это сильно устаревшие на сегодняшний день продукты. Для поддержки протокола HTTP/2 необходим вебсервер Apache с версии 2.4.24. Поэтому в дальнейшем мы переходим на новый сервер с Ubuntu 20 и всеми новыми серверными продуктами. Но это уже другая история…
Работы были начаты 25.07.2020 и закончены 17.08.2020.