company_banner

От UI-kit до дизайн-системы

    Опыт онлайн-кинотеатра Иви

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


    Меж тем компания год от года удваивала штат — нужно было масштабировать отдел дизайна и оптимизировать процессы создания и передачи макетов в разработку. Умножаем всё это на «зоопарк» платформ, которые нужно поддерживать, и получаем подобие вавилонского столпотворения, которое просто не способно «нормально делать» и приносить доход. Развитие платформ часто шло параллельно, и один и тот же функционал мог выходить на разных платформах с лагом в несколько месяцев.


    Отдельные наборы макетов для каждой платформы

    Традиционно, мы начали с проблем, которые помогла бы решить дизайн-система и сформулировали требования к её проектированию. Помимо создания единого визуального языка, увеличения скорости макетирования и разработки, повышения качества продукта в целом, было жизненно необходимо максимально унифицировать дизайн. Это нужно для того, чтобы развитие функционала стало возможным сразу на всех наших платформах одновременно: Web, iOS, Android, Smart TV, tvOS, Android TV, Windows 10, xBox One, PS4, Roku — не прорабатывая при этом каждую из них в отдельности. И это у нас получилось!

    Дизайн → данные


    Когда принципиальные договорённости отделов продукта и разработки были достигнуты, мы сели за подбор технологического стека и проработку деталей всего процесса — от макета до релиза. Чтобы полностью автоматизировать процесс передачи дизайна в разработку поисследовали вариант с парсером параметров компонентов прямо из Sketch-файлов с макетами. Оказалось, что находить нужные нам куски кода и извлекать нужные нам параметры — затея сложная и опасная. Во-первых, дизайнерам придётся быть крайне аккуратными в именовании всех слоёв исходника, во-вторых, это работает только для самых простых компонентов, а в-третьих, зависимость от чужой технологии и структуры кода исходного Sketch-макета ставит под угрозу будущее всего проекта. Мы решили отказаться от автоматизации на этом участке. Так в команде дизайн-системы появился первый человек, на вход которому подаются дизайн-макеты, а на выходе — данные, описывающие все параметры компонентов и иерархически упорядоченные по методологии атомарного дизайна.

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

    Вручную разбираем визуал на элементы-атомы: шрифты, цвета, прозрачности, отступы, скругления, иконки, картинки и длительности для анимаций. И собираем из этого кнопки, инпуты, чекбоксы, виджеты банковских карт и т. д. Стилям любого из уровней, кроме пиктограмм присваиваем несемантические имена, например названия городов, имена нимф, покемонов, марки автомобилей… Тут условие одно — список не должен исчерпаться раньше, чем закончатся стили — шоу маст гоу он! Семантикой же не стоит увлекаться, чтобы не пришлось добавлять среднюю кнопку между «small» и «medium», например.

    Визуальный язык


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

    Ранее мы уже успели «обкатать» большинство элементов дизайна в приложении под Windows 10, которое на тот момент являлось для нас новой платформой, то есть требовалась отрисовка и разработка «с нуля». Рисуя его, мы смогли подготовить и проверить большинство компонентов и понять, какие из них должны были войти в будущую дизайн-систему Иви. Без такой «песочницы» подобный опыт можно было получить только большим числом итераций на уже работающих платформах, а на это потребовалось бы больше года.

    Переиспользование одинаковых компонентов на разных платформах уменьшает количество макетов и массив данных дизайн-системы в разы, поэтому дизайну предстояло решить ещё одну задачу, ранее не описанную в практиках продуктового дизайна и разработки — как, например кнопку для телефонов и планшетов переиспользовать на телевизорах? И как в принципе быть с размерами шрифтов и элементов на таких разных платформах?

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


    Теперь нужно привести к одному размеру макета все большие экраны и вписать их в общую сетку. Apple TV и Roku разрабатываются в размер 1920x1080, Android TV — 960x540, Smart TV, в зависимости от вендора бывают такими же, а бывают 1280x720. Когда приложение рендерится и отображается на экранах Full HD, 960 умножается на 2, 1280 на 1,33, а 1920 выводится как есть.

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


    Единый UI для всех платформ

    Теперь для отрисовки новой фичи нам не нужно рисовать макеты под каждую из платформ, плюс варианты адаптивности для каждой из них. Достаточно показать один макет и его адаптивность для всех платформ и устройств любой ширины: телефоны — 320–599, всё остальное — 600–1280.

    Данные → разработка


    Конечно, как бы нам ни хотелось прийти к абсолютно унифицированному дизайну, каждая платформа имеет свои уникальные особенности. Несмотря на то, что и веб, и Smart TV используют стек ReactJS + TypeScript, приложение для Smart TV запускается на устаревших WebKit- и Presto-клиентах, и потому не может использовать общие стили с вебом. А email-рассылки и вовсе вынуждены работать с табличной вёрсткой. При этом ни одна из не-html-платформ не использует и не планирует использовать React Native или какие-то её аналоги, опасаясь ухудшения производительности, так как у нас слишком много кастомных лэйаутов, коллекций со сложной логикой обновления, изображений и видео. Поэтому для нас не подходит распространённая схема — поставлять готовые CSS-стили или React-компоненты. Поэтому мы решили передавать данные в формате JSON, описывая значения в абстрактном декларативном виде.
    Так свойство rounding: 8 приложение Windows 10 преобразует в CornerRadius="8", веб — border-radius: 8px, Android — android:radius="8dp", iOS — self.layer.cornerRadius = 8.0.
    Cвойство offsetTop: 12 один и тот же веб-клиент в разных случаях может интерпретировать как top, margin-top, padding-top или transform

    Декларативность описания также предполагает, что если платформа технически не может использовать какое-либо свойство или его значение, она может его проигнорировать. С точки зрения терминологии мы сделали некое подобие языка эсперанто: что-то взяли из Android, что-то из SVG, что-то из CSS.

    В случае если на той или иной платформе потребуется отображать элементы как-то иначе, мы реализовали возможность передачи соответствующей генерации данных в виде отдельного JSON-файла. Например, состояние «в фокусе» для Smart TV, диктует изменение позиции текста под постером, значит для этой платформы данный компонент в значении свойства «отступ» будет содержать необходимые ей 8 поинтов отступа. Хоть это и усложняет инфраструктуру дизайн-системы, зато даёт дополнительную степень свободы, оставляя нам возможность самим управлять визуальной «непохожестью» платформ, а не быть заложниками нами же созданной архитектуры.


    Пиктограммы


    Иконографика в цифровом продукте — это всегда объёмный и не самый простой подпроект, часто имеющий отдельного дизайнера. Глифов всегда много, каждый из них имеет несколько размеров и цветов, к тому же платформам они нужны, как правило в разных форматах. В общем, не было повода не завести всё это в дизайн-систему.


    Глифы загружаются в векторном SVG-формате, а значения цветов автоматически заменяются переменными. Приложения-клиенты могут получать их уже готовыми к использованию — в любом формате и цвете.

    Предпросмотр


    Поверх JSON’а с данными мы написали инструмент для предпросмотра компонентов — JS-приложение, на лету пропускающее JSON-данные через свои генераторы разметки и стилей, и отображающее в браузере различные вариации каждого из компонентов. По сути, предпросмотр является точно таким же клиентом, как и платформенные приложения, и работает с теми же данными.

    Понять, как работает тот или иной компонент, проще всего путём взаимодействия с ним. Поэтому мы не стали использовать инструменты, подобные Storybook, а сделали интерактивный предпросмотр — можно пощупать, понаводить, покликать… При добавлении в дизайн-систему нового компонента он появляется в предпросмотре, чтобы платформам было на что ориентироваться при его внедрении.

    Документация


    На основе тех данных, которые в виде JSON поставляются платформам, автоматически формируется документация по компонентам. Описывается перечень свойств и возможные типы значений в каждом из них. После автогенерации информацию можно уточнить в ручном режиме, добавить текстовое описание. Предпросмотр и документация снабжены перекрёстными ссылками друг на друга на уровне каждого компонента, а вся информация, попадающая в документацию, доступна разработчикам в виде дополнительных JSON-файлов.

    Депрекатор


    Ещё одной необходимостью стала возможность со временем заменять и обновлять уже существующие компоненты. Дизайн-система научилась сообщать разработчикам, какие свойства или даже целые компоненты использовать нельзя и удалять их, как только они перестают использоваться на всех платформах. Пока в этом процессе ещё много «ручного» труда, но мы не стоим на месте.

    Клиентская разработка


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

    Для верстки экранов iOS-приложения мы используем два базовых механизма, которые предоставляет iviUIKit: cвободная компоновка элементов и компоновка коллекций элементов. Мы используем VIPER, и всё взаимодействие с iviUIKit сосредоточено во View, а большая часть взаимодействия с Apple UIKit сосредоточена в iviUIKit. Размеры и расположение элементов задаётся в терминах колонок и синтаксических конструкций, работающих поверх нативных констрейнтов iOS SDK, делающих их более прикладными. Особенно это упростило нам жизнь при работе с UICollectionView. Мы написали несколько настраиваемых обёрток для лэйаутов, в том числе довольно сложных. Клиентского кода получилось минимум и он стал декларативным.

    Для генерации стилей в проекте Android мы используем Gradle, превращая данные дизайн-системы в стили формата XML. При этом у нас есть несколько генераторов различного уровня:

    • Базовые. Парсят данные примитивов для генераторов более высокого уровня.
    • Ресурсные. Скачивают картинки, иконки, и прочую графику.
    • Компонентные. Пишутся для каждого компонента, где описано какие свойства и как перевести в стили.

    Релизы приложений


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

    Итоги


    Скоро год как дизайн-система стала частью инфраструктуры, обслуживающей развитие онлайн-кинотеатра Иви, и уже можно делать кое-какие выводы:

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

    Предпросмотр компонентов дизайн-системы Иви — design.ivi.ru
    Онлайн-кинотеатр ivi
    148,97
    Компания
    Поделиться публикацией

    Комментарии 22

      0
      У вас заголовки в посте случайно цветом забрендировались.
        +1
        Спасибо за статью. А расскажите про сетку поподробнее, очень интересно. На design.ivi.ru нет информации.
          +1
          Про это можно рассказывать часами!) Что именно интересует?
            0

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

              0
              Для начала нужно забыть про повышенные плотности экранов (retina) и считать их в дипах (dp у Андроида) или поинтах (pt у Айос).

              За отправную точку для сетки вы взяли количество постеров, которые хотим видеть на том или ином экране. На телефонах получилось от 2 до 4 колонок. На всём остальном от 3 (Андроид фаблеты шириной 600 dp) до 7 (1280). Ширину всех телеэкранов мы решили считать равной 960 dp (5 колонок), поэтому им подходят макеты среднего планшета. В зависимости от платформы (Android TV, tvOS, Smart TV) вёрстка просто умножается на коэффициент (скейлится) и всегда выглядит одинаково.

              У сетки по сути есть один основной параметр — минимальная ширина одной колонки и один формальный — максимальная ширина всей сетки (мы решили, что не будем заполнять контентом экраны десктопов шире 1280 pt). Запускаясь на устройстве, приложение/сайт измеряет ширину экрана/окна и считает сколько колонок в неё помещается. При расположении элементов на экране, их привязка и ширина задаётся не в хардкодных пикселях, а в колонках, вот и всё. Например промо блок вверху главной страницы ivi.ru всегда занимает все колонки и сетка сама ему передаёт нужную ширину для того или иного окна. Галерея рисует столько постеров в подборке, сколько есть колонок. А размер каждого постера берётся из текущей ширины колонки.

              Надеюсь объяснил хоть немного!)
          –1
          Это нормально?
          image
            +1
            Это сгенерированный статический код для предпросмотра компонента. Мы постепенно улучшаем эту часть системы, чтобы было лучше и красивее :)
            +1
            Figma или Sketch?: )
              0
              Sketch. Да, не всё гладко с версионностью и нет командного доступа к одному проекту, но почти весь UI подключён библиотекой, а остальное обещают скоро докатить.
                0
                да, тоже есть надежды на новые фичи Скетча, как раз на распутье сейчас.
                спасибо за статью и за сам труд по системе!
                  0

                  А что-нибудь вроде Plant или Abstract пробовали?

                    0
                    Да, примеряли Abstract и осознанно отказались. Это прилично усложняло наши процессы, а смысла поддерживать мастер-макет = продакшн мы не увидели. К тому же это ещё один сторонний инструмент, а значит зависимость от чужой технологии и её багов. Наш источник «правды» для UI — дизайн-система, для UX — продакшн. Минусы нашего подхода тоже есть. Со временем макетов становится много и найти актуальное состояние сложно. Сделают подобное в Скетче, может попробуем ещё раз.
                +1
                Очень суперская статья, круто подошли к процессу.
                По сетке я так понимаю продумали умножение на 2.
                А будете что-то делать под широкие экраны? А то куча свободного места пропадает, да и карточки кажутся мелкими.
                  0
                  Спасибо.
                  Да, для универсализации UI, вёрстка под телеэкраны умножается на различные коэффициенты, в зависимости от платформы. А на этапе дизайна мы считаем их все равными шириной в 960 pt.
                  Речь про широкие экраны веба, как я понимаю? Текущая сетка адаптируется до 1280 pt и мы пока думаем, что делать с бо́льшими размерами.
                  0
                  Хотелось бы узнать, каким набором инструментов пользуетесь для верстки, сборки всех веб-компонентов и элементов веб-дизайна. Интересно буквально все: сборщики, препроцессоры, постпроцессоры, шаблонизаторы итд. Желательно отдельный материал по теме.
                    0
                    Если коротко то:
                    Интеграция ДС на вебе: ts + nodejs.
                    сборщик стилей: grunt и gulp (да да, такая вот у нас связка, legacy код, из под grunt вызываем gulp)
                    препроцессор для стилей: less.
                    постпроцессор: postcss со стандартными модулями, autoprefixer, postcss-url, css-byebye, csso, postcss-prefixer
                    шаблонизатор вёрстки: twig, react

                    P.S. Готовим отдельный материал на эту тему
                      0
                      Очень жду. Хотелось бы, чтобы было все «от а до я». От момента, когда дизайнер нарисовал кнопочку, до того момента, когда кнопочка сверстана, протестирована и интегрирована в общую дизайн-систему.
                    0

                    Спасибо большое за статью! Есть несколько вопросов.


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

                    Вы действительно делаете это только при релизах или на каждую сборку, например для тестирования новой функциональности (возможно в рамках CI)?


                    Для генерации стилей в проекте Android мы используем Gradle, превращая данные дизайн-системы в стили формата XML.

                    Компонентные. Пишутся для каждого компонента, где описано какие свойства и как перевести в стили.

                    Вы на стороне Android генерируете только xml из стандартных виджетов фреймворка? Или у вас так же есть кастомные реализации для ваших компонент и подразумевается также java/kotlin кодогенерация?

                      +1
                      Вы действительно делаете это только при релизах или на каждую сборку, например для тестирования новой функциональности (возможно в рамках CI)?

                      Когда нам нужно что-то новое из ДС, мы мигрируем на следующую версию Json с описанием ДС.
                      Время, когда новые компоненты появлялись постоянно, прошло и сейчас это требуется раз или два в неделю. На Android эта процедура занимает пару минут, поэтому CI для этого пока не используем.

                      Вы на стороне Android генерируете только xml из стандартных виджетов фреймворка? Или у вас так же есть кастомные реализации для ваших компонент и подразумевается также java/kotlin кодогенерация?

                      У нас есть кастомные реализации для своих компонентов, но логику их работы мы прописываем сами на Kotlin. А вот стили и значения для описания их внешнего вида, мы берём из xml, который генерируется автоматически. Таким образом, у нас есть возможность достаточно гибко настраивать компоненты сначала, а потом автоматически подтягивать изменения из ДС.
                      0
                      Илья, подскажите, пожалуйста, а как у вас устроен процесс создания дизайна и верстки писем? Вам удалось стандартизировать и автоматизировать этот процесс?
                        0
                        На данный момент мы в процессе создания адаптивных шаблонов для автоматической сборки писем.
                          0
                          Круто! Мы тоже хотим к этому прийти и думаем, делать ли самописную систему или на основе плагинов stripo

                      Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                      Самое читаемое