x
 
Александр
21 декабря 2017
Советы почтой каждую неделю
Пожалуйста, получите наше письмо, чтобы подтвердить свой адрес:
Вы подписаны на «Советы за неделю»:

Василию Половнёву: как быстро и без миганий загружать веб-шрифты?


Это зави­сит от задачи. Рас­скажу, как мы решаем эту про­блему в кни­гах бюро.

Книги пред­на­зна­чены для дли­тель­ного и мно­го­крат­ного чте­ния. Мы опти­ми­зи­руем загрузку шриф­тов соот­вет­ственно: ника­ких мига­ний, пер­вое откры­тие мед­лен­ное, после­ду­ю­щие — быстрые.

Дол­гое время мы загру­жали веб‑шрифты, коди­руя их в Base64 и встра­и­вая прямо в ЦСС. Это мед­ленно: шрифты весят на 30% больше, плюс ухо­дит время на деко­ди­ро­ва­ние. Когда мы вынесли шрифты из ЦСС и стали загру­жать их в WOFF2 по HTTP/2, время до пер­вой отри­совки сокра­ти­лось на треть.

А чтобы при сле­ду­ю­щем откры­тии шрифты не гру­зи­лись заново, явно кеши­руем их навечно:

cache-control:max-age=315360000
expires:Thu, 31 Dec 2037 23:55:55 GMT

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

<head>
  <title>...</title>
  ​
  <link rel="preload" as="font" type="font/woff2"
    href="https://fonts.bureau.ru/1.6/bureausans-regular.woff2"
    crossorigin>
  ​
  <link rel="preload" as="font" type="font/woff2"
    href="https://fonts.bureau.ru/1.6/bureausans-bold.woff2"
    crossorigin>
</head>
После вклю­че­ния пред­за­грузки шриф­тов, время до пер­вой отри­совки «Типо­гра­фики и вёрстки» умень­ши­лось в сред­нем на секунду

Чтобы шрифты не мигали, мы дожи­да­емся их загрузки и готов­но­сти. Для этого в кни­гах есть «проб­ники» — эле­менты с задан­ным шриф­том и тре­бу­е­мой шириной.

Напри­мер, мы знаем, что слово mmm, набран­ное Бюро­сан­сом с кег­лем в 100 пик­се­лей, имеет ширину 238 пик­се­лей на экране. То же слово, набран­ное систем­ным шриф­том, — 250 пик­се­лей. Зна­чит, если ширина эле­мента с тек­стом mmm равна 238 пик­се­лям, шрифт загру­жен и готов к использованию.

<style>
.fontChecker {
  position: fixed;
  z-index: -1;
  font-size: 100px;
  opacity: 0;
}
​
.fontChecker::before {
  content: 'mmm';
}
</style>
​
<div
  style="font-family: Bureausans;"
  data-min-width="237"
  data-max-width="240"
  class="fontChecker js__fontChecker">
</div>
Неболь­шой раз­брос нужен для ретины‑нере­тины, где ширина и начер­та­ние немного меня­ются

Перед запус­ком книга ждёт, пока раз­меры всех проб­ни­ков не попа­дут в требуемые:

let fontCheckInterval
​
// Как часто про­ве­ряем проб­ники
const FONT_CHECK_INTERVAL = 100
​
// Мак­си­маль­ное время ожи­да­ния шриф­тов
const MAX_FONTS_WAIT = 4000
​
const isFontLoaded = (font) => {
  const probeWidth = font.$el.width()
​
  return probeWidth >= font.minWidth && probeWidth <= font.maxWidth
}
​
const onFontsReady = (callback) => {
  const fonts = $('.js__fontChecker').map((_, el) => {
    const $el = $(el)
    ​
    return {
      $el: $el,
      minWidth: +$el.attr('data-min-width'),
      maxWidth: +$el.attr('data-max-width'),
    }
  }).get()
  ​
  let timeSpent = 0
  ​
  fontCheckInterval = setInterval(function() {
    const allFontsReady = fonts.every(isFontLoaded)
    ​
    // Если все шрифты уже готовы или
    // мы так и не дожда­лись их загрузки,
    // отри­со­вы­ваем стра­ницу
    if (allFontsReady || timeSpent > MAX_FONTS_WAIT) {
      clearInterval(fontCheckInterval)
      callback()
    }
    ​
    timeSpent += FONT_CHECK_INTERVAL
  }, FONT_CHECK_INTERVAL)
}
​
// onFontsReady(initApp)
Пер­вая вер­сия опи­ра­лась на document.fonts.ready. К сожа­ле­нию, в Сафари он сра­ба­ты­вает слиш­ком рано: когда бра­у­зер уже загру­зил шрифты, но ещё не при­ме­нил их к стра­нице

Ещё по теме

P. S. Это был совет о веб‑разработке. Хотите знать всё о коде, тестах, фронтенд‑разработке, цеэсэсе, яваскрипте, рельсах и джейде? Присылайте вопросы.
Вёрстка и прототипирование — дисциплина Школы дизайнеров. Набор закрыт. Оставьте почту, и мы напишем вам, когда откроется следующий набор.
 

Поделиться
Отправить

Цель рубрики — обсуждение вопросов дизайна всех видов, текста в дизайне и взаимоотношений дизайнеров с клиентами.

Мы публикуем комментарии, которые добавляют к уже сказанному новые мысли и хорошие примеры. Мы ожидаем, что такие комментарии составят около 20% от общего числа.

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

Вот такой веб 2.0.

Разработчик, который не думает, а просто делает — не нужен? 4 Что делает тег meta с атрибутом name="viewport"? Зачем его указывать? Автотесты «на пальцах» 1 Как следить за качеством кода? Часть третья: процессы 3




Недавно всплыло

В бюро есть таймтрекинг для сотрудников? 5 Хочу научиться сторителлингу 2 Как найти себе замену 1 Как совместить информационный стиль и текст для поисковиков? 7