Разрушители CSS, которые объединяют элементы, разрушительны? - PullRequest
7 голосов
/ 18 октября 2011

Я нашел этот минификатор CSS (http://www.lotterypost.com/css-compress.aspx). В нижней части этой страницы есть раздел, озаглавленный «Что CSS Compressor намеренно НЕ делает?». Есть четыре вещи, две из которых я не смог понятьпочему они могут быть разрушительными:

Объединение отдельных стилей полей, отступов или границ в одно свойство.

  margin-top: 10px; 
  margin-right: 0; 
  margin-bottom: 8px;
  margin-left: 30px;

Становится

  margin: 10px 0 8px 30px;

И объединение стилей дляодин и тот же элемент, который указан в разных блоках стиля.

#element {
   margin: 0;
}

#element {
   color: #000000;
}

становится

#element {
   margin: 0;
   color: #000000;
}

Я думаю, что CSSTidy выполняет оба этих действия. Является ли веб-страница выше верной? Существуют ли ситуации, когда эти типыминификации может быть проблемой?

Ответы [ 3 ]

8 голосов
/ 20 октября 2011

Я разработчик CSS Compressor, который является предметом этого вопроса (http://www.lotterypost.com/css-compress.aspx),), поэтому я приведу пример того, как компрессор может сломать каскад CSS, если инструмент агрессивно переписываетit.

Существует множество способов нацеливания на элементы в таблице стилей, и поскольку компрессор CSS не имеет глубоких знаний о структуре DOM страницы, классах, идентификаторах и т. д., для компрессора нет способа.чтобы знать, будет ли ломаться оптимизация, которая пересекает определения в скобках.

Например, простая структура HTML:

<div class="normal centered">
    <p>Hello world.</p>
</div>

И немного CSS:

div.normal p {
    margin: 10px 0 10px 0;
}

div.centered p {
    margin: 10px auto;
}

div.normal p {
    margin-bottom: 5px;
}

Несжатый код может создать центрированный абзац с верхним полем в 10px и нижним полем в 5px.

Если вы запустите стили CSS через CSS Compressor, вы получите следующий код:который поддерживает порядок и каскад исходных несжатых стилей.

div.normal p{margin:10px 0}div.centered p{margin:10px auto}div.normal p{margin-bottom:5px}

Допустим, вы хотите еще больше агрессивно сжимать стили, комбинируяполя двух div.normal p определений.Они оба имеют один и тот же селектор, и они, похоже, избыточно стилизуют нижнее поле.

Было бы два способа объединить поля: вы можете объединить два определения полей в первое (верхнее) div.normal p стиль или объединить их в последний (нижний).Давайте попробуем оба способа.

Если вы объедините поля в первый (верхний) div.normal p стиль, вы получите:

div.normal p{margin:10px 0 5px}div.centered p{margin:10px auto}

Результатобъединение полей таким способом привело бы к тому, что нижнее поле было бы неправильно установлено в 10px, потому что «центрированный» класс переопределил бы нижнее поле (потому что определение «центрированного» стиля теперь появляется позже в каскаде).

Если вы объедините поля в последний (нижний) стиль div.normal p , вы получите следующее:

div.centered p{margin:10px auto}div.normal p{margin:10px 0 5px}

В результате объединения полей таким образом, абзац №больше отображается как центрированный, потому что нижнее определение «p» переопределяет левые и правые поля «auto», определенные в «центрированном» классе.

Таким образом, мы можем увидеть это, комбинируя определения стилей, которые дажеодин и тот же селектор может вызвать довольно серьезные проблемы.

Вы бы лично когда-нибудь писали такой код?Может быть, а может и нет.Из-за различных «весовых» правил каскада можно попасть в ловушку кода такого типа, даже не осознавая этого.

Кроме того, учитывая тот факт, что на современных веб-страницах несколько CSS-файлов частоОбъединенный в один файл для загрузки на сервер с меньшим количеством загрузок, легко представить, что CSS Compressor по-королевски облажает каскад, переписывая несколько таблиц стилей (возможно, написанных разными людьми), которые объединяются в один файл.

На самом деле я написал CSS Compressor для этого сценария на моем веб-сайте, Lottery Post .Каждая веб-страница имеет множество таблиц стилей, поддерживающих различные jQuery и другие компоненты, а CSS Compressor используется для автоматического сжатия всех этих таблиц стилей в одну загрузку.На всех страницах сайта есть как минимум 10 различных таблиц стилей, объединенных вместе, и на большинстве страниц их больше.

Например, если вы посмотрите на код позади самой страницы CSS Compressor, вы найдете основныеТаблица стилей в голове, которая выглядит следующим образом:

<link rel="stylesheet" href="http://lp.vg/css/d11019.0/j2HKnp0oKDOVoos8SA3Bpy3UHd7cAuftiXRBTKCt95r9plCnvTtBMU2BY2PoOQDEUlKCgDn83h16Tv4jbcCeZ(gupKbOQ9ko(TcspLAluwgBqrAjEhOyXvkhqHA(h5WFDypZDK2TIr(xEXVZtX7UANdFp6n1xfnxqIMR8awqGE)vrwUgY2hrCGNNTt1xV7R1LtCSfF46qdH1YQr2iA38r1SQjAgHze(9" />

Gobbledeegook в URL - это фактически зашифрованная строка, содержащая все таблицы стилей для объединения на сервере.Сервер сжимает их и кэширует результат.

Методы экономии пространства и времени при вызове одной таблицы стилей включают:

  • Объединение множества таблиц стилей в один файл / загрузка с помощьюпросто добавив их все вместе
  • Сжатие комбинированной таблицы стилей с помощью CSS Compressor (без путаницы в каскаде!)
  • Использование другого доменного имени (lp.vg) для загрузки таблицы стилей, что улучшает возможности браузера загружать параллельно
  • Использование очень короткого доменного имени (lp.vg)
  • GZip-сжатие применяется к таблице стилей на веб-сервере
  • Номер версии таблицы стилей встраивается в URL ("... / d11019.0 / ..."), так что если любой стиль изменяется в любой из нескольких таблиц стилей, я могу изменить версию номер и браузер никогда не будет использовать версию, которую он кэшировал. (Обратите внимание, что номер версии должен быть частью пути URL, а не в строке запроса, поскольку некоторые прокси-серверы не смотрят на строку запроса, чтобы определить, должна ли страница быть извлечена из кэша.)

Надеюсь, это лучше объясняет вещи и помогает тем, кто хочет улучшить производительность страницы!

-Todd

ДОПОЛНИТЕЛЬНАЯ ИНФОРМАЦИЯ:

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

Вот несколько несжатых стилей:

div.normal p {
    margin: 10px 0 10px 0;
}

div.centered p {
    margin: 10px auto;
    color: blue;
}

div.normal p {
    color: black;
}

Компрессор CSS выдает следующий вывод:

div.normal p{margin:10px 0}div.centered p{margin:10px auto;color:blue}div.normal p{color:#000}

Если бы мы применили агрессивное объединение определений стилей с одинаковым селектором, мы получим следующий код.

Метод 1 , объединяющий оба в первом определении, неправильно сделал бы цвет текста синим:

div.normal p{margin:10px 0;color:#000}div.centered p{margin:10px auto;color:blue}

Метод 2 , объединяющий оба во второе определение, неправильно выровняет текст по левому краю:

div.centered p{margin:10px auto;color:blue}div.normal p{margin:10px 0;color:#000}

Единственное время, когда сочетания определений стилей с одним и тем же селектором на 100% безошибочны, - это когда определения появляются непосредственно одно за другим, но в любом другом случае этот метод может привести к повреждению каскада стилей.

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

Честно говоря, я был бы очень обеспокоен компрессором CSS, который комбинировал стили из разных блоков определения, потому что каскад - очень хрупкая вещь, и сломать каскад чрезвычайно легко.

2 голосов
/ 18 октября 2011

На странице есть раздел на тему «причина не используется», в которой описывается, почему она не выполняет эти две вещи .

И, вдобавок ко всему, я бы предположил, что он не пытается делать это, потому что он не является полным синтаксическим анализатором / интерпретатором CSS и начал бы создавать такие вещи, как условные блоки CSS.

0 голосов
/ 18 октября 2011

Под «деструктивным» я полагаю, вы имеете в виду «CSS работает не так, как ожидалось».

Комбинация правил длинной руки, таких как ваш первый пример, может быть выполнена без каких-либо побочных эффектов.

В простой старой таблице стилей без медиа-блоков или других причудливых вещей второй пример также не вызовет никаких проблем.

Причина № 2 в том, что изменение порядка правил или объединение правил без учета каскада может привести к поломкам.

Некоторые компрессоры CSS могут переупорядочивать правила по алфавиту или по типу селектора. Это очень рискованно, потому что перемещение правил может нарушить каскадное поведение, созданное автором.

Минификаторы, такие как компрессор YUI, не делают ничего из этого, выбирая более безопасные стратегии, такие как удаление пробелов, избыточных точек с запятой и нулей и т. П.

С большим количеством CSS, содержащих медиа-блоки и другой код CSS3, вполне вероятно, что многие из существующих компрессоров CSS не будут работать правильно вообще. Большинство из них не имеют правильного лексера для анализа кода - для обработки кода они используют контекстно-зависимые побайтовые (Tidy) или регулярные выражения (большинство остальных).

При выборе компрессора я бы предложил найти что-то, что будет делать это локально, и подкреплено хорошим набором тестов, чтобы вы могли видеть, какие случаи обрабатываются (и не обрабатываются) правильно.

...