Pull to refresh

Анализ применения SVG в качестве background-image

Reading time2 min
Views47K

В последнее время все чаще появляются статьи, в которых авторы рекомендуют использовать SVG для backgroud-image. Действительно, применение SVG приносит большую пользу. Во всех прочитанных статьях очень вскользь упоминалось про производительность отрисовки SVG, что это более затратная операция, так как браузеру необходимо каждый раз заново отрисовывать растр.

И вот в один прекрасный день, открыв одно веб-приложение, я заметил, что мой браузер безумно «пожирает» память — одна вкладка «ела» около 600 МиБ. На МacBook с ретиной дела обстояли еще хуже. С этого момента началось расследование, куда же течет память. Кому интересно, добро пожаловать под кат.

Первым, на что я обратил внимание, был рост памяти при открытии одного попапа, в котором отрисовывались всего 20 элементов с иконками. Сделав профайлинг в chrome, я сделал вывод, что дело не в javaScript, не в CSS, и не в HTML.

Однако я заметил, что чем меньше присутствует элементов с иконками, тем меньше памяти расходуется. Посмотрев, откуда берутся иконки, я увидел, что они взяты из спрайта размером 2000px х 500px. После подмены SVG спрайта на PNG спрайт с такими же размерами, случилось чудо — использование памяти вернулось в разумные рамки. Порассуждав, легко прийти к выводу, что на каждую маленькую иконку отрисовывался большой битмап, на который и расходовалась память.
Первая мысль, которая пришла мне в голову — отказаться от SVG. Но взять и просто заменить на png нельзя, так как мы заботимся о пользователях, имеющих мониторы высокой четкости.
Прочитав спецификацию по SVG и большое количество различных статей (ссылки в конце статьи), я решил попробовать задавать размер SVG не в px, а в em. В итоге, как я и ожидал, с относительными единицами объем потребляемой памяти оказался приблизительно равным тому, как если бы использовался png-спрайт.

Ниже приведена таблица потребления памяти в chromium на моей машине при отрисовке 16 иконок:
SVG, размеры заданы в em 9 216k демо
SVG, размеры заданы в px 101 600k демо
PNG, малый размер холста 7 748к демо
PNG, большой размер холста 10 060k демо
Какие же выводы можно сделать? Возможны два варианта. Первый — использовать два спрайта PNG, в обычном и ретиновском качестве. Если же вы используете SVG-спрайты, задавайте размер в относительных единицах, например в em.
Список статей, которые рекомендую почитать на тему SVG:

coding.smashingmagazine.com/2012/01/16/resolution-independence-with-svg
habrahabr.ru/post/141654
www.broken-links.com/2012/08/14/better-svg-sprites-with-fragment-identifiers
www.w3.org/TR/SVG
smus.com/canvas-vs-svg-performance

UPD: И так, в ходе общих исследований было выяснено, что такое поведение присутствует в chromium-based браузерах. В браузерах firefox, opera, ie похожий эффект не наблюдается. В комментариях верно указано, что объем памяти зависит от размера холста, а не от единиц измерения. Но единицы измерения могут повлиять на маштабируемость SVG, так что выбирайте единицы под вашу задачу. Спасибо всем за замечания и проведенные тесты в других браузерах.
UPD: code.google.com/p/chromium/issues/detail?id=196524 добавлен баг в багтрекер.
UPD: Баг закрыт, исправлен в canary build.
Tags:
Hubs:
Total votes 47: ↑45 and ↓2+43
Comments29

Articles