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

Василий, привет!

Расскажи про устройство поиска в ваших книгах? В чём и как храните данные? Как показываете превьюшки текста в поиске? Что почитать на эту тему? Как дела?

(Вторая часть)


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

Превьюшки разворотов генерирует PhantomJS, управляемый браузер без визуального интерфейса. Чаще всего его используют для автоматизации, визуального и интеграционного тестирования (см. PhantomCSS и Poltergeist).

Превьюшки генерируются при каждой продакшен-сборке книги: и развороты, и движок меняются так часто, что хранить их и перегенерировать время от времени не имеет смысла. Поэтому для превьюшек мы используем «безголовый», а не реальный браузер: в «Типографике и вёрстке» PhantomJS генерирует их за 1,5 минуты, Хром — за 5 минут, а Сафари — за 6.

Чтобы в превьюшках было меньше шума, убираем с них номера разворотов и колонтитулы. Делаем это через инъекцию стилей для превьюшек:

function injectPreviewCSS() {
  // ...
  page.evaluate(function(css) {
    $('<div />', { html: '<style>' + css + '</style>' }).appendTo('body');
  }, previewCSS);
}

page.open(book, function() {
  injectPreviewCSS();
  // ...
}

Так как книги самостоятельно управляют загрузкой картинок, дополнительно учим PhantomJS дожидаться их загрузки:

var RESOURCE_WAIT = 1000;
var MAX_RENDER_WAIT = 30000;

var resourceCount = 0;
var renderTimeout;

// При запросе картинки увеличиваем счетчик ресурсов,
// которые ещё предстоит скачать. Если уже собрались
// снимать скриншоты, отменяем.
page.onResourceRequested = function() {
  resourceCount += 1;
  clearTimeout(renderTimeout);
};

// При получении картинки, уменьшаем счетчиков ресурсов.
// Если уже всё скачали, даем браузеру ещё секунду
// на раздумье.
//
// Если за эту секунду, браузер не стал ничего скачивать,
// считаем, что всё готово и начинаем снимать скриншоты.
page.onResourceReceived = function(res) {
  if (!res.stage || res.stage === 'end') {
    resourceCount -= 1;
    if (resourceCount === 0) {
      renderTimeout = setTimeout(doRender, RESOURCE_WAIT);
    }
  }
};

// Если за 30 секунд браузер так всё и не загрузил,
// перестаем ждать и снимаем скриншоты.
setTimeout(function() {
  doRender();
}, MAX_RENDER_WAIT);
Этот подход применим и для работы с сайтами, асинхронно загружающими содержимое

У PhantomJS есть и проблемы: он не поддерживает видео и отстает в поддержке стандартов. Книжный движок до сих пор использует -webkit- префиксы для флексбоксов только ради него. Поэтому со временем планируем перейти на Headless Chrome.

P. S. А ещё мы ищем фронтендера в издательство.

P. P. S. Это был совет о веб-разработке. Хотите знать всё о коде, тестах, фронтенд-разработке, цеэсэсе, яваскрипте, рельсах и джейде? Присылайте вопросы.

Поделиться

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

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

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

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





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

Кто ты? 1 Начальник считает, что перед встречей нужно обязательно разработать несколько вариантов предложений 6 1 2