Використання користувацьких шрифтів із SVG у тегу зображення

Дізнайтеся про розвиток на Frontend Masters

css-фокуси

Коли ми створюємо зображення у форматі PNG, ми використовуємо тег або фон CSS, і все про це. Це по-справжньому просто і гарантовано працює.

PNG набагато простіший у використанні в HTML, ніж SVG

На жаль, цього не можна сказати про SVG, незважаючи на багато переваг. Хоча ви зіпсовані для вибору при використанні SVG в HTML, це справді зводиться до вбудованого, і все з серйозними зачіпами та компромісами.

Проблеми з вбудованим SVG

Якщо ви вбудовуєте SVG, ви втрачаєте можливість використовувати кеш браузера, стиснення Gzip між серверами та браузерами та індексацію зображень у пошуковій системі (вбудований SVG не розглядається як зображення). Незважаючи на те, що ваше зображення може не змінитися ні на біт, воно завжди перезавантажується, і це спричиняє повільніший час завантаження вашого веб-сайту, компроміс, який більшість не готові терпіти.

Крім того, вбудовування SVG також спричиняє складні проблеми залежності, коли ви не можете легко вставити зображення в HTML і доводиться вдаватися до сценаріїв (PHP чи іншим чином). Коли у вас більше кількох зображень, це стає величезною проблемою, коли справа доходить до обслуговування вашого сайту, оскільки по суті ви більше не можете використовувати тег.

Без сумніву, є області, де вбудований SVG сяє - тобто, якщо ви хочете, щоб ваші зображення відображалися швидко, не чекаючи завантаження інших ресурсів. Окрім цього, очевидно, ви просто не можете все вбудувати.

Проблеми з тегом об’єкта

SVG добре відомий своєю чудовою якістю при відображенні на пристроях будь-якої роздільної здатності та здатністю посилатися на зовнішні ресурси, такі як CSS та шрифти, зберігаючи при цьому дуже малий розмір файлу. Ідея полягає в тому, щоб мати безліч SVG-файлів, які мають спільний CSS або один файл шрифту, щоб зменшити кількість ресурсів, які потрібно завантажити.

Міф про розподіл ресурсів

Невідомо багатьом, спільне використання зовнішніх ресурсів для SVG стосується лише вбудованого SVG. Оскільки використання тегів надає доступ до цих ресурсів, існує думка, що браузер завантажить одну копію вашого CSS, навіть якщо у вас багато тегів, що посилаються на один і той же файл CSS.

Однак це зовсім не так:

Кілька тегів об’єктів завантажать кілька CSS

Проблему ускладнює той факт, що теги не розпізнаються як зображення, і тому індексація пошуку зображень неможлива.

Надалі ускладнюють проблему проблеми залежності. Наприклад, скажімо, у вас є 100 зображень, і 25 з них використовують шрифт Roboto, ще 25 використовують Lato, 25 використовують Open Sans, тоді як решта використовують комбінацію трьох шрифтів. Ваш CSS повинен посилатися на всі три шрифти, тому що відстежити, який файл використовує які шрифти, абсолютно неможливо, тобто ви можете завантажувати шрифти, які вам не потрібні, на певних сторінках.

Це залишає нас із тегом, який багато чого вимагає. Оскільки це той самий тег, що використовується для інших форматів зображень, ви отримуєте знайомство, кешування браузера, стиснення Gzip та пошук зображень. Кожне зображення є автономним, без проблем залежності.

SVG втрачає шрифти, якщо використовується з тегом

Єдина проблема ви втратите шрифти. Якщо бути точнішим, якщо у вас є який-небудь текст у SVG, якщо ви не вбудуєте шрифти, ваш текст відображатиметься із системними шрифтами, як правило, Times New Roman. Ви витратили години, вибираючи гарний шрифт, але в той момент, коли ви використовуєте тег для вбудування SVG, все це втрачається. Як це може бути прийнятним?

Дослідження растеризації шрифтів

Наша перша реакція - перевірити, чи зможемо ми виконати растеризацію шрифтів. Це загальновживаний прийом для перетворення шрифтів у контури, тому він добре відображатиметься на всіх пристроях і підтримуватиме нульові залежності. На перший погляд, це працює дуже добре, а в редакторі все виглядає ідеально.

Хоча растризований SVG потрапив колосально 137 КБ у порівнянні з 15,7 КБ до растеризації ми були оптимістичними, оскільки після оптимізації нашого SVG із використанням стиснення Gzip, растризований файл зменшується до 11 КБ, трохи менше еквівалентного PNG у 11,9 КБ.

Оригінальна растеризація шрифтів Растеризація шрифтів (.svgz)
15,7 КБ 137 КБ 11,0 КБ
PNG @ 1x PNG @ 2x PNG @ 3x
11,9 КБ 26,5 КБ 42,6 КБ
Зображення SVG із растеризацією шрифтів

На жаль, як тільки ми вбудували растровий SVG в HTML, наш оптимізм виявився передчасним. Хоча це може чудово виглядати на дисплеях із високою роздільною здатністю, якість на дисплеях з низькою роздільною здатністю є неприйнятною.

Растрові шрифти зверху та оригінальні знизу

Внизу зображення - оригінал, з чітко відображеними шрифтами, тоді як зверху шрифти пікселізовані з використанням растеризації шрифтів.

Різниця між чіткими типами, коли вона відображається на екранах

Що відбувається, так це те, що більшість операційних систем оптимізують шрифти, щоб забезпечити їх чітке та чітке відображення на всіх екранах. У Windows це називається ClearType, і оскільки ми растеризували шрифти, оптимізація застосовуватись не буде, що призведе до розмитості тексту, особливо видимого на екранах з низькою роздільною здатністю.

Очевидно, що зниження якості неприпустимо, тому повернімось до креслення.

Вбудовування шрифтів на допомогу

Спочатку ми були надзвичайно скептично налаштовані на вбудовування шрифтів, головним чином через складний робочий процес.

Щоб вставляти шрифти у SVG, спочатку потрібно знати, які сімейства шрифтів використовуються. Потім вам потрібно знайти ці шрифтові файли та завантажити їх. Після завантаження вам доведеться перетворити звичайне, напівжирне, курсив та жирний курсив у кодування Base64. Якщо ви робите це вручну, через велику кількість файлів неможливо дізнатися, який файл використовує жирний шрифт, а який ні. Потім вам потрібно скопіювати всі чотири кодовані рядки Base64 у ваш SVG.

Звичайно, повинен бути кращий спосіб. Ось чому ми створили Nano. Nano автоматично сканує SVG та вставляє лише ті шрифти, які використовуються. Наприклад, якщо жирний шрифт не використовується або якщо текст не існує, тоді шрифти не будуть вбудовані.

Тим не менше, отриманий файл величезний і не конкурентоспроможний еквіваленту PNG, тому ми підключилися до мережі та створили власний оптимізатор SVG (Nano), який зменшить розмір файлів SVG до цівки. (Подивіться, як Nano стискає SVG.) Крім того, ми також оптимізували спосіб вбудовування шрифтів у SVG, що призвело до дуже малих розмірів файлів.

Зображення SVG з текстом, оптимізоване за допомогою Nano та вбудованих шрифтів

Порівняння розмірів файлів та економії пропускної здатності

Оригінальна растеризація шрифтів Неоптимізоване вбудовування шрифтів Вбудовування шрифтів Nano
Розмір 15,7 КБ 137 КБ 65,2 КБ 22,0 КБ
Gzip 3,57 КБ 11,0 КБ 44,5 КБ 11,7 КБ
PNG @ 1x PNG @ 2x PNG @ 3x
Розмір 11,9 КБ 26,5 КБ 42,6 КБ
Gzip 12,1 КБ 26,1 КБ 41,7 КБ

З вищевикладеного ми бачимо, що Nano виробляє надзвичайно легкий SVG навіть із вбудованими шрифтами, що надходить у 11,7 КБ (Gzipped) порівняно з еквівалентним PNG @ 1x at 11,9 КБ. Хоча це може здатися незначним, загальна пропускна здатність, збережена на вашому сайті, безумовно, буде значною.

Припустимо, що 50% вашого трафіку має низьку роздільну здатність, 40% - це роздільна здатність 2X, а решта 10% - роздільна здатність 3X. Якщо ваш веб-сайт має 10000 переглядів на одному зображенні:

(5000 * 11,9 КБ) + (4000 * 26,5 КБ) + (1000 * 42,6 КБ) = 208,1 МБ

Якщо ви використовуєте Nano, стиснений SVG із GZip:

10 000 * 11,7 КБ = 117,0 МБ

Це призведе до: 208,1 МБ - 117,0 МБ = 91,1 МБ економії, або 43,7%, економії пропускної здатності, значної суми за будь-яким показником.

На додаток до економії пропускної здатності, ви отримуєте набагато простіший робочий процес, не вдаючись до кількох зображень PNG із декількома srcset, набагато кращої якості, включаючи покращення шрифтів операційної системи, щоб ваші зображення залишалися чіткими та різкими на пристроях будь-якої роздільної здатності. Найкраще, краща взаємодія для користувачів, оскільки ваш сайт завантажується швидше - особливо це стосується пристроїв із високою роздільною здатністю.

Ретельно протестуючи Nano

Не задоволені всіма економіями, ми почали шукати зображення SVG, щоб ретельно протестувати Nano. Усього 2,571 Були використані файли SVG різних розмірів та дизайну, загальною вагою 16,3 МБ. А після оптимізації Nano, що дало 6,2 МБ, дивовижна економія в розмірі 61,8%.

Невеликий вибір із понад 2500 зображень SVG, який використовується для тестування Nano

Відображення візуальної різниці

Через величезну кількість файлів, які ми тестували, і вона час від часу збільшується, нам доводиться створювати автоматизований тест, що включає автоматичне виділення різниць пікселів до та після оптимізації. Однією зі скарг на інші оптимізатори SVG є той факт, що мініфікація SVG може зламати ваше зображення, змусивши його відображатись інакше порівняно з оригіналом.

З цією метою ми переносимо диференціацію пікселів у нашому автоматизованому тесті на сам Nano. Тобто, Nano попередить вас, якщо виявить, що оптимізований SVG має різницю в пікселях більше 1% порівняно з оригіналом, тому гарантуючи, що оптимізація Nano ніколи не порушить SVG.

Нано-оптимізація, що відображає візуальні відмінності

Оскільки шрифти вбудовані та збережені, а також SVG, який є форматом векторної графіки, якість рендерингу в усіх роздільних здатностях незрівнянна з іншими растровими форматами.

Ми сподіваємось, що наша робота полегшить використання SVG скрізь. Зараз ми працюємо над створенням ще менших розмірів файлів, переносячи наші коди для роботи на Node.js, щоб ви могли автоматизувати свої виробничі збірки за допомогою Nano, серед іншого.

Як ви вважаєте, чи знайдете Nano корисним у своїх проектах? Повідомте мене в коментарях!