Критический CSS + прогрессивный CSS = ?
Однажды я прочел статью на Хабре о результатах, полученных при проведении ребятами из Google различных тестов. Они выяснили, что в большинстве сценариев встраивание стилей в HTML приводит к более быстрой загрузке страницы, чем подключение стилей одним файлом. Тем не менее, такой трюк я не применял, за одним исключением: в одном проекте, в котором я принимал участие, было реализовано встраивание стилей на страницу сгенерированного лендинга, что действительно немного ускоряло загрузку. При разработке обычных сайтов заморачиваться с загрузкой стилей не обязательно, но есть и такие проекты, где необходимо показать страницу пользователю как можно скорее, ведь это может улучшить аудиторные показатели. Для этого существуют, как минимум, две практики: «критический CSS» и «прогрессивный CSS».
Критический CSS Скопировать ссылку
Основной принцип в обеих практиках заключается в том, что стили загружаются постепенно, а не все сразу. Критический CSS — это стили, которые необходимы для отрисовки первой видимой части страницы. Выделить такие стили автоматически вы можете с помощью пакета CriticalCSS. Для моментальной отрисовки критический CSS встраивают в HTML, все остальные стили загружаются отдельным файлом асинхронно.

При отрисовке HTML, как только браузер встречает или , он останавливается и ждёт, пока JS или CSS-файл загрузится, и только после этого идет дальше. При использовании с атрибутами async и defer , мы можем попросить браузер загружать скрипт асинхронно, без блокировки рендеринга страницы, но у таких атрибутов нет. Из этой ситуации нас спасёт функция loadCSS — её использование позволит вашей странице отрисоваться с критическим CSS и не ждать полной загрузки остальных стилей.
/* Критические стили */ .article, .comments, .about, .footer …
Как это работает? Если коротко, то эта функция создает с атрибутом media=»only x» . Таким образом, браузер загружает стили, при этом не блокируя рендеринг страницы. После того, как стили загружены, атрибуту задается значение media=»all» . В современных браузерах, поддерживающих rel=»preload» для , можно обойтись без loadCSS.
С media=»only x» такой трюк не сработает: разные браузеры загружают CSS по-разному, loadCSS учитывает все эти нюансы.
Прогрессивный CSS Скопировать ссылку

Прогрессивный CSS предполагает создание отдельного CSS-файла для каждой части страницы: перед каждой вставляется со стилем только этой части. Благодаря тому, что блокирует рендеринг до окончания загрузки стилей, страница будет загружаться последовательно по частям. В этом сценарии выгоднее всего использовать HTTP/2, он хорошо работает с одновременными запросами.
Пришла пора признаться, что прогрессивный CSS это скорее концепт, чем что-то применимое на практике: в спецификации HTML никак не объяснено, как рендеринг страницы должен блокироваться загрузкой CSS и как должен вести себя в , поэтому все браузеры обрабатывают эту ситуацию по-своему. Можно выделить два основных поведения браузеров:
- Встретил ;
- Дождался загрузки всех обнаруженных стилей;
- Рендерит дальше.
Подробнее про поведение каждого браузера можно почитать у Джейка Арчибальда. На реальных проектах прогрессивный CSS в полной мере не применить, но сама концепция выглядит очень интересно.
Gulp в помощь Скопировать ссылку
Чтобы с лёгкостью применять критический и прогрессивный CSS вместе во всех браузерах, я написал плагин gulp-progressive-css. Этот плагин обрабатывает HTML-файлы и добавляет возможность использовать атрибуты priority=»critical» , priority=»queued» и priority=»async» у элемента .
Стили, подключенные с атрибутом priority=»critical» , будут встроены в HTML-файл, а стили с атрибутом priority=»queued» или priority=»async» будут загружены асинхронно с помощью функции importCSS. Это вариация функции loadCSS , её особенность в том, что загрузка стилей начинается одновременно, но стили с priority=»queued» будут применяться в том порядке, в котором они были указаны в HTML-файле. Чтобы загрузка стилей работала одинаково во всех браузерах, подключение стилей переносится в конец . Также добавляется в для каждого файла стилей, чтобы в браузерах, которые поддерживают rel=»preload» , загрузка начиналась еще при обработке .
Результаты применения Скопировать ссылку
Я решил взять один из лендингов, который однажды верстал, и на его примере продемонстрировать пользу применения асинхронной загрузки стилей.
Тестируем изначальный вариант лендинга на PageSpeed Insights:

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

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

На этом примере становится понятно, что небольшому лендингу основное ускорение придает асинхронная загрузка шрифтов, а не прогрессивная загрузка стилей. Так происходит из-за слишком малого размера файла стилей. Прогрессивная загрузка будет давать ощутимую пользу только полноценным сайтам, у которых размер стилей больше в несколько раз.
Источники Скопировать ссылку
- 33 способа ускорить ваш фронтенд в 2017 году, Александр Гутников
- The future of loading CSS, Джейк Арчибальд
- Ускорение Lenta.ru: 3 человека, 2 недели, улучшение глубины просмотра на 27%, Денис Паращий
Как подключить к пакету css файл
Дизайн Web-страниц — это точное размещение компонентов HTML-страниц относительно друг друга в рабочей области окна браузера.
К компонентам страницы относятся:
- блоки текста
- графика
- встроенные приложения.
Размер и границы каждого из этих компонентов в рамках HTML-разметки задаются с разной степенью точности. Размер графики и приложений можно задать с точностью до пикселя. Размеры текстовых блоков в HTML задать нельзя: они вычисляются браузером исходя из относительного размера шрифта по умолчанию.
Автор страницы не может заранее определить настройки браузера пользователя, что существенно ограничивает число вариантов представления информации на странице.
CSS (Cascading Style Sheets) позволяет полностью контролировать форму представления элементов HTML-разметки.
Каскадные таблицы стилей призваны разрешить противоречие между точностью определения размеров картинок и приложений, с одной стороны, и точностью определения размеров блоков текста и его начертания — с другой.
Таблицы стилей также позволяют определить цвет и начертание текстового фрагмента, изменять эти параметры внутри текстового блока, выполнять выравнивание текстового блока относительно других блоков и компонентов страницы.
Наличие подобных возможностей позволяет говорить о CSS как о средстве разделения логической структуры документа и формы его представления.
Логическая структура документа определяется элементами HTML-разметки, в то время как форма представления каждого из этих элементов задается CSS-описателем элемента.
CSS (CascadingStyleSheets) — Каскадные таблицы стилей — это свод стилевых описаний, тех или иных HTML тегов (далее элементов HTML), который может быть применён как к отдельному тегу — элементу, так и одновременно ко всем идентичным элементам на всех страницах сайта.
2. Способы подключения CSS к HTML коду
Давайте теперь разберемся с тем, как сделать так, чтобы написанный CSS применился к нашему HTML коду.
Различают четыре способа применения стилей:
- переопределение стиля в элементе разметки;
- размещение описания стиля в заголовке документа в элементе style ;
- размещение ссылки на внешнее описание через элемент link;
- импорт описания стиля в документ.
Первые два способа заключаются в том, что CSS код будет написан прямо на HTML странице. Третий способ заключается в том, что CSS будет написан в отдельном файле и специальным образом подключен к нашей HTML странице. Третий способ используется гораздо чаще (в подавляющем большинстве случаев). С ним соперничает четвертый способ. Одновременно можно применять все четыре способа.
Давайте разберемся с этими способами более подробно.
CSS внутри атрибута style
Первый способ заключается в том, что можно добавить атрибут style любому тегу на странице и прямо там написать для него HTML код. Обратите внимание на то, что при этом никаких селекторов писать не нужно, так как CSS код применится только к тому тегу, для которого он написан:

Первый способ не рекомендуется к использованию, потому что он захламляет HTML код.
2 CSS внутри тега style
Второй способ заключается в том, что CSS код можно написать в теге <style> Его можно размещать как внутри <head> (чаще всего), так и внутри <body>.

Недостаток этого способа в том, что CSS код применяется только к одной странице сайта, а не ко многим. Этот способ обычно применяется тогда, когда нужно написать CSS на конкретной странице сайта, не затрагивая остальных, и, в общем случае, к употреблению не рекомендуется.
3 Отдельный CSS файл
Самый распространенный способ подключения CSS — это когда он хранится в отдельном файле и этот файл подключается ко всем страницам нашего сайта.
Преимущество такого подхода в том, что CSS файл один, а HTML файлов может быть любое количество, хоть тысяча. Мы сделаем изменение в одном месте CSS файла, например, покрасим все абзацы в красный цвет, и эти изменения применятся на всей 1000 HTML страниц, к которым подключен наш CSS файл. Очень удобно и быстро.
Чтобы подключить CSS файл к HTML странице, в теге head следует написать такую конструкцию:
<linkrel=»stylesheet» href=»путь к CSS файлу»>.
Сам CSS файл должен быть с расширением .css. Обычно его называют styles.css или style.css.
В следующем примере к нашему HTML файлу подключается CSS файл style.css:

Можно подключать не один файл, а несколько. Давайте подключим файлы style1.css, style2.css и style3.css:
Организация пакетов с помощью css-suki
Стили и соответствующие им картинки группируются в однин модуль. Для каждого модуля — отдельная директория. Ссылки к картинкам задаются относительно родительской директории. Например, для модуля «pager» создаётся одноимённая директория, в которую кладётся один или несколько css с произвольным названием (например, с тем же — «pager.css»), рядом с ним картинка «pager-current_bg.png», ссылка к которой выглядит так «../page/pager-current_bg.png». Картинка из примера задаёт фон для элемента содержащего номер текущей страницы в пэйджере. Имена картинок складываются из имени элемента (pager-current, pager-next, pager-prev..), расположения картинки (bg, top, left, top-left, icon..) и модификаторов (hover, active, selected..), разделённых между собой подчёркиванием. Сложный пример: pager-next_icon_hover.png
Группировка в модуль происходит по родству. Например, в модуле «text» могут содержаться стили для стандартных элементов гипертекста (em, strong, q..), в «form» — стили для элементов форм, в «table» — всё, что касается таблиц. Разметка выполняется как описано в статье про независимые элементы.
Бонусом от этих шаманств является высокая степень независимости визуальных модулей друг от друга, что позволяет легко переносить их между проектами и пакетами не заботясь о порядке их подключения. Некоторые модули требуют подключения вначале (например, css-reset) — их можно именовать добавляя в начале цифру (например, «0_reset»).
Как было упомянуто выше, модули собираются в пакеты — простой группировкой по директориям. Пакет конечному пользователю приходит одним файлом. Разработчик же может переключиться в режим загрузки всех css файлов по отдельности.
Для спрайтов заводится отдельный модуль. Но не стоит без крайней необходимости засовывать все картинки в один файл — лучше группировать по смыслу и форм-фактору.
Описанная файловая структура позволяет компилировать стили простым слиянием всех файлов, не ломая при этом относительные ссылки к картинкам. При запуске css-suki создаёт в указанном пакете псевдомодуль с именем «~» куда записывает index.css, compiled.css и при необходимости разбивки на страницы page=*.css. Благодаря автоматическому разбиению на страницы, в пакете может быть до 900 css-файлов даже в IE.
Чтобы создать новый модуль, вы просто создаёте директорию внутри пакета и в ней css-файл. Вам не нужно никуда дополнительно его прописывать — всё будет сделано автоматически. Перенос в другой пакет осуществляется соответствующим образом. Работа с пакетами полностью аналогична. Благодаря относительным путям вам не надо беспокоиться о том, в какой директории надо расположить стили, в «/css/», «/client/styles/» или ещё где.
А вот и собственно компилятор (пакеты нужно создавать прямо рядом с ним):
# входные параметры
$mode = @ $_GET [ ‘mode’ ] or $mode = ‘index’ ;
if( $mode === ‘source’ ) highlight_file ( __FILE__ ) and die();
$name = preg_replace ( ‘![^\w-]+!’ , » , @ $_GET [ ‘name’ ] ) or $name = ‘main’ ;
# константы
$pageLimit = 30 ;
# подготовка файловой системы
chdir ( $name );
@ mkdir ( ‘~’ , 0777 , true );
# составление списка файлов пакета
$files = glob ( «??*/*.css» , GLOB_BRACE );
sort ( $files );
$filesCount = count ( $files );
if( $filesCount > pow ( $pageLimit , 2 ) ) print ‘too many files’ and die();
# компиляция в один файл
$compile = array();
foreach( $files as $file ):
$compile []= «/* @import url( ‘../’ ); */» ;
$compile []= file_get_contents ( $file ) . «\n» ;
endforeach;
$compile = implode ( $compile , «\n\n» );
file_put_contents ( «~/compiled.css» , $compile );
# формирование индекса
if( $filesCount < $pageLimit ):
$index = preg_replace ( ‘!(.+)!’ , ‘../$1’ , $files );
else:
$index = array();
for( $page = 0 ; ( $page * $pageLimit ) < $filesCount ; ++ $page ):
$index []= «page=.css» ;
endfor;
endif;
# сохранение индекса на диск
$index = preg_replace ( ‘!(.+)!’ , ‘@import url( «$1» );’ , $index );
$index = implode ( $index , «\n» );
file_put_contents ( «~/index.css» , $index );
# нарезание списка файлов на страницы и запись их на диск
if( $filesCount >= $pageLimit ):
for( $page = 0 ; ( $page * $pageLimit ) < $filesCount ; ++ $page ):
$pageFiles = array_slice ( $files , $page * $pageLimit , $pageLimit );
$pageFiles = implode ( preg_replace ( ‘!(.+)!’ , ‘@import url( «../$1» );’ , $pageFiles ), «\n» );
file_put_contents ( «~/page=.css» , $pageFiles );
endfor;
endif;
# браузеру отдаётся ссылка на нужный файл
switch( $mode ) case ‘index’ : case ‘compiled’ :
header ( «Content-Type: text/css» , true , 200 );
echo «@import url( ‘/~/.css’ );\n» ;
break;
default:
echo «wrong mode» ;
>
exit(); ?>
параметры:
mode — режим работы
name — имя пакета
режимы работы:
source — исходник css-suki
index — ссылка на индексный файл подключающий все файлы, принеобходимости разбивает вывод на страницы
compiled — ссылка на содержимое всех файлов одной простынёй
Назначение
Программный пакет CSS Control System Studio средство для мониторинга и управления широко масштабными системами управления.
Представляет попытка реализации концепции визуального программирования, когда люди основной деятельность которых не является программирование на универсальном языке имеют возможность самостоятельно реализовывать интерфейс доступа и управления объектом. Данная задача решается с помощью простого встроенного визуального редактора. Редактор позоляет произвольным образом размещать специальные виджеты готовые для работы с ситемой. Естественно это возможно при условии что нижний уровень предоставляет такую возможность. При необходимости можно писать простенькие скрипты на питне или яваскрипт.
Запуск css на машинах пульта ВЭПП
Для запуска служит CSS скрипт css-vepp4.
css-vepp4
При запуске CSS создает в домашней директории рабочего окружения файл блокировки. Поскольку домашняя директория общаяя для всех машин пультовой, то возникает проблема запуска на разных машинах. Данную проблему и решает скрипт css-vepp4 добавляя в путь до директории рабочего окружения имя компьютера.
Установка
Для загрузки с сайта CSS предлагается версии 3 и 4 под linux И Windows, как 32 так и 64 разрядные. На ВЭПП используется версия 3.x.x. Версия 3 требует для своей работы java 7, данное условие выполняется для Scintific Linux 5.x, достаточно установить пакет java–1.7.0-openjdk. Версия 4 требует java 8.
Linux
- готовые rpm пакеты
- сборка rpm пакета
Данный rpm пакет это переупаковка исходного архива с добавлением зависимостей и скрипта css-vepp4, для его сборки jdk не требуется. Получить spec
git clone --branch css https://star.inp.nsk.su/~bekhte/rpms.git rpms.css
- Установка в домашнюю директорию
Скачать, распаковать, запустить
windows
Скачать, распаковать, запустить
Настройка
После установки необходимо настроить CSS и установть opi файлы. При первом запуске будет создано рабочее пространство, где будут храниться настройки и opi файлы. Для определенности предположим что папка называется css-workspace. Папка создается скриптом css-vepp4 в домашней директории (под Windows %USERPROFILE%\css-workspace).
Перспектива

Приветственное окно можно закрыть нажав на кнопку Workbench

получение opi файлов
После создания папки с рабочим пространством, следует установить файлы описания окон — opi файлы.
Суперрепозиторий
Устанавливаем opi файлы с использованием менеджера репозиториев. Это репозиторий в котором содержится список всех остальных репозиториев.
последовательность для установки в уже существующую папку CSS, не удаляя файлы
cd ~/css-workspace/CSS git init git remote add origin https://star.inp.nsk.su/~bekhte/vepp-opi.git git fetch git checkout -t origin/CSS-vepp4 git status make check make clone_all

Экран верхнего уровня
Далее надо открыть файлы в рантайм окружении. Это можно достигнуть многими способома, например пропишем главное окно ВЭПП4 в качестве окна верхнего уровня, это удобно потому что для вызова этого окна есть специальная кнопка в интерфейсе.
Откроем меню Edit -> Preferences… -> CSS Aplication -> Display -> BOY
В поле ввода TOP OPIs напишем “/CSS/vepp-opi/main.opi” — вызов окна верхнего уровня ВЭПП4

Теперь нажав на кнопку вызова окна верхнего уровня

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

Не нужную перспективу можно закрыть выбрав соответствующий пункт по правой кнопке мышы на заголовке перспективы

Теперь окно приняло настроенный вид

CSS сохраняет при закрытии расположение окон, поэтому данную процедуру достаточно проделать один раз при установке
Оптимизация трафика
Обновление opi файлов
Для обновления выполнить в директории с opi файлами:
git pull git submodule update
скрипт для обновления update
