В последнее время все чаще появляются статьи, в которых авторы рекомендуют использовать 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 | демо |
Список статей, которые рекомендую почитать на тему 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.