Привет Хабр! Друзья, зовут меня Данил, я web-разработчик в МегаФоне. Работаю над системой обработки обращений наших пользователей.

Расскажу о том, как я, пытаясь внедрить emoji в проект, напугал наших пользователей. Какие подводные камни вас ждут, если вы хотите использовать emoji и почему вам стоит тестировать проект не только в “вакууме”. 

Для меня это первая статья, постараюсь написать все доходчиво и интересно. Enjoy! 

Немного о себе

Как уже сказал, зовут меня Данил, и я web-разработчик, родом из Кудымкара, маленького коми-пермяцкого городка, сейчас живу и работаю в Самаре. Я развиваю интерфейс системы DARM.

DARM - тот самый сервис для обработки обращений клиентов. Мы сами разработали его с учетом наших потребностей.

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

  • на данный момент поддерживаем 5 каналов (VK, приложение МегаФона, наш сайт, почта и СМС);

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

История Emoji

Давайте, погрузимся немного в историю emoji, чтобы понимать с чем мы имеем дело.

Разница между Emoticons и Emoji

Слева emoticon, справа emoji.

Эмотиконы (смайлик) - это комбинация символов, пиктограмма, изображающая эмоцию, созданная из разных типографских знаков.

В Японии свои эмотиконы, их называют каомодзи (с японского kao - «лицо», а moji - «знак, иероглиф») - они отличаются повышенной сложностью и декоративностью.

Тост
Даёт монетку

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

Короче говоря, emoticon - это набор символов, а эмодзи - готовая картинка.

Первое появление Emoji

Самый первый набор эмодзи придумал в 1999 году Сигетака Курита. Он разработал его для японского телефонного оператора NTT DoCoMo. Всего он нарисовал 176 эмоджи размером 12×12 пикселей, обозначающие людей, места и предметы. Как планировал Курита, это был набор «символов, которые передавали весь спектр человеческих эмоций».

Набор первых Emoji.

Из-за того, что это был внутренний стандарт оператора NTT DoCoMo, отправлять и получать такие emoji могли только клиенты этого оператора. Спустя время другие компании тоже начали делать свои emoji и ими так могли пользоваться только пользователи в рамках конкретной системы. Не было возможности передавать их между клиентами разных компаний. И только в 6 версии unicode (2010 год), emoji включили в стандарт. Теперь появилась возможность передавать emoji между системами, и их популярность стала стремительно расти.

Магия emoji

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

Комбинированные эмодзи, такие, как семья, обозначающие профессии и прочее, на самом деле представляют собой комбинации более простых эмодзи, с соединительными символами нулевой ширины ZWJ (Zero-width joiner, U+200D) между ними. Таким образом получаются разные наборы семей, профессий, флагов стран, а также эмодзи с разными цветами кожи.

От истории к проблемам задачам

Наши пользователи (операторы), постоянно стараются как-нибудь оживить диалог с клиентом, найти с ним общий язык и emoji для этого подходят прекрасно. Без них сейчас не обходится ни одна беседа. ? Перед тем как мы начали добавлять клавиатуру, нам рассказали, что операторы использовали вордовский документ, где у них были заготовлены некоторые emoji. При необходимости они копировали emoji и вставляли в поле ввода. Мы были очень удивлены этому и решили, что пора сделать клавиатуру. И, как ни странно, эта задача не так тривиальна, как кажется.

Emoji - это картинки, и значит, что весят они прилично. Так как emoji - это стандарт unicode, значит с ними можно делать шрифты. В каждой системе есть встроенный шрифт с emoji. Также есть другие шрифты с эмоджи, от сторонних шрифтовых дизайнеров, которые не установлены в систему по умолчанию. При желании можно даже подключить их на страницу как обычные шрифты, но весить они могут ~10мб, а это очень много, ОЧЕНЬ МНОГО.

Размер шрифта с emoji от Google

Размер шрифта с emoji от Google

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

Разные значения одинаковых emoji

Вот пример, кричащее от страха желтое лицо, эмоджи предназначенное для обозначения ужаса и испуга. У Apple и Google, выглядят они похоже, всё более-менее хорошо, а у Samsung, эммм, тут что-то пошло не так, персонаж не ужаснулся, а уже похоже испустил дух. У Microsoft персонаж просто кричит кому-то в даль.

Разные значения одинаковых emoji

Вот так различаются инопланетяне. У Samsung больше похоже на осьминога.

Все-таки хочется, чтобы эмоджи в проекте были одинаковые вне зависимости от среды выполнения, чтобы не было никаких конфликтов, да и просто интерфейс выглядел приятно. И как это сделать?! ?‍? Расскажу об этом чуть позже... А сейчас вернемся к нашей задаче.

Что у нас?

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

Emoji на Windows 10

В итоге наша клавиатура выглядела вот так:

Скриншот клавиатуры у нас
Скриншот клавиатуры у операторов

Почему так произошло?

Всему виной была другая версия windows использовавшаяся на клиентах операторов. Операторы работают через VDI (удаленный рабочий стол), где использовалась windows server 2012, по сути, это windows 8. В windows 8 ещё не было цветного emoji шрифта, такой шрифт появился только в windows 8.1, до этого использовался символьный шрифт.

Разница между симбольными emoji из windows 8 и emoji android

Вот для сравнения emoji из шрифта SegoeUI Symbol из windows 8 и Noto Color Emolji от гугла.

Ну, и в историю стрёмных эмодзи. Вот такое забавное недопонимание дизайнеров я нашел пока искал материал для этой статьи - это легендарное волосатое сердце из android 4.4.

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

Какие есть решения?

И так, теперь обсудим решения. Изучив подобные темы в сети, мы пришли к варианту, заменить на клиенте emoji заранее нарисованными картинками. Как это можно сделать?

Для начала, давайте разберемся, как их лучше хранить, мы нашли два варианта:

  1. Отдельный файл для каждого emoji:

Сохраняем все emoji в отдельные картинки разных размеров, и тогда получается идея доступа к emoji такая: /64/U_1f60d.png. Принцип класть файлы картинок в папки для разных размеров, а для названия файлов используем номер emoji, в Unicode.

Плюсы

  • Загружаются только необходимые emoji, не грузим ничего лишнего.

Минусы:

  • Сильно забивается сеть большим количеством запросов, а это очень страшно. Например, из-за этого у нас могут встать на паузу какие-то другие более важные запросы (контентные картинки, скрипты или основные шрифты).

  1. Бандл файл для всех emoji:

Склеиваем все emoji одного размера в большую картинку. Тогда у нас получится несколько картинок: 64.png, 128.png и т.д. Тут название файла - это разрешение emoji. Размер от шрифта отличается кардинально, для обычного текста хватает размера в 20px, он весит 500кб.

Плюсы:

  • Загружаются сразу все emoji определённого размера.

  • Загрузка делается одним запросом, и если потребуется другой emoji такого же размера, то повторной загрузки не потребуется.

Минусы:

  • Грузятся лишние emoji которые возможно не будут использоваться, гоняем лишний трафик.

  • Тут нам понадобится еще один файл для разметки бандла, чтобы понять в каком месте, какой emoji (можно автоматизировать через сборщики по типу webpack`а).

Дальше через RegeXp мы находим все emoji в тексте и заменяем их.

На что заменять есть тоже два варианта:

1. span обёртка

Этот вариант подразумевает оборачивать каждый emoji тегом span и вставлять нашу картинку, как фоновое изображение. Если у нас не найдется замены, то как fallback значение отрисуется нативный emoji.

<span
    aria-label="?, partying_face"
    style="
        width: 22px;
        height: 22px;
        vertical-align: middle;
        display: inline-block;
        background-image: url(https://example.com/static/emoji/20/U_1F973.png);
        color: transparent;
    "
>
    ?
</span>

так, либо так:

<span
    aria-label="?, partying_face"
    style="
        width: 22px;
        height: 22px;
        vertical-align: middle;
        display: inline-block;
        background-image: url(https://example.com/static/emoji/20.png);
        background-size: 5700% 5700%;
        background-position: 67.8571% 80.3571%;
        color: transparent;
    "
>
    ?
</span>

Плюсы:

  • Корректно работает выделение текста.

Минусы:

  • При выделении проглядывается нативный emoji.

2. img

Этот вариант подразумевает заменять все emoji тегом img и через alt прописывать нативный emoji. Тут с fallback всё так же.

<img
    src="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=="
    alt="?"
    draggable="false"
    style="
        vertical-align: middle;
        cursor: text;
        display: inline-block;
        background-image: url(https://example.com/static/emoji/64.png);
        background-position: 75% 10.7143%;
        background-size: 5700% 5700%;
        height: 22px;
        width: 22px;
    "
>

так, либо так:

<img
    src="https://example.com/static/emoji/20.png"
    alt="?"
    draggable="false"
    style="
        vertical-align: middle;
        cursor: text;
        display: inline-block;
        height: 22px;
        width: 22px;
    "
>

Плюсы:

  • В коде выглядит чище.

Минусы:

  • Если использовать вариант с бандлом emoji, то картинку придется вставлять через background, а в src вставлять заглушку.

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

Итоговая клавиатура.

Как мы смогли бы предотвратить проблему?

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

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

Итоги и советы:

  • Собирайте метрики разрешений экранов, где используется ваша система, потом можно взять диапазон самых популярных разрешений, это поможет понять вам где и как используется ваш продукт. А также учесть это в тестировании, и в последующей отрисовке макетов. Например, вы рисуете основные макеты для FullHD экранов, а ваша система используется на терминалах с экранами 4х3, в итоге получается лишняя работа и потеря потенциала.

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

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

Поделитесь в комментариях вашим опытом общения с операторами и использования emoji? Или вам достаточно слов и caps lock?