07 Mar 2014
Часто встречаю в рекомендациях по оптимизации загрузки страниц такой совет:
Объединяйте файлы стилей, скриптов, картинок в один соответствующий файл, это поможет сократить количество запросов и этим ускорит загрузку ресурсов!
В наличии несколько файлов:
jquery.fancybox.js
jquery.tiptip.js
jquery.some.js
jquery.more.js
jquery.plgn.js
init.js
load.js
main.js
Некоторые из них меняются часто, другие каждый месяц. Размер у каждого примерно одинаков, изменяющиеся даже меньше среднего. Все они кешируются более, чем на год.
Объединяя эти файлы, вы обрекаете своих пользователей на ежемесячную загрузку этого большого комплекта скриптов. В то же время, держа их раздельно, позволяете скачивать только то, что изменилось.
Да, остаётся вариант с первым посещением. Действительно, впервые пришедшим на наш сайт посетителям придётся загружать все эти файлы параллельно, делая запросы, которые можно было бы потратить на изображения, например.
К счастью, этих файлов намного меньше, чем изображений, а потраченное время из-за большего количества запросов будет незначительным, по сравнению со временем загрузки часто меняющегося объединённого файла.
Я к тому, что универсальных способов оптимизации нет, всё индивидуально.
Не гадай, тестируй!
04 Mar 2014
Элементы интерфейса на страницах сайта редко бывают абстрактными, они связаны назначением в общих блоках и их объединениях. Внутри таких блоков формируется контекст.
Каждому элементу интерфейса необходим класс, обозначающий принадлежность к его контексту. При этом такой контекстный элемент должен наследовать все необходимые свойства абстрактных блоков, которые ему необходимы для выполнения своих функций.
Контекстные блоки — расширенные и обьединённые абстрактные, приправленные нужными только им стилями!
Например, нужно дать элементу Error__header
стили блока Header
с его модификаторами.
Как и в ситуации с глобальными модификаторами, такое расширение возможно несколькими способами в зависимости от технических возможностей:
html
<h4 class="Header Header--main Header--type-error Error__header"></h4>
Способ проблемен тем, что если понадобится изменить модификатор блока, придётся, помимо соответствующей правки стилей, изменять и классы блока везде, где он встречается в разметке.
Если нет возможности использовать шаблонизаторы, автоматически собирающие требуемую разметку из абстрактных блоков, можно воспользоваться препроцессором для реализации контекстных блоков из абстрактных в вёрстке.
Чтобы контекстный блок использовал стили абстрактного, можно объединять их классы в составных селекторах.
Вручную это делать сложно, так как часто контекстные и абстрактные блоки не находятся рядом в коде, приходилось бы упоминать блок во многих местах файла стилей.
Для того, чтобы упростить объединение селекторов, в препроцессорах есть функция @extend
, позволяющая указывать класс расширяющей сущности в блоке объявлений расширяемой.
```css .Header {…} .Header–main {…} .Header–type-error {…}
.Error__header { @extend .Header; @extend .Header–main; @extend .Header–type-error; } ```
что даёт в итоге нужное
css
.Header, .Error__header {...}
.Header--main, .Error__header {...}
.Header--type-error, .Error__header {...}
Проблема может возникнуть, если модификаторы связаны с друг другом. @extend
не добавит контекстный класс к .Header--main.Header--type-error
, если разработчик сам не напишет @extend .Header--main.Header--type-error
.
Для решения этой проблемы нужно будет написать функцию, которая будет делать то, что нам нужно:
```css .Header { font-weight: bold; &–main { font-family: ‘Segoe UI’, sans-serif; } &–type-error { color: red; } &–main&–type-error { font-size: 1.2em; } }
Header(mods) { @extend .Header; if (match(‘main’, mods)) { @extend .Header–main; } if (match(‘error’, mods)) { @extend .Header–type-error; } if (match(‘main’, mods) && match(‘error’, mods)) { @extend .Header–main.Header–type-error; } }
.Error__header { Header(‘main error’); } ```
Таким образом, появляется возможность расширения блока стилями абстрактного при помощи функции с нужными параметрами.