22 декабря 2015
28 мая 2010
40
Оптимизация CSS для ускорения обработки браузерами
Всем привет.
Сегодня хочу поговорить о том, как браузеры обрабатывают правила CSS и как писать эти самые правила так, чтобы страница рендерилась быстрее.
Наверное, самый яркий пример тормозов, которые может вызвать CSS, это когда страница «дергается» при прокрутке в Ослике — это обычно связано с использованием :hover не у элементов <a>.
Итак, в связи с всеобщей тягой к ускорению веба, многие монстры интернета начали писать статьи и притворять в жизнь описываемые приемы. У Гугла есть статья про оптимизацию рендеринга в браузерах, у Мозиллы — про написание эффективного CSS. Я же хочу сделать «выжимку» из них ;-)
Как браузер обрабатывает стили
Ключевой момент — браузер читает правила справа налево. Мы же с вами пишем их слева на право. Чтобы почувствовать разницу, рассмотрим простой пример:
#global-wrapper ul.companies li a span { ... }
Браузер делаем следующее: сначала он находит все элементы <span>, затем берет те из них, что содержатся внутри <a>, потом внутри <li> и так далее. Соответственно, процесс обработки такого правила довольно долгий.
Основные типы селекторов и их эффективность
Существует четыре основных типа селекторов, на которых основаны все остальные. Ниже они представлены в порядке уменьшения их эффективности с точки зрения скорости обработки:
#global-wrapper { ... } /* по id элемента — самый эффективный */
.partners { ... } /* по классу */
ul { ... } /* по тегу */
*, [rel=external] { ... } /* универсальный — самый медленный */
Как видите, любые другие правила можно составить на основе этих четырех. Принимая во внимание способ обработки стилей браузером и эффективность основных типов легко понять принцип ускорения.
Советы по написанию селекторов
Избегайте универсальных селекторов
Делайте так, чтобы элементы наследовали стили от родителей или используйте классы для применения стилей к разным элементам.
Избегайте лишних селекторов
Не используйте без нужды теги при селекторе по id или классу:
div#global-wrapper { ... } /* Плохо */
#global-wrapper { ... } /* Хорошо */
... li.categories { ... } /* Плохо */
.categories { ... } /* Хорошо */
Излишняя вложенность селекторов так же нежелательна:
#company-profile ul li { ... } /* Плохо (ul лишний, так как li может содержаться только внутри ul) */
#company-profile li { ... } /* Хорошо */
Используйте class и id — самые быстрые селекторы
По возможности старайтесь использовать в ваших правилах селекторы по id или классам — они самые эффективные.
Используйте :hover только для ссылок в IE7 и IE8
Если вам нужно указать поведение элемента при наведении, используйте JavaScript.
Не используйте expression
Экспрешены работают только в IE 5-7, но при этом замедляют рендеринг страниц. Вместо них можно использовать JavaScript.
Дополнительные материалы
Рекомендую ознакомиться с оригинальными статьями от Гугла и Мозиллы:
- Optimize browser rendering (Google);
- Writing Efficient CSS for use in the Mozilla UI (Mozilla).
Еще есть небольшая заметка от Яндекса по поводу верстки новой страницы результатов поиска. Метод основан на указанных выше статьях.
Самый простой способ обойти этот баг - это использовать библиотеку Дэна Эдвардса IE7.
"Internet Explorer 7 and later, in standards-compliant mode (strict !DOCTYPE), can apply the :hover pseudo-class to any element, not merely links."
Там была еще ссылка на источник из MSDN, но нерабочая. Как и основная часть ссылок на MSDN.
Откуда эта информация? Просто предположение? Думаю там алгоритмы поиска по ДОМ не такие уж и тупые как может показаться.
Конечно я согласен с тем, что длинные селекторы обрабатываются медленнее, но зачем же так заморачиваться?
Вот если бы речь была о селекторах jQuery - это было бы куда актуальнее!
По-моему полная глупость!
Ну не может JS работать быстрее заточенных как раз под конкретные нужды вещей и еще скомпилированных в битовый код. Это вы про какие-то конкретные браузеры говорите?
Люди! Не пользуйтесь затычками, от них проблем всегда больше чем пользы! Используйте вещи по прямому назначению! Если они и в правду где-то работают медленнее, то это временные баги и они будут исправляться и ускорятся!
>> Откуда эта информация? Просто предположение?
пруф
>> По-моему полная глупость!
А по моему нужно отделять "поведение" от "отображения"
Ну и пусть старые IE не поймут :hover для произвольных элементов, не так уж страшно. Нужно проектировать сайт так, чтобы даже при отсутствии некоторых способностей браузера сайт оставался доступным и приятным, пусть и без некоторых полезных фишечек.
А навешивать JS на каждый пук - изврат.
ну что за бред-то? ol идёт лесом, что ли? всегда указываю, для элемента какого именно списка пишу стиль.
>>> li может содержаться только внутри ul
>>ну что за бред-то? ol идёт лесом, что ли? всегда указываю, для элемента какого именно списка пишу стиль.
Наверное имелось ввиду, что необязательно упопенять ul. :)
Ну то-есть если ol, то не писать ul ol, а стразу ol. Хотя тожешь.. это рекомендации Мозинны. Возможно в других каких-то бразузерах это будет не так.. фиг его занет.
В принципе статья хорошая, но нужно читать с умом, а не тупо следовать инструкциям.
>>>> По-моему полная глупость!
>>А по моему нужно отделять "поведение" от "отображения"
Извините, но я не чувствую разницы.. Объясните пожалуйста зачем мне навешивать js-есные события на элементы, там где я могу обойтись обычным hover?
Что-то я завтыкал... :)
http://www.w3schools.com/tags/tag_ol.asp
Что если пользователь отключил javascript (многие так делают для избежания тупых рекламных скриптов). Тогда все ваши hover пойдут лесом...
К тому же - javascript будет замедлять работу браузера несопоставимо больше с плохо работающими этими стилями в ИЕ.
>> ну что за бред-то? ol идёт лесом, что ли? всегда указываю, для элемента какого именно списка пишу стиль.
+1 - li может содержатся как внутри ul, так и внутри ol
ИМХО - выжимка получилась очень скудной.
все написал понятно)
А если оптимизировать и то и другое то работать будет еще быстрее. Не так ли?
>>Ну не может JS работать быстрее заточенных как раз под конкретные нужды вещей и еще скомпилированных в битовый код.
Представьте себе может =) Не знаю слышали вы или нет, но кое какие люди написали флеш плеер на javascript и вот у меня он работает быстрее чем скомпилированный адобовский)))) Хоть я и понимаю всю абсурдность сего факта, но это так. Вот кстати линк: http://www.linux.org.ru/news/opensource/4980402
Вообще-то в данном контексте решь ишла о встрояных возможностях самого браузера, а не о флеш-плеере.
И вообще, там реализована только возможность проигрования видео, то-есть это оч оч громно сказано по поводу флеш-плеера. Темболее можно начинать широко использовать как альтернативу флешу - HTML5 и тег Видео, темболее в линукса, где нету ИЕ! Это будет работать точно лучше чем самоточеные затычки...
Еще было бы интересно протестить этого зверя на винде. Просто в линуктсе часто вечно какие-то глюки лезул с флеш-плеером, и реализации под линукс вечно какие-то недоконца выленаные.
Оптимизировать безусловно нужно, но не ценой удобства и отказа от прямого предназначения готового функционала (это я о сложных селекторах). И не заменой стандартного функционала затычками. Тем более, как сказал Zen Similia, что этой оптимизации даже никто не заметит.
Можно же с нуля написать свой браузер на ассемблере конкретно заточенный под некий сайт. И даже можно добиться, что он будет работать быстрее чем все остальные. Но кому это надо?