Не используйте SVG на своих сайтах
Привет, Хабр!
Сегодня я хотел бы рассказать Вам про серьёзную проблему, возникающую при использовании SVG на сайтах, а также о том как её избежать (неожиданно, но просто не используйте SVG), и почему использование SVG для ускорения загрузки сайта и решения проблемы потери качества при масштабировании JPEG/PNG картинок — далеко не всегда хорошая идея.
Меня зовут Айшат Нуржанов, я frontend‑разработчик, мечтающий о разработке игр, беспечной жизни и покое в богатстве. У меня есть Telegram‑канал, где я делаю посты про веб, свою жизнь и (в основном) мемы.
Неожиданная проблема на production
Я решил написать эту статью, так как я уже во второй раз сталкиваюсь с этой проблемой. Но я, пожалуй, расскажу именно про первый случай.
Как‑то раз я занимался редизайном главной страницы нашего продукта. Наши дизайнеры решили не сдерживаться и напихали в новый дизайн все возможные анимации и эффекты, которые только существуют. Я не стал реализовывать все эти эффекты и анимации, так как было решено оставить это на потом, потому что это было достаточно сложно, учитывая текущую на тот момент архитектуру, да и не сильно нужно было. Мне нужно было всего лишь местами переделать стили и поставить красивый градиентный фон почти на всю страницу.
Я быстренько все сделал, убедился, что все корректно отображается как на десктопе, так и на мобильных устройствах и запушил изменения в dev. На dev‑стенде тоже все проверили, после чего новый дизайн благополучно отправился на production.
Примерно через час, а то и меньше в тех. поддержку начали стучаться люди с жалобами на... производительность. У них при открытии главной страницы жутко проседал FPS.
Всем из нашей команды разработки это показалось довольно странно, потому что, во‑первых, как минимум у меня не было никаких просадок по FPS, во‑вторых, на главной странице не было никакой сложной логики, которая могла бы повлечь за собой проблемы с производительностью. На главной странице отображались недавние презентации пользователя, несколько кнопок создания новой презентации и сайдбар. Но все это было реализовано ещё до редизайна, поменялись лишь только стили: скругления, цвета, размеры, шрифты, отступы, layout. И красивый градиентный фон почти на всю страницу.
В попытках разобраться в чем же все‑таки проблема, я заметил, что просадка по FPS происходит только у тех пользователей, у которых 2k/4k экран. У меня самого на тот момент был экран с разрешением 1440:900.
Как вы могли уже догадаться, проблема была в том самом красивом градиентном фоне, а точнее в том, что он был в SVG формате. Пришел я к этой мысли совершенно случайно путем перебора всех возможных гипотез, одной из которых являлась гипотеза, связанная с удалением этого фона. И о чудо, у моего друга с 4k экраном сайт работал без просадок. Тут я решил заменить SVG формат на PNG, и все также было хорошо.
На самом деле я пришел к этой мысли, отталкиваясь от того факта, что сайт начинал тормозить именно больших экранах. Я сразу вспомнил про тот факт, что чем больше разрешение, тем больше нагрузка на видеоадаптер. И про тот факт, что SVG — это математическое представление изображения на основе XML. В таком формате изображение строится из геометрических примитивов: точек, линий, прямоугольников и окружностей. А теперь просто представьте, сколько понадобится таких геометрических примитивов, чтобы отобразить сложный градиент. Это будет намного сложнее, чем отобразить растровое изображение. Поэтому все и тормозило.
Какой вывод можно сделать?
А такой, что SVG идеально подходит для иконок, логотипов, инфографики, в общем чего‑то простого. Но никак не для сложных изображений. Согласен с тем, что заголовок немного кликбейтный, однако далеко не каждый сможет придти к вышеуказанному выводу. Например, мой коллега senior, который убеждал меня и всю команду разработки, что проблема не в SVG, а в «слепых пятнах» моего кода.
Он также говорил мне, что замена фона на растровое изображение повлечет за собой следующие проблемы:
Сайт будет долго грузится из‑за большого размера JPEG/PNG форматов
Растровые изображения теряют качество при масштабировании
Это все правда, однако стоит понимать, что эти проблемы можно и нужно решать другими способами, помимо замены на SVG формат. Идеальным решением здесь будет использование тега <picture> с помощью, которого можно грузить разные версии изображений под разные версии устройств. Хотя на сколько я знаю, в новой версии тега <img> тоже есть такой функционал, реализованный в виде атрибутов srcset и sizes. Более подробно про эти возможности написано в этой статье.
А ещё существует .webp формат, созданный специально для браузеров. А ещё можно поставить loading="lazy" в теге <img>. А ещё, если Вы делаете SPA‑приложение, то его можно грузить не целиком, а разбивать на чанки. Ну и так далее.
По итогу проблему решили вышеуказанным способом, а поиск «слепых пятен» в коде оставили на рефакторинг.
Картинки того самого красивого сложного градиентного фона не приложу, так как потерялась, да и на проекте случился очередной редизайн, вследствие которого, от этого фона вообще отказались по эстетическим причинам.
На этом все! Спасибо Всем, кто прочитал до конца. Это моя дебютная статья, поэтому я буду рад любой критике, а ещё больше буду рад, если кто‑то проголосует за нее в песочнице, после чего я стану полноправным членом (ха‑ха) сообщества Хабр. Ещё раз напомню про свой Telegram‑канал про веб‑разработку, жизнь и мемы, и Всем до новых встреч!