Подтвердить что ты не робот

Какие селектор или правила CSS могут существенно повлиять на производительность интерфейса/рендеринга в реальном мире?

Стоит ли беспокоиться о производительности CSS-рендеринга? Или мы просто не будем беспокоиться об эффективности вообще с помощью CSS и просто сосредоточимся на написании элегантного или поддерживаемого CSS?

Этот вопрос предназначен для того, чтобы быть полезным ресурсом для разработчиков интерфейсов, на которых части CSS могут существенно влиять на производительность устройства и на какие устройства/браузеры или механизмы могут быть затронуты. Это не вопрос о том, как писать элегантный или поддерживаемый CSS, это чисто о производительности (хотя, надеюсь, написанное здесь может содержать более общие статьи о лучшей практике).

Существующие доказательства

Google и Mozilla написали рекомендации по написанию эффективных CSS и набор правил CSSLint включает в себя:

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

но ни один из них не дает каких-либо доказательств (которые я мог найти) о влиянии, которое они имеют.

A статья css-tricks.com об эффективном CSS утверждает (после изложения передовой практики эффективности), что мы должны not .. sacrifice semantics or maintainability for efficient CSS эти дни.

A совершенство убивает сообщение в блоге, предположил, что border-radius и box-shadow оказываются на порядок медленнее, чем более простые правила CSS. Это было очень важно в Opera, но в Webkit было незначительным. Кроме того, smashing magazine CSS benchmark обнаружил, что время рендеринга для правил отображения CSS3 было незначительным и значительно быстрее, чем рендеринг эквивалентного эффекта с использованием изображений.

Знай свой мобильный протестировавший различные мобильные браузеры и обнаружил, что все они отображали CSS3 одинаково незначительно быстро (в 12 мс), но похоже, что они сделали тесты на ПК, поэтому мы ничего не можем сказать о том, как ручные устройства работают с CSS3 в целом.

Здесь many статьи в Интернете о том, как писать эффективный CSS. Тем не менее, мне еще предстоит найти исчерпывающее доказательство того, что плохо рассматриваемый CSS фактически оказывает значительное влияние на время рендеринга или привязанность сайта.

Фон

отступить, я собираюсь попробовать науку http://brightgreenscotland.org/wp-content/uploads/2010/09/stand-back-Im-going-to-try-science.png

Я предложил щедрость для этого вопроса, чтобы попытаться использовать силу сообщества SO для создания полезного хорошо исследованного ресурса.

4b9b3361

Ответ 1

Первое, что приходит в голову здесь: насколько умным является механизм рендеринга, который вы используете?

Это, как правило, очень важно, когда вы спрашиваете эффективность рендеринга/выбора CSS. Например, предположим, что первое правило в вашем файле CSS:

.class1 {
    /*make elements with "class1" look fancy*/
}

Итак, когда очень простой движок видит это (и поскольку это первое правило), он идет и смотрит на каждый элемент вашего DOM и проверяет существование class1 в каждом. Лучшие двигатели, вероятно, сопоставляют имена классов с списком элементов DOM и используют что-то вроде хеш-таблицы для эффективного поиска.

.class1.class2 {
    /*make elements with both "class1" and "class2" look extra fancy*/
}

Наш пример "базовый движок" пойдет и пересматривает каждый элемент в DOM, ища оба класса. Более умный движок будет сравнивать n('class1') и n('class2'), где n(str) - количество элементов в DOM с классом str, и берется в зависимости от того, что минимально; предположим, что class1, затем передает все элементы с class1, ища элементы с class2.

В любом случае современные двигатели являются умными (более умными, чем описанный выше пример), а блестящие новые процессоры могут выполнять миллионы (десятки миллионов) операций в секунду. Весьма маловероятно, что у вас есть миллионы элементов в вашей DOM, поэтому наихудшая производительность для любого выбора (O(n)) будет не так уж плоха.


Обновление:

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

Facebook: ~ 1900 элементов (проверено на моей личной главной странице).
Google: ~ 340 элементов (проверено на главной странице, нет результатов поиска).
Google: ~ 950 элементов (проверено на странице результатов поиска).
Yahoo!: ~ 1400 элементов (проверено на главной странице).
Stackoverflow: ~ 680 элементов (проверено на странице вопроса).
AOL: ~ 1060 элементов (проверено на главной странице).
Википедия: ~ 6000 элементов, из которых 2420 не являются spans или anchors (проверено в статье Википедии о Glee).
Twitter: ~ 270 элементов (проверено на главной странице).

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


Тесты

Стили и элементы создаются с помощью PHP. Я загрузил PHP файлы, которые я использовал, и создал индекс, чтобы другие могли тестировать локально: небольшая ссылка.


Результаты:

Каждый тест выполняется 5 раз в трех браузерах (сообщается среднее время): Firefox 15.0 (A), Chrome 19.0.1084.1 (B), Internet Explorer 8 (C):

                                                                        A      B      C
1500 class selectors (.classname)                                      35ms   100ms  35ms
1500 class selectors, more specific (div.classname)                    36ms   110ms  37ms
1500 class selectors, even more specific (div div.classname)           40ms   115ms  40ms
1500 id selectors (#id)                                                35ms   99ms   35ms
1500 id selectors, more specific (div#id)                              35ms   105ms  38ms
1500 id selectors, even more specific (div div#id)                     40ms   110ms  39ms
1500 class selectors, with attribute (.class[title="ttl"])             45ms   400ms  2000ms
1500 class selectors, more complex attribute (.class[title~="ttl"])    45ms   1050ms 2200ms

Аналогичные эксперименты:

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


Нижняя строка:

Если вы не заботитесь о сохранении нескольких миллисекунд при рендеринге (1 мс = 0,001 с), не беспокойтесь, чтобы это слишком много думал. С другой стороны, хорошая практика - избегать использования сложных селекторов для выбора больших подмножеств элементов, поскольку это может иметь заметную разницу (как мы можем видеть из результатов теста выше). Все распространенные селектор CSS достаточно быстр в современных браузерах.

Предположим, вы создаете страницу чата, и вы хотите стилизовать все сообщения. Вы знаете, что каждое сообщение находится в div, который имеет title и вложен в div с классом .chatpage. правильно использовать .chatpage div[title] для выбора сообщений, но это также плохой практикой. Это проще, удобнее обслуживать и более эффективно давать всем сообщениям класс и выбирать их с помощью этого класса.


Выдающийся однострочный вывод:

Что-нибудь в рамках "да, этот CSS имеет смысл", все в порядке.

Ответ 2

Большинство ответов здесь сосредоточены на производительности селектора, как будто это единственное, что имеет значение. Я попытаюсь прикрыть некоторые мелочи (spoiler alert: они не всегда являются хорошей идеей), css использует ценность и рендеринг определенных свойств.

Прежде чем я получу ответ, позвольте мне отвлечь ИМО: лично я категорически не согласен с заявленной необходимостью "данных, основанных на доказательствах". Это просто делает утверждение о производительности показателем надежности, в то время как на самом деле область движков рендеринга достаточно гетерогенна, чтобы сделать такое статистическое заключение неточным для измерения и нецелесообразности принятия или мониторинга.

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


Начните с производительности селектора:

Мелкие, предпочтительно одноуровневые специфические селекторы обрабатываются быстрее. Явные показатели производительности отсутствуют в исходном ответе, но ключевой момент остается: во время выполнения HTML-документ анализируется в дереве DOM, содержащем элементы N со средней глубиной D и чем имеет общее количество правил CSS S. Чтобы снизить вычислительную сложность O(N*D*S), вы должны

  • Использовать правильные клавиши как можно меньше элементов - селектора соответствуют справа налево ^ для индивидуальное правило, поэтому, если самый правый ключ не соответствует определенному элементу, нет необходимости дополнительно обрабатывать селектор и он отбрасывается.

    Общепринято, что следует избегать селектора *, но этот пункт следует принять дальше. "Обычный" CSS reset действительно совпадает с большинством элементов - когда эта страница SO профилируется, reset отвечает за около 1/3 от времени выбора селектора, поэтому вы можете предпочесть normalize.css (все же это добавляет до 3,5 мс - точка против преждевременной оптимизации стоит сильная)

  • Избегайте селекторов-потомков, поскольку они требуют до ~D элементов, которые нужно повторить. Это в основном влияет на подтверждения несоответствия - например, положительное соответствие .container .content может потребовать только один шаг для элементов в отношениях между родителями и дочерними элементами, но дерево DOM нужно пройти до уровня html до того, как отрицательное совпадение может быть подтвержденным.

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

  • Удалить неиспользуемые правила, поскольку браузеру приходится оценивать их применимость для каждого отображаемого элемента, Достаточно сказано - самым быстрым правилом является тот, которого нет:)

Это приведет к количественному (но, в зависимости от страницы, не обязательно воспринимаемому) улучшению с точки зрения производительности движка рендеринга, однако всегда есть дополнительные факторы, такие как накладные расходы трафика и разбор DOM и т.д.


Далее, производительность свойств CSS3:

CSS3 принес нам (помимо прочего) закругленные углы, фоновые градиенты и вариации тени, а вместе с ними и проблему с грузом. Подумайте об этом, по определению предварительно обработанное изображение работает лучше, чем набор правил CSS3, который должен быть отображен первым. Из webkit wiki:

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

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


Далее, списание производительности:

Избегайте высоких и широких спрайтов, даже если их транспортный след относительно невелик. Общеизвестно, что механизм рендеринга не может работать с gif/jpg/png, и во время выполнения все графические активы управляются как несжатые растровые изображения. По крайней мере, легко вычислить: this sprite ширина раз высота раз четыре байта на пиксель (RGBA) 238*1073*4≅1MB. Используйте его на нескольких элементах на разных одновременно открытых вкладках, и это быстро добавляет значительную ценность.

Довольно экстремальный случай: был найден на mozilla webdev, но это совсем не неожиданно, когда сомнительные практики, такие как диагональные спрайты.

Альтернативой рассмотрению являются отдельные изображения с кодировкой base64, встроенные непосредственно в CSS.


Далее, переплачивает и реконструирует:

Это неправильное представление о том, что reflow может быть запущен только с помощью JS DOM-манипуляции - на самом деле любое приложение макетирования стиль приведет к его воздействию на целевой элемент, его дочерние элементы и последующие элементы и т.д. Единственный способ предотвратить ненужные итерации - попытаться и избежать зависимостей рендеринга. Прямым примером этого может быть таблицы рендеринга:

Таблицы часто требуют нескольких проходов до того, как макет полностью установлен, потому что они являются одним из редких случаев, когда элементы могут влияют на отображение других элементов, которые были перед ними на DOM. Представьте ячейку в конце таблицы с очень широким контентом, который вызывает полное изменение столбца. Вот почему таблицы не постепенно продвигается во всех браузерах.


Я сделаю изменения, если вспомню что-то важное, что было пропущено. Некоторые ссылки для завершения:

http://perfectionkills.com/profiling-css-for-fun-and-profit-optimization-notes/

http://jacwright.com/476/runtime-performance-with-css3-vs-images/

https://developers.google.com/speed/docs/best-practices/payload

https://trac.webkit.org/wiki/QtWebKitGraphics

https://blog.mozilla.org/webdev/2009/06/22/use-sprites-wisely/

http://dev.opera.com/articles/view/efficient-javascript/

Ответ 3

Хотя верно, что

компьютеры были медленнее 10 лет назад.

У вас также есть гораздо более широкий спектр устройств, которые в настоящее время могут получить доступ к вашему сайту. И хотя рабочие столы/ноутбуки появились в прыжках, устройства на рынке смартфонов среднего и низкого уровня во многих случаях не намного мощнее, чем то, что у нас было на десктопах десять лет назад.

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

Расширившись, я не смог найти конкретную информацию, касающуюся более современных браузеров или мобильных устройств, борющихся с неэффективными селекторами CSS, но я смог найти следующее:

  • http://www.stevesouders.com/blog/2009/03/10/performance-impact-of-css-selectors/

    Удовлетворительно (IE8, Chrome 2) теперь, но имеет приличную попытку установить эффективность различных селекторов в некоторых браузерах, а также пытается определить, как количество CSS-правил влияет на время рендеринга страницы.

  • http://www.thebrightlines.com/2010/07/28/css-performance-who-cares/

    Снова довольно устаревший (IE8, Chrome 6), но доходит до крайности в неэффективных селекторах CSS * * * * * * * * * { background: #ff1; }, чтобы установить ухудшение производительности.

Ответ 4

Для такой большой щедрости я готов рискнуть ответом Null: нет официальных селекторов CSS, которые вызывают заметные замедления рендеринга и (в этот день быстрых компьютеров и быстрой итерации браузера) любые, которые найденные быстро решаются разработчиками браузеров. Даже в мобильных браузерах нет проблем, если только неосторожный разработчик не захочет использовать нестандартные селектора jQuery. Эти разработчики jQuery помечаются как опасные и могут быть проблематичными.

В этом случае отсутствие доказательств свидетельствует о недостатке проблем. Итак, используйте семантическую разметку (особенно OOCSS) и сообщайте о любых замедлениях, которые вы обнаружите при использовании стандартных селекторов CSS в неясных браузерах.

Люди из будущего: проблемы с производительностью CSS в 2012 году были уже ушли в прошлое.

Ответ 5

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

Как я прокомментировал использование pagepeed для chrome своего инструмента Google, который анализирует веб-сайт в 27 параметрах, css является одним из них.

Мое сообщение касается только того, что не будет иметь около 99% веб-пользователей, которые смогут открыть веб-сайт и увидеть его правильно, даже люди с IE7 и т.д. Затем, закрыв 10%, используя css3, (если окажется, что вы можете получить дополнительные 1-10 мс на производительность).

Большинство людей имеют по крайней мере 1mbit/512kbit или выше, и если вы загружаете тяжелый сайт, для загрузки требуется около 3 секунд, но вы можете сэкономить 10 мс, возможно, на css??

И когда речь идет о мобильных устройствах, вы должны создавать сайты только для мобильных телефонов, поэтому, когда у вас есть устройство с размером экрана меньше, чем "Ширина", у вас есть отдельный сайт

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

Ответ 6

Не связавшись напрямую с кодом, использование <link> over @import для включения ваших таблиц стилей обеспечивает гораздо более высокую производительность.

'Не использовать @import' через stevesouders.com

В статье содержатся многочисленные примеры тестов скорости между каждым типом, а также один тип с другим (например: файл CSS, называемый через <link>, также содержит @import в другой файл css).