Страница результатов поиска — одна из самых популярных страниц Яндекса. Её загружают около 130 миллионов раз в день. Это при среднем размере страницы в 25КБ дает нам 3ТБ трафика в сутки.
Несмотря на кажущуюся простоту, за тем, из чего состоит эта страница, — огромная работа большого количества людей и много сложных технологий.
Развивая интерфейсы, обычно мы идём по эволюционному пути, меняем страницу поэтапно. Проверяем наши решения, внедряя их на небольшой процент пользователей, — проводим эксперименты. Нас уже не устраивают небольшие изменения: хотим развивать продукт, построив новую технологическую платформу, на которой в будущем будем реализовывать свои проекты.
Сегодня мы начинаем эксперимент с новой страницей результатов поиска. И для этого мы выбрали нашу площадку для тестирования поиска по мировому интернету — yandex.com. Первое, на что вы обратите внимание, когда увидите новую страницу — это отличие ее дизайна от текущей версии страницы результатов поиска на yandex.ru. Но этот эксперимент в первую очередь не про дизайн, а про реализацию значительных технологических изменений. Разумеется, над дизайном мы тоже работаем и планируем проверять новые решения, но построение нового начинается с качественного фундамента. Хотим рассказать, как именно мы его строили: какие решения принимали и какие использовали технологии.
Разработка шаблонов
Ещё до того, как появились первые картинки-макеты, нам нужно было определиться с подходом к разработке. Варианта было два: сверстать статическую страницу и порезать её потом на шаблоны или разрабатывать сразу на реальных данных и писать реальные шаблоны.
В общем случае, особенно если вёрсткой и разработкой шаблонов занимается одна команда, второй подход предпочтительнее. Он обеспечивает готовность проекта к релизу (или хотя бы к тестированию) в любой момент времени. То есть уже в самом начале разработки возникает «сырой», но уже функционирующий прототип проекта, который можно «потрогать». В итоге именно этот вариант мы и выбрали.
Сильно сократить время на разработку и тестирование первого прототипа помог наш механизм сборки проектов, основанный на методологии БЭМ (Блок-Элемент-Модификатор). Он позволяет подключать внешние библиотеки блоков, так что существенную часть интерфейса мы собрали из готовых блоков, которые уже есть на других сервисах Яндекса и лежат в разных внутренних git- и svn-репозиториях.
JavaScript везде
Под капотом у новой версии страницы результатов поиска — JavaScript-шаблоны. Они работают быстрее, чем чем шаблонизатор для языка Perl TT2, который мы использовали раньше, и писать их удобнее и проще. Сейчас на JS написаны два уровня шаблонизации, клиентские скрипты, утилиты и технологии сборки, демон-сборщик.
В настоящий момент для сжатия JS- и CSS-кода используется YUICompressor, который требует Java на сервере, поэтому в перспективе мы хотим перейти на JS-обфускаторы UglifyJS и CSSO — они работают быстрее и менее требовательны к ресурсам.
Использование одного языка на всех технологических уровнях, начиная c браузера и заканчивая утилитами сборки, сильно упрощает жизнь многим участникам процесса. Разработчики могут конфигурировать (а при желании и дописывать) инструменты для сборки, одинаково легко пишут код для клиента и сервера. Уже не требуется глубокое знание большого количества разных технологий, достаточно хорошо знать базовые: HTML, CSS, JS. Благодаря этому стало проще подключать новых людей в команду: JavaScript знают все фронтенд-разработчики в Яндексе, а серверную специфику можно освоить очень быстро.
AJAX, History API
Довольно давно стало «модно» использовать технику AJAX для обновления данных на странице без полной перезагрузки. Плюсы этой техники достаточно очевидны: не требуется каждый раз при обновлении данных грузить полностью всю страницу (разметку, стили, скрипты, картинки), инициализировать скрипты. Это сильно ускоряет процесс доставки новых данных до пользователя. Разница по скорости загрузки на медленных каналах — радикальная.
Однако, прекрасно понимая все плюсы AJAX, мы не спешили применять этот подход в Яндекс.Поиске. Мы хотели предложить нашим пользователям не просто технологию, а целостный продукт с переработанным интерфейсом. Поэтому новая версия страницы результатов поиска потребует повсеместного применения ajax и histori api.
(Подробно о нашей реализации мы рассказывали 2 июня 2012 года в Минске на Я.Субботнике)
CSS
Изначально у нас не было цели использовать возможности CSS3 полностью, но почти все они оказались необходимы для решений наших задач. Стрелочки меню на трансформах, тени у блоков, псевдоселекторы first-child/last-child вместо классов-модификаторов — все это есть в новом интерфейсе. При этом для старых браузеров предусмотрена деградация: вместо теней — простые однопиксельные контуры, вместо стрелочек в меню — обычные прямоугольники, svg-градиенты в IE9 и сплошная заливка фона для IE8 и старше.
Ещё одним из важных решений было использование абсолютных единиц измерения для указания размеров шрифта. Практически на всех наших сервисах сейчас используется указание размеров в относительных процентах или тегах <em>, но в новом проекте мы решили отказаться от них в пользу пикселей. Аргументов у этого решения несколько. Во-первых, доля браузеров, которые не умеют масштабировать шрифты в пикселях, исчезающе мала. Во-вторых, размеры в абсолютных единицах исключают влияние контекста, а вёрстка абсолютно независимыми блоками — один из основных принципов БЭМ-методологии. Ну и в-третьих, страница результатов поиска должна нормально работать на тач-устройствах. Разрешение экрана на них часто заранее известно и строго фиксировано, а меняться может только его ориентация.
Деплой
Почти все наши проекты хранят свои статические файлы на статическом кластере — yandex.st. Это несколько десятков машин, расположенных в разных городах и странах, которые умеют очень быстро отдавать данные.
Причин для использования статистического кластера несколько:
— не нужно генерировать файлы перед отправкой — всё уже готово и лежит на диске;
— для передачи готовых файлов достаточно лёгкого веб-сервера;
— не требуется высокая производительность машин;
— статика кэшируется навсегда, а инвалидация осуществляется либо изменением версии пакета, либо изменением хэш-суммы;
— на домен yandex.st не отправляются куки сервиса, это уменьшает объём трафика;
— «сквозные» файлы (использующиеся на нескольких сервисах, например jquery.min.js или логотип Яндекса) не нужно загружать каждый раз при переходе с сервиса на сервис.
Чтобы положить файлы сервиса на статический кластер, нужно собрать deb-пакет. Пакет собирается либо вручную, либо специальным скриптом. После сборки нового пакета заявка на выкладку отправляется в Кондуктор — наш внутренний инструмент, позволяющий без участия людей выложить пакет на сотни машин. Это очень важно, учитывая количество сервисов Яндекса и частоту их обновления.
Статический кластер — очень сложная система, которая решает множество задач оптимизации скорости работы браузера у клиента и доставки файлов пользователю. При этом пользоваться им очень просто: чтобы завести новый проект в Кондукторе, достаточно заполнить небольшую форму-заявку и получить подтверждение от ответственного администратора, после этого разработчик сервиса сам полностью контролирует процесс выкладки. Время на подготовку статики нового сервиса к деплою сокращается буквально до пары часов одного специалиста, а новая версия пакета выкладывается и развертывается за несколько секунд.
Обновление страницы результатов поиска будет продолжаться: как на yandex.com, так и на других версиях Яндекса – от турецкого до российского. У нас в планах много экспериментов, в том числе и с интерфейсами.
Михаил Трошев,
Руководитель группы разработки поисковых интерфейсов
Автор: Zalina