Блокнот · Заметка 002 · Типографика
Десять языков, три файла шрифтов
При запуске сайта на десяти языках первым трещит бюджет на шрифты. Мы уложились. Но за кириллицу и арабские символы пришлось заплатить иначе. Эту цену мы не скрыли.
Основатель BLN Global · · Читать 6 мин
Короткий ответ
Если бы те же три шрифта загружались из Google Fonts, турецкая страница скачивала бы 6 файлов на 250 KB с двух внешних источников. С нашего сервера приходят 3 файла на 165 KB из одного источника. Основную экономию дали не подмножества символов, а фиксация неиспользуемых осей. Для кириллицы и арабского пришлось выбрать отдельные семейства. Поэтому часть символов в арабской версии берётся из запасного шрифта.
Типографика сайта держалась на трёх гарнитурах: Archivo для заголовков, Instrument Sans для текста, Martian Mono для чисел и меток. Все три шрифта переменные. На пяти языках всё было спокойно. Когда дошли до десяти, сразу выросли две проблемы: вес загрузки и покрытие алфавитов.
Что с чем сравниваем
Сравнивать исходные TTF с опубликованными WOFF2 нечестно. Большую часть разницы даёт сжатие, а не сокращённый набор символов. Сравнивать надо с реальной альтернативой: сколько пришлось бы скачать, если бы те же три семейства загружались из Google Fonts.
Все девять файлов не качаются. Браузер unicode-range смотрит на поле и загружает только нужные странице подмножества. Для турецкой страницы это latin + latin-ext на каждое семейство:
latin 88.0 KB <- latin-ext 83.8 KB <- vietnamese 33.6 KB latin 29.2 KB <- latin-ext 10.8 KB <- latin 23.0 KB <- latin-ext 15.5 KB <- cyrillic 10.3 KB cyrillic-ext 3.1 KB Турецкая страница скачает: 250 KB (6 файлов)
Вес шрифтов на турецкой странице
archivo.woff2 + instrument.woff2 + martian.woff2 реальный вес файлов на диске.Помимо байтов, выиграли еще в двух местах: шесть запросов стали тремя, а DNS + TLS-рукопожатия к двум внешним источникам исчезли. Как мы закрыли ресурс, который блокировал первую отрисовку в заметке про последние 18 баллов рассказываем.
Три ловушки
Первое: в подмножестве latin-ext нет базовых латинских букв
Сначала мы скачали файл latin-ext из Google Fonts и собрали подмножество. Получили 130 глифов без цифр. Причина проста: latin-ext дополняет latin, а не заменяет его. Это отдельный доп. это подмножество, а не полный алфавит. Скачай полный вариативный шрифт из репозитория google/fonts и сам выдели нужное подмножество.
Второе: если не зафиксировать неиспользуемые оси, файл вырастет в пять раз
Каждая ось вариативного шрифта утяжеляет файл. В макете нужны только вес и ширина. Если не зафиксировать остальные оси на значениях по умолчанию, их данные останутся в файле.
tam = {a.axisTag: a.defaultValue for a in t['fvar'].axes if a.axisTag not in eksen} tam.update(eksen) # Оси, кроме wght/wdth, фиксируются на значениях по умолчанию, # иначе файл вырастает в пять раз
Третья: gvar грузится лениво
после фиксации оси через fontTools попытка сразу собрать сабсет KeyError: space получается. Причина в ленивой загрузке данных переменных глифов (gvar): после фиксации объект в памяти выглядит цельным, но сабсеттер не может его прочитать. Обход кривой, зато в одну строку: сохрани файл как временный TTF, открой заново и потом вырежи подмножество.
Кириллица и арабский: за что платим
В Archivo нет кириллицы, в Instrument Sans тоже. Арабского письма нет ни в одном. Для этих двух языков пришлось выбрать отдельные семейства, и выбор был не на вкус.
- Русский: Roboto Flex. По структуре совпало только одно: есть ось ширины. Значит, все
font-variation-settingsзначения работают без изменений. Один файл обслуживает заголовки и основной текст. Русская страница остаётся легче страницы на латинице. - Арабский: Noto Sans Arabic. Единственный кандидат с осью ширины. Один файл весит 144 КБ и закрывает сразу три роли, поэтому арабская страница загружает меньше страницы на латинице.
Цена вот где: Noto Sans Arabic → и ✓ Этих глифов нет. На арабской странице два знака берутся из резервного шрифта и немного отличаются от соседних. Мы не стали маскировать разницу и оставили комментарий в CSS. Иначе следующий разработчик примет её за ошибку.
Вёрстку справа налево мы настроили отдельно: развернули стрелки и заменили свойства позиционирования логическими аналогами (margin-inline-start, inset-inline-start), поэтому один CSS верно работает в обоих направлениях.
Небольшая настройка: почему Martian Mono подключён опционально
Две из трёх гарнитур font-display:swap использует Martian Mono. optional. Причину мы измерили: со swap Martian приходит поздно, заставляет меню заново измерить кнопку и даёт сдвиг вёрстки 0,015. Из-за предзагрузки он почти всегда успевает. Если не успел, страница не прыгает и остаётся на запасном шрифте.
Папка со шрифтами для десяти языков весит 404 КБ. Целиком её не скачивает никто. Каждая страница загружает файлы только для своего языка.