РИД ЭММОНС

Редизайн сайта NYTimes.com — это больше, чем свежий слой краски. Помимо нового внешнего вида, наши страницы статей также основаны на новой структуре и кодовой базе, чтобы работать быстрее и упростить будущие изменения. Рид Эммонс, руководитель разработки проекта, объясняет, как мы сделали это возможным.

Редко когда есть возможность начать с нуля на таком сайте, как NYTimes.com, и когда я говорю «с нуля», я имею в виду не просто обновление дизайна, а полное переосмысление всей цифровой платформы. Последний визуальный редизайн NYTimes.com произошел в 2006 году, но нам пришлось бы перевести наши часы в начало тысячелетия, чтобы найти последнее столь же масштабное изменение инфраструктуры. Мы решили изменить архитектуру клиентской и серверной части, чтобы соответствовать требованиям нового продукта, дизайна и отдела новостей, таким как более высокая производительность и отзывчивые макеты. Хотя часть существующего кода была сохранена и подвергнута серьезному рефакторингу, большая часть кода была удалена и использовалась только в качестве справочного материала.

Взгляд на дизайн прошлых статей

Публикация статических страниц: урок истории

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

Одним из основных недостатков использования нашей старой архитектуры были ее ограниченные динамические возможности. Поскольку HTML-код статьи был исправлен, но скрипты и таблицы стилей внутри него были динамическими, нашей команде переднего плана нужно было поддерживать каждую когда-либо созданную версию шаблона. Вот почему статья, опубликованная два года назад немного отличается от статьи, опубликованной несколько недель назад. Мягкий запуск обратно совместимого CSS и ожидание его раскеширования в каждом браузере перед запуском изменения JavaScript стало обычной практикой.

Главный архитектор проекта Эйтан Кенигсбург представил более глубокое погружение в нашу историю на одном из наших мероприятий TimesOpen в прошлом году.

Более продуманная планировка

Чтобы приспособиться к более продуманному дизайну, мы создали собственный адаптивный движок JavaScript, который позволяет нам поддерживать большое количество точек останова без использования каких-либо медиа-запросов CSS. Механизм обеспечивает адаптивный дизайн, переключая классы области просмотра в теге HTML в определенных точках останова. В сочетании с МЕНЬШЕ это позволяет создавать элегантный код, который гораздо проще поддерживать, а также поддерживать браузеры, которые до сих пор используют многие из наших читателей. Хотя его трансформация иногда неуловима, страница статьи корректируется более 20 раз в зависимости от размера браузера или устройства. Например, следующий фрагмент LESS использует наши адаптивные классы области просмотра:

.ribbon {
   ...
   // responsive
   // 1020
   .viewport-medium-50 & {
      .offset(0, 1, 0, left);
    }
// 1200
   .viewport-large-20 & {
      .offset(0, 2, 0, left);
   }
}

В дополнение к реагированию на точки останова платформа делает ряд вариантов того, как отображать макет, в зависимости от типа носителя в позиции ведущего, ориентации и размера носителя, а также от того, продается ли реклама напрямую или «покупается на обмен". С учетом контрольных точек страница статьи имеет более 100 вариантов.

Добавление структуры в наш JavaScript

Редизайн потребовал написания большого количества JavaScript для поддержки динамического и персонализированного набора функций. Надежная структура была необходима, чтобы модули могли жить вместе, не будучи сильно связанными. Backbone.js и RequireJS предоставили структуру и стандартный способ написания кода. Мы выбрали Backbone, потому что он обеспечивает желаемую степень гибкости и менее самоуверен, чем другие фреймворки. jQuery, Modernizr, SockJS, Underscore.js и Hammer.js были вспомогательными библиотеками, и мы также использовали преимущества Mocha и Chai для обеспечения тестового покрытия наших модулей.

Вот несколько методов, которые мы использовали при разработке нашего фреймворка:

  • Использование Backbone mixins для уменьшения дублирования кода.
  • Расширение всех представлений (и моделей) Backbone из базового представления.
  • Дросселирование/отключение дорогостоящих событий, таких как прокрутка и изменение размера.

Новая среда рендеринга PHP

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

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

Ускорение работы с помощью кэширования на стороне сервера

При обслуживании динамических статей нашей технологической платформе требовался надежный обратный прокси-сервер, чтобы защитить структуру рендеринга PHP от взлома. Успешный запуск Varnish на мобильном сайте NYTimes в мае прошлого года вселил в нас уверенность, что Varnish — лучшая технология для новой платформы. Varnish легко настраивается и обеспечивает молниеносное время отклика при обслуживании контента из кэша. Это также позволяет нам кэшировать наши статьи, чтобы те, которые изменяются чаще, оставались в кеше в течение более короткого времени.

Процесс сборки и производительность переднего плана

С помощью Grunt мы оптимизировали наш код, чтобы делать меньше запросов. Наши страницы статей теперь содержат три минимизированных файла сценария и CSS, которые загружаются синхронно, что значительно меньше, чем примерно 80 не минимизированных файлов, которые были включены в HEAD в старых статьях. Внизу страницы мы используем RequireJS для асинхронной загрузки нескольких файлов сборки, которые обрабатывают большую часть внешнего рендеринга. CDN без файлов cookie и заголовки кеша, установленные на один год, гарантируют, что наши читатели будут загружать значительно меньше байтов, чем раньше. С Varnish наша страница со статьей постоянно достигает DOMContentLoaded между 500–1000 миллисекундами.

Все теги сценариев блокируются, поэтому одно из самых больших улучшений производительности произошло за счет асинхронной загрузки рекламы. Поскольку реклама печально известна включением document.write, мы не можем просто добавить код прямо в DOM, не рискуя перезаписать содержимое страницы. Вместо этого все объявления привязываются к iFrame и добавляются при запуске DOMContentLoaded, что предотвращает потенциальные проблемы с отображением страницы.

Процесс сборки также генерирует другую магию, которую интерфейсная структура может использовать. Мы храним все наши значки в папке «sprite-me», чтобы пользовательская задача Grunt могла экспортировать лист спрайтов и файл миксина LESS, которые обеспечивают легкий доступ к координатам скомпилированного изображения. Наконец, мы используем Underscore для предварительной компиляции шаблонов HTML, чтобы они могли быть легко «затребованы» модулями и быстро отображались браузером.

Заключительные замечания

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

В будущем другие члены нашей команды углубятся в технологии, используемые для создания этой платформы, начиная от WebSockets и заканчивая фреймворком PHP.