Розганяємо CSS-селектори: id проти class, раунд другий
У першій статті циклу я вже розглядав швидкість роботи движка, відповідального за створення і відображення HTML-сторінки на екрані. Однак, зараз мова піде про дещо інше аспекті, ніж движок CSS-селекторів. Дана серія тестів була присвячена швидкості створення окремого HTML-документа.
Якщо в перших двох дослідженнях ставилося під сумнів швидкість розпізнавання браузером CSS-правил і їх застосування, то зараз цікавило інше питання, а саме: як швидко браузер створює DOM-дерево в залежності від наявності в ньому елементів з id або class?
Для цього було підготовлено 3 набору HTML-файлів. Перший містив 10000 елементів, у яких частина має id (кількість іменованих елементів варіювалося від 50 до 10000). У другому HTML-файли були, практично, ідентичними, тільки замість id мали атрибут class. У третьому наборі в DOM-дереві були тільки елементи з id (тобто варіювалося саме число елементів). Відповідно, всі вимірювання проводилися в прихованому iframe. щоб уникнути відтворення завантажених сторінок на екрані.
Для виміру часу створення сторінки застосовувалася та ж, що добре зарекомендувала себе, техніка, що і в попередніх тестах: бралася мітка часу до набору елементів і після цього набору, потім з останньої віднімалася перша. Підсумкові результати є середньозваженими за всіма браузерам.
Вплив на getElementById
Додатково для тих HTML-файлів, які містили ідентифікатори, запускалося обчислення getElementById ( 'id1') 10000 раз (щоб перевірити, наскільки кількість елементів або ідентифікаторів впливає на цю процедуру). Результати вийшли вельми цікаві, хоча і дуже передбачувані. Напевно, в наступних дослідження цей аспект роботи браузерів буде досліджений трохи докладніше.
Самі тести можна поганяти на webo.in/tests/css-efficiency-3/ або завантажити на зазначеній сторінці все одним архівом (разом з моїми результатами).
Всі 3 тестових набору (кожен містив по 6 файлів, в них було 50, 100, 500, 1000, 5000 і 10000 досліджуваних елементів) проганяли по 10 разів для 5 браузерів (Firefox2, IE6, IE7, Opera 9.5 (так-так, не стоїть у мене 9.27) і Safari 3). В результаті, статистичними методами похибка зводилася до цілком допустимого значення: 2-3%.
Відразу хочу обмовитися про невеликому сплеску для самого першого документа у всіх браузерів: швидше за все, при завантаженні документа в iframe браузер (це було характерно абсолютно для всіх) виділяє певну кількість пам'яті для нового HTML-документа в цьому iframe. яке потім якимось чином повторно використовує для нових документів. В результаті для документа з 50 ідентифікаторами на 10000 елементів результати виявилися дещо невірними.
Напевно, в майбутньому цей аспект варто врахувати і завантажувати порожній документ на самому початку або, що краще, завантажувати документ з максимальною кількістю об'єктів, щоб виділення пам'яті не впливало на подальші вимірювання. Однак, на якісні висновки дане відхилення ніяк не вплинуло.
результати
Напевно, найпростіше буде представити результати у вигляді графіків, що я, в принципі і зроблю. Пару слів про легенду: на ній зібрано 5 випадків. ID (create) відображає час створення HTML-документа з 10000 елементів (div), з яких тільки у 50. 10000 були ідентифікатори. class (create) відповідає часу створення такого ж документа, але з class замість id. ID (clean) характеризує час створення документа, в якому всі елементи мали ідентифікатори (але елементів всього було 50. 10000). Два графіка з 10000 get показують час на отримання елемента з конкретним ідентифікатором 10000 раз в першому і третьому документі, відповідно.
Малюнок 1. Швидкість створення документа і вибірки елемента для Firefox 2
Малюнок 2. Швидкість створення документа і вибірки елемента для IE 6
Малюнок 3. Швидкість створення документа і вибірки елемента для IE 7
Малюнок 4. Швидкість створення документа і вибірки елемента для Opera 9.5
Малюнок 5. Швидкість створення документа і вибірки елемента для Safari 3
Для Internet Explorer важко щось зрозуміти, бо час на обчислення елемента за ідентифікатором по порядку ненабагато менше часу створення документа, в результаті, воно «забиває» всі результати. Нижче наведені розділені графіки за середньозваженим значенням (природно, основну роль відіграє Internet Explorer).
Малюнок 6. Швидкість створення документа, середньозважена за всіма браузерам
Малюнок 7. Швидкість вибірки елемента, середньозважена за всіма браузерам
За графіком середньозважених значень добре видно, що, за інших рівних умов, створення документа з class обходиться меншою кров'ю, ніж з id (в загальному випадку, від 2 до 10% виграшу). Якщо взяти до уваги, що element.class -селектори відпрацьовують швидше, ніж #id на ті ж 10%, то загальний виграш при використанні в документі класів перед ідентифікаторами складе близько 15%. В абсолютному значенні ці цифри не такі великі: для Centrino Duo 1.7 виходить цифра приблизно в 0,0085мс на 1 ідентифікатор (в середньому, 3 CSS-правила і 1 вживання).
Однак (що й потрібно було довести, в загальному), значне навантаження становить саме створення DOM-дерева в документі (можна подивитися, як експоненціально зростає час для Opera, Firefox і Safari) і самого документа (постійне час в 60мс для IE, яке перевершує всі інші накладні витрати при створенні середнього документа). В цілому, ці операції йде від 70% всього часу (тобто найбільша економія досягається за рахунок мінімізації розміру дерева і кількість HTML-сторінок, що завантажуються, наприклад, на кадрі, в цій області планується провести додаткові дослідження).
На швидкість обчислення одного елементу за ідентифікатором, як не дивно, найбільший вплив робить знову-таки DOM-Дерево, ніж кількість таких елементів. Навіть при 1000 елементів з id більше половини тимчасових витрат можна урізати, якщо просто скоротити загальне число елементів (особливо добре це помітно для IE).
В цілому ж, основних порад поки два: зменшуйте DOM-дерево і використовуйте id тільки в разі дійсної необхідності.