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


#1

Доброго времени @cs-cart_team !
Современные требования к качеству сайте от гугла изменились и требуют изменений на уровне ядра.
Для оптимизации одной из основных метрик LCP(эта метрика показывает действительно важную цифру, которую можно заметить даже без инструментов - время отрисовки самого большего контента во вьюпорте) предлагают использовать методику loadCss
По этому предлагаю вот что

  1. Перебрать все ненужные стили для верхней части страницы и вынесте их в файл рядом с названием styles_non_critical.[css|less]
  2. В файле app/functions/smarty_plugins/block.styles.php заменить
    if (!empty($styles) || !empty($inline_styles)) {
        fn_set_hook('styles_block_files', $styles);

        list($_area) = Tygh::$app['view']->getArea();
        $params['compressed'] = true;
        $filename = fn_merge_styles($styles, $inline_styles, $prepend_prefix, $params, $_area);

        $content = '<link type="text/css" rel="stylesheet" href="' . $filename . '" />';

        if (!empty($external_styles)) {
            $content .= PHP_EOL . implode(PHP_EOL, $external_styles);
        }
    }

на

    if (!empty($styles) || !empty($inline_styles)) {
        fn_set_hook('styles_block_files', $styles);

        list($_area) = Tygh::$app['view']->getArea();
        $params['compressed'] = true;
        $non_critical_styles = [];
        foreach ($styles as $index => $style) {
            if(strpos($style['file'],'non_critical') != false){
                $non_critical_styles[]= $style;
                unset($styles[$index]);
            }
        }
        $filename = fn_merge_styles($styles, $inline_styles, $prepend_prefix, $params, $_area);
$content = '';
        if(!empty($non_critical_styles)){
            $non_critical_filename = fn_merge_styles($non_critical_styles, '', '', $params, $_area);

            $content .='<link rel="stylesheet" href="'.$non_critical_filename.'" media="print" onload="this.media=\'all\'; this.onload=null;">'. PHP_EOL;

        }

        $content .= '<link type="text/css" rel="stylesheet" href="' . $filename . '" />';

        if (!empty($external_styles)) {
            $content .= PHP_EOL . implode(PHP_EOL, $external_styles);
        }
    }

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

  1. Сторонним разработчикам внедрить у себя в продуктах данный подход(Отделив второстепенные стили в файл styles_non_critical.[css|less])

Откладка неиспользованных файлов сss для главной страницы
Что означает данная строчка в коде include_dropdown=true ?
#2

Спасибо за детальное предложение. Изучим.


#3

Спасибо за предложение.

Использование метода отложенной загрузки CSS-стилей является хорошим, но к сожалению не подходит для CS-Cart. Из-за гибкой настройки блоков в блок-менеджере понять какие стили являются важными, а какие нет затруднительно. Поэтому сделать общее решение, которое подойдет для всех клиентов не представляется возможным.


Но данный способ подойдёт для конкретных магазинов с заблокированным блок менеджером.

Суть оптимизации:

  1. Вручную разделяем стили на важные и неважные.
  2. Важные стили грузим как обычно.
  3. Неважные стили грузятся с низким приоритетом и применяются после полной загрузки страницы

Принцип работы оптимизации:
Второстепенные стили подключаем следующим образом:
<link rel="stylesheet" href="/path/to/my.css" media="print" onload="this.media='all'">

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

Особенности оптимизации загрузки стилей на 2020 год:

  • Текущая оптимизация загрузки стилей не нуждается в JavaScript. Не нужна библиотека loadCSS.
  • Не используется современный атрибут rel=preload из-за того, что стили тогда загружаются с большим приоритетом.
  • Используется тип print, а не несуществующий тип, из-за того, что в некоторых браузерах несуществующий тип не загружается.
    Подробнее в оригинальной статье https://www.filamentgroup.com/lab/load-css-simpler/

#4

А можно добавить в настройки блоков функцию “использовать стили с низким приоритетом” и каждый сможет тогда включать / отключать в зависимости от своих предпочтений?


#5

Стили немного не так работают.
Зачастую они описаны для всего модуля в одном файле, а модуль в своё время может содержать несколько блоков, да и блоки могут быть размещены на разных диспатчах, да и на одном диспатче может быть несколько одинаковых блоков с разной настройкой да и…, да и…, да и…

А если коротко - то нет, реализация кажется очень сложной


#6

К слову, раз уж отталкиваться от блочной структуры, то в движке есть механизм, который предусматривает все возможные вариации и расширяется из модулей - это кеш. Что если файлы стилей привязывать аналогичным образом? За каждым блоком хранить в схеме путь к файлам стилей, которые можно будет заменить или дополнить модульно. Для блока “Главное содержимое” всё так же разделять по диспатчу или любым другим параметрам. Само собой отдельно иметь файл для основной структуры, который будет подключен всегда и будет иметь минимум стилей для страницы, сетки и т.д.


#7

А что если в настройки модулей тоже добавлять функцию “использовать стили с низким приоритетом”, ведь для большинства модулей это будет не критично?


#8

Сейчас буду ковырять, как раз после блоков товарных и сетки(переверстки их для Юни2) хотел это попробывать.
Я вообще думал сделать инлайном css в шапке набор стилей чтобы отрисовать шапку и сетку. А теперь думаю твоё попробывать взять, и поставить базовые стили цс карта наверх, а всё на них. Если не будет нужного еффекта, напишем просто less файл стилей для корректной быстрой отрисовки шапки, а потом все стили будут грузится в конец.
Спасибо большое для готовый кусок допила. Ллллайк


#9

Здраствуйте. А не проще нам, к примеру сделать так, чтобы очень много не перебирать сss.

  1. Просто важный код , который нам нужен для “Главной страницы” перенести в отдельный файл и подключить в head через метод loadCss

  2. А стандартное подключение которое у на в head ( {include file=“common/styles.tpl” include_dropdown=true} просто перенести в конец head


#11

Здраствуйте. А не проще нам, к примеру сделать так, чтобы очень много не перебирать сss.

  1. Просто важный код , который нам нужен для “Главной страницы” перенести в отдельный файл и подключить в head через метод loadCss

  2. А стандартное подключение которое у на в head ( {include file=“common/styles.tpl” include_dropdown=true} просто перенести в конец head


#12

Нет…


#13

Вот статья по этому вопросу из ВебДев


неужели это все не применимо к cs-cart?


#14

Не применимо в общем случае. Подробнее писал в:


#15

чуть выше описывал вариант добавления стилей по блокам через схему (как и применение шаблонов). Или же хранить за шаблонами, так как они, собственно, и привязаны к html. Добавить это к текущей структуре, сохранив полную обратную совместимость. Просто со временем всё больше стилей будут вырезаться из основного файла и подключаться к блокам. Убрав даже часть, можно будет существенно сократить их размер (к примеру, разделив главное содержимое по значению dispatch, как это делает кеширование). Понятно, что это не состыковуется с политикой единого кешируемого файла, но может это уже и не столь актуально?
Это как возможный вариант


#16

Единые и только нужные для контроллера. Для блоков которые надо только блокам на странице. Нужно писать свой движок ((