Tinder - один из самых популярных сервисов онлайн-знакомств, теперь доступен на веб-платформе по всему миру.

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

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

Наша веб-команда имеет относительно небольшой размер, но мы начинаем с великой миссии - мы хотим обеспечить эффективную и бесперебойную работу в Интернете с использованием передовых веб-технологий.

Архитектура

Tinder Online построен с использованием стека React / Redux.

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

Мы используем хранилище Redux для сохранения состояния нашего приложения. Наше состояние создается с помощью ImmutableJS и Normalizr, что позволяет нам выполнять эффективные и производительные операции с состоянием. Запомненные селекторы делают доступ к нашему магазину высокопроизводительным.

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

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

Побочные эффекты и асинхронные операции, такие как запросы API, обрабатываются с помощью Redux Sagas. Мы сохраняем части нашего состояния, такие как пользовательские настройки, местоположение и настройки приложений, с помощью IndexDB в поддерживаемых браузерах и при необходимости возвращаемся к localStorage. Постоянное хранилище значительно улучшает производительность запуска приложения и удобство использования.

Логика отрисовки приложения и настройки маршрутов централизованы и настраиваются на верхнем уровне. Эта абстракция позволяет нам отделить логику уровня страницы от логики уровня компонента и упрощает обработку разделения кода на уровне маршрута и различных эффектов перехода между страницами. Мы также разрабатываем компонент реакции прокси для реализации динамической загрузки Javascript и предварительной загрузки ресурсов для следующего маршрута.

Основные возможности прокрутки и анимация построены на основе React Motion. Интернационализацией занимается React Intl. Мы используем React I13n, чтобы отделить логику инструментария от логики пользовательского интерфейса путем создания подключаемых слушателей для различных систем отслеживания.

Представление

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

Мы фокусируемся на двух основных областях - производительности сети и производительности рендеринга.

Производительность сети

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

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

Критический путь рендеринга оптимизирован за счет встраивания большей части нашего общего CSS. Мы используем атомарный CSS для создания многоразовых и сжимаемых таблиц стилей. В атомарном CSS тематика пользовательского интерфейса и логика отображения контролируются реквизитами React, что упрощает совместное использование и поддержку нашего кода. Наш основной CSS, который включает темы, интервалы и адаптивный стиль, составляет около 10 КБ (gzip) для всего сайта.

Чтобы предотвратить увеличение размера нашего пакета при добавлении новых функций, мы устанавливаем бюджеты производительности для всех наших ресурсов. Размер наших пакетов Javascript и CSS проверяется при каждой фиксации. Установка пакета с хорошей производительностью вынуждает нас создавать компоненты с широким доступом. Мы также измеряем и отслеживаем производительность с помощью таких инструментов, как Lighthouse и CSS stats перед каждым выпуском. На стороне клиента собираются показатели мониторинга пользователей в реальном времени, такие как время загрузки и время рисования (PerformancePaintTiming).

Наш исходный код компилируется и заполняется Babel, а генерируется Webpack. Проведя анализ пакетов, мы смогли выявить несколько возможностей для стратегий оптимизации производительности, таких как разделение кода, встряхивание дерева или выбор альтернативных библиотек. Мы также используем babel-preset-env, чтобы включить только подмножество полифилов, предназначенных для наших поддерживаемых браузеров. Общие ресурсы, необходимые для веб-приложения, составляют около 3 МБ, что отлично подходит для пользователей с ограниченным объемом памяти на устройстве.

Производительность рендеринга

Мы оптимизируем производительность рендеринга и анимации, приоритизируя задачи Javascript с помощью requestIdleCallback. Некритические задачи, такие как контрольно-измерительные приборы, будут запланированы на время простоя. Мы также гарантируем, что наша разметка HTML и CSS являются высокооптимизированными и ленивыми загружаемыми заэкранными ресурсами через I nteraction Observer для быстрого рендеринга и плавной работы даже на более медленных устройствах.

Мы активно используем инструмент разработчика Chrome и инструмент разработчика React для выявления узких мест производительности, таких как перерисовка браузера, повторный рендеринг React или дорогостоящие операции Javascript.

Что дальше

Что касается продукта, мы наблюдаем очень положительное взаимодействие пользователей с веб-платформой.

Что касается технологий, есть несколько областей, на которых мы хотели бы сосредоточиться в ближайшее время.

  • Поэкспериментируйте с различными подходами к разделению кода, такими как отсрочка регистрации редукторов Redux и обработчиков саг.
  • Более широкое использование кэширования среды выполнения сервис-воркеров для улучшения работы в автономном режиме.
  • Выгрузка дорогостоящих задач, таких как анализ часто используемых ответов API, на веб-воркеров.
  • Повысьте производительность современных браузеров, экспериментируя с новыми примитивами браузера, такими как API сетевой информации.
  • Экспериментируйте с развертыванием модуля ES в поддерживаемом браузере
  • Перестроить структуру магазина Chitect Redux для улучшения управления состоянием

Мы также поделимся с сообществом дополнительной практикой и знаниями.

Особая благодарность нашим друзьям Адди Османи, Лиаму Спрэдлину, Чейни Цай и другим сотрудникам Google за предоставленные отличные идеи и предложения для прогрессивного веб-приложения Tinder!

Этот пост является совместной работой всех членов команды Tinder Web. Амрита Аракали, Энтони Чан, Брендан Тодаро, Эрик Хелленбранд, Джеки Вунг, Дженни Пенг, Кейт Макнайт, Салина Ву и Сид Джайн.

Связанные ресурсы