Пользователь
0,0
рейтинг
23 мая 2013 в 20:17

Разработка → Ещё один способ устранить ВОШ из песочницы

HTML*, CSS*

Задача


ВОШ — эффект, возникающий при стилизации текста подключаемым шрифтом, не установленным на компьютере пользователя. Проявляется, когда подключаемый шрифт ещё не успел скачаться, и стилизуемый текст отображается следующим шрифтом из значения свойства font-family этого элемента. Такое переключение шрифтов также может повлиять на размеры элемента, если они зависят от размеров текста в нём.
Эффект известен также как FOUT — так его назвал Пол Айриш.

При общих моментах, есть и особенности. Например, в Файрфоксе текст, который нужно будет отрисовать нестандартным шрифтом, в течение 3 секунд не отображается, в Хроме тоже есть подобная задержка. Если шрифт успеет скачаться за это время, текст отобразится сразу нужным шрифтом.

На эту тему здесь была такая статья. В ней последствия ВОШ рекомендовалось нивелировать грамотной игрой со шрифтами. К сожалению, иногда подключаются такие шрифты, которые слишком отличаются по характеристикам от стандартных.

Решение


Чтобы устранить ВОШ, я решил указывать шрифт в основном файле стилей при помощи data:uri, чтобы шрифт отображался сразу, вместе со страницей.

Остаётся выбрать формат шрифта, понимаемый большинством браузеров посетителей и удобный для загрузки. Широту поддержки форматов подключаемых шрифтов можно узнать здесь.

Шрифты в eot наиболее лёгкие, но поддерживаются только ИЕ.
Шрифты в ttf и svg тяжелы, иногда — конечно, это зависит от шрифта — занимающие в два раза больше места, чем eot и woff. В моей ситуации я выбрал woff, этот формат поддерживается большинством браузеров наших посетителей.
Ещё есть браузеры, которые woff не понимают, поэтому указываются альтернативы для них.

ИЕ версии 8 и старше не понимают шрифты в woff, им нужен eot. В то же время, ИЕ8 не понимает файлы в data:uri тяжелее 32КБ, а более старшие версии не воспринимают совсем никакие, поэтому в отдельном файле стилей для них можно просто указать ссылки на файлы шрифтов. Чтобы эти браузеры не загружали ненужное, подключение шрифта в woff и в других форматах выделено в отдельный файл стилей и отделено условным комментарием.

Также, есть мнение, что под Вин в Хроме svg-шрифты выглядят лучше других, но, мне кажется, это дело вкуса. Шрифт в этом формате лучше других сжимается при помощи gzip, но не поддерживается Файрфоксами и ИЕ.

Таким образом, подгружать шрифты можно при помощи следующего кода:

<!-- подключение файлов стилей -->
<!--[if lte IE 8]>
  <link rel="stylesheet" href="fonts_ie.css" media="all">
<![endif]-->
<!--[if gt IE 8]><!-->
  <link rel="stylesheet" href="fonts.css" media="all">
<!--<![endif]-->

<link rel="stylesheet" href="main.css" media="all">

/* fonts_ie.css */
@font-face {
	font-family: 'PT Sans Narrow';
	font-style: italic;
	font-weight: bold;
	src: url('PTS76F_W.eot');
}

/* fonts.css */
@font-face {
	font-family: 'PT Sans Narrow';
	font-style: italic;
	font-weight: bold;
	font-variant: normal;
	src: url('data:application/x-font-woff;base64,d09GRgABAAAA...aCw0AAA==') format('woff'), 
	     url('PTN77F_W.svg#PTSans-NarrowBold') format('svg'),
	     url('PTN77F_W.ttf') format('truetype');
}


/* main.css */
body {
	font-family: 'PT Sans Narrow', 'Arial Narrow', sans-serif;
	font-style: italic;
}


При использовании этого способа ВОШ остаётся только в неподдерживающих woff-шрифты, планомерно теряющих пользователей браузерах, самый распространённый из которых на данный момент — ИЕ8.

На этой странице шрифт подключен традиционно.
Здесь шрифт закодирован.
Эффект заметней на медленном соединении.

Особенности


Стоит осознать, что при использовании такой техники остаются браузеры, которые не понимают шрифты в woff, но которым придётся их загружать. Тут уже играет роль количество посетителей с такими браузерами и продуктивность их посещений. В моей ситуации оказалось, что лучше устранить ВОШ.

Шрифт всё равно будет скачиваться, даже если установлен локально. Это сделано, чтобы предотвратить конфликты между начертаниями; будет скачиваться такое, какое нужно.
Страница не будет отрисовываться, пока файл стилей со шрифтом не скачается.

Также отмечу, что способ не подойдёт для шрифтов с лицензией, не позволяющей загружать их при помощи data:uri.

И, конечно, гарантированное решение всех проблем с подгружаемыми шрифтами — отказаться от их использования. Серьёзно, иногда они ни к чему.

Дополнительная информация


Отличная отправная точка для изучения темы подключаемых шрифтов
Если нужно подключить шрифт как обычно. Здесь же находится комментарий, который я заметил уже после того, как применил этот способ.

Немного об особенностях подключения.
Сергей Васильев @SVGen
карма
10,0
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

Комментарии (16)

  • 0
    Ха, весьма элегантное решение, спасибо. Добавил в избранное.
  • 0
    Познавательно, спасибо.
  • 0
    Что касается разных шрифтов в разных браузерах… А нельзя на сервере определять браузер и выдавать шрифт в нужном формате (уже закодированным в dataurl)?
    • 0
      Да определять особо нечего. IE не поддерживает data:uri больше 32 КБ, а для других в 99% случаев подойдёт WOFF.
    • +1
      Конечно, можно. Это будет максимально доброжелательно для всех посетителей. При этом всё равно нужно указывать альтернативные версии шрифтов — вдруг браузер неверно определится.

      В моём случае определять браузер оказалось нецелесообразно; тех, кому пришлось скачивать дополнительную версию шрифта, помимо woff, оказалось меньше половины процента.
      К тому же, своим способом я постарался избежать вмешательств в серверную часть.
    • 0
      Google Fonts именно так и делает
      • 0
        Почти так.
        Всё-таки Google Fonts отдаёт шрифт отдельным файлом, поэтому описываемый мной эффект может наблюдаться. Для его устранения у них есть js-инструмент WebFont Loader.
  • 0
    Плохой способ. base64 увеличивает количество подгружаемых данных. К тому же, вы даете гарантию, что разработчик, который будет поддерживать код после вас, поймет ваши пляски со шрифтами?

    Самый лучший способ — вырезать все неиспользуемые символы из шрифта, перекодировать шрифт с помощью белки и наслаждаться удивительным результатом. Таким способом можно урезать шрифт до трети от первоначального размера.
    • 0
      Что никак не спасёт от мигания при пинге в 500мс, например. Поэтому, имхо, лучше совместить приятное с полезным — урезать и заэмбедить.
      • +1
        Борьба с ветрянными мельницами. Проблема сегодняшнего дня — не большое количество соединений и не большие пинги, а страницы по 5-6 мегабайт.

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

        Я всё же останусь при мнении, что данная техника порочна, так как является не нужной оптимизацией и увеличивает размер страницы. Всегда есть вещи, которые можно было бы оптимизировать, чтобы извлечь бОльшую выгоду, чем от данного способа. Например, объединение картинок в спрайты, загрузка шрифтов до скриптов или объединение скриптов в один файл.
        • 0
          К тому же, вы даете гарантию, что разработчик, который будет поддерживать код после вас, поймет ваши пляски со шрифтами?

          Если это не знакомый мне разработчик, гарантию не дам :)
          Но способ задокументирую и уверен, что всё будет хорошо.

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

          Вообще, подключаемые шрифты увеличивают размер страницы сами по себе, а в этой статье я пишу только про эффект, с ними связанный.
          Своим методом я не отменяю необходимость оптимизации других аспектов. Конечно, всё это — и даже больше — нужно делать, вырезать неиспользуемые символы в том числе.

          Для примера к статье я использовал PT Sans Narrow с большим количеством символов, которые я, скорее всего, никогда не буду использовать. Но ничего не мешает мне на реальном сайте их все вырезать, как вы описали.

          Да, base64 увеличивает размер шрифта, но gzip практически нивелирует разницу.
  • 0
    Хотя мне и не нравится мода хранить тяжелые файлы в data:URI, стоит отметить, что woff-шрифт в base64 сжатый gzip на какие-то байты больше обычного woff (хоть тот gzip'нут хоть нет — и так уже сжат).
  • 0
    Автору хочется сказать спасибо, а статью дополнить другими методами оптимизации загрузки шрифтов (оригинал и перевод).
    • 0
      Спасибо и вам за полезное дополнение!
  • 0
    А как кодировать шрифты в data:uri?
    • 0
      Для себя определил два варианта:
      — кодировать генератором (например, таким), когда результат нужен быстро;
      — использовать генератор белки-шрифтелки, если нужно что-то посерьёзнее — к примеру, вырезать ненужные символы — в экспертном режиме есть опция «Base64 Encode, embed font in CSS».

      В конце концов, после генерации следует удостовериться, что mime-type у закодированного шрифта проставлен в соответствии со спецификациейapplication/font-woff (хотя Хром утверждает, что должно быть application/x-font-woff).

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.