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

Доброго времени @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])
26 лайков

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

1 лайк

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

Использование метода отложенной загрузки 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/
1 лайк

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

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

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

1 лайк

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

6 лайков

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

1 лайк

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

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

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

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

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

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

Нет…

1 лайк

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

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

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

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

4 лайка

Апну тему
Есть шансы что будет внедрено в ядро?
А то есть ощущение что на тему забили тема затерялась

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

К примеру можно вынести в НЕ критические стили ховеры и все, что касается футера.

Предложенное решение является обратно совместимым и не сломает ничего.

@imac , @avoronin дайте пожалуйста внятный комментарий(будем делать, не будем делать, создайте пул реквест и т.д. ) и давайте сделаем мир немножко лучше

7 лайков

Поднимаю тему

2 лайка

Тема в Марианской впадине, без шансов.

3 лайка

Я все же надеюсь что нет, думаю реакция будет, но не так быстро, как того хотелось бы.
Первое сообщение лайкнули серьезные люди, среди которых alexbranding, ecomlabs и imac.
Значит тема действительно чего-то стоит и получит свою корректную реакцию

2 лайка

Ну они просто в трендах современного мира, лайкнуть и написать комментарий из серии, сочувствую тебе Бро, ты держись там! Ну год уже прошел, а cs-cart делают комментарии новые, о чем может быть речь? В Интересах явно не ускорить работу движка. Для того, чтобы продать, нужны же фишки зрительные, проблемы скорости люди узнают после покупки

2 лайка

@imac Получилось рассмотреть?

2 лайка

Результат рассмотрения был уже через несколько дней: