Привет Хабр! Друзья, зовут меня Данил, я web-разработчик в МегаФоне. Работаю над системой обработки обращений наших пользователей.
Расскажу о том, как я, пытаясь внедрить emoji в проект, напугал наших пользователей. Какие подводные камни вас ждут, если вы хотите использовать emoji и почему вам стоит тестировать проект не только в “вакууме”.
Для меня это первая статья, постараюсь написать все доходчиво и интересно. Enjoy!
Немного о себе
Как уже сказал, зовут меня Данил, и я web-разработчик, родом из Кудымкара, маленького коми-пермяцкого городка, сейчас живу и работаю в Самаре. Я развиваю интерфейс системы DARM.
Поскольку МегаФон - компания огромная, обрабатывать необходимо огромный поток обращений с разных каналов. Вот, как мы решаем эту задачу:
на данный момент поддерживаем 5 каналов (VK, приложение МегаФона, наш сайт, почта и СМС);
система омниканальна, то есть юзер может начать общение в приложении, продолжить на сайте, а оператор это увидит и беспроблемно продолжит беседу, не отходя от кассы.
История Emoji
Давайте, погрузимся немного в историю emoji, чтобы понимать с чем мы имеем дело.
Разница между Emoticons и Emoji
Эмотиконы (смайлик) - это комбинация символов, пиктограмма, изображающая эмоцию, созданная из разных типографских знаков.
В Японии свои эмотиконы, их называют каомодзи (с японского kao - «лицо», а moji - «знак, иероглиф») - они отличаются повышенной сложностью и декоративностью.
Emoji - это конкретные идеограммы, заложенные в стандарт Unicode. Для передачи эмоции с улыбающимся лицом понадобится специальный эмодзи, а если использовать эмотиконы, то у нас есть бесконечное количество вариантов, которые ограничиваются лишь фантазией.
Короче говоря, emoticon - это набор символов, а эмодзи - готовая картинка.
Первое появление Emoji
Самый первый набор эмодзи придумал в 1999 году Сигетака Курита. Он разработал его для японского телефонного оператора NTT DoCoMo. Всего он нарисовал 176 эмоджи размером 12×12 пикселей, обозначающие людей, места и предметы. Как планировал Курита, это был набор «символов, которые передавали весь спектр человеческих эмоций».
Из-за того, что это был внутренний стандарт оператора 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 выглядят по-разному и могут по-разному интерпретироваться.
Вот пример, кричащее от страха желтое лицо, эмоджи предназначенное для обозначения ужаса и испуга. У Apple и Google, выглядят они похоже, всё более-менее хорошо, а у Samsung, эммм, тут что-то пошло не так, персонаж не ужаснулся, а уже похоже испустил дух. У Microsoft персонаж просто кричит кому-то в даль.
Вот так различаются инопланетяне. У Samsung больше похоже на осьминога.
Все-таки хочется, чтобы эмоджи в проекте были одинаковые вне зависимости от среды выполнения, чтобы не было никаких конфликтов, да и просто интерфейс выглядел приятно. И как это сделать?! ???????? Расскажу об этом чуть позже... А сейчас вернемся к нашей задаче.
Что у нас?
Мы знали, что наши пользователи сидят только на windows, так как система внутренняя, поэтому решили использовать системный шрифт, который для нас был вполне сносным.
В итоге наша клавиатура выглядела вот так:
Почему так произошло?
Всему виной была другая версия windows использовавшаяся на клиентах операторов. Операторы работают через VDI (удаленный рабочий стол), где использовалась windows server 2012, по сути, это windows 8. В windows 8 ещё не было цветного emoji шрифта, такой шрифт появился только в windows 8.1, до этого использовался символьный шрифт.
Вот для сравнения emoji из шрифта SegoeUI Symbol из windows 8 и Noto Color Emolji от гугла.
Ну, и в историю стрёмных эмодзи. Вот такое забавное недопонимание дизайнеров я нашел пока искал материал для этой статьи - это легендарное волосатое сердце из android 4.4.
Какие есть решения?
И так, теперь обсудим решения. Изучив подобные темы в сети, мы пришли к варианту, заменить на клиенте emoji заранее нарисованными картинками. Как это можно сделать?
Для начала, давайте разберемся, как их лучше хранить, мы нашли два варианта:
Отдельный файл для каждого emoji:
Сохраняем все emoji в отдельные картинки разных размеров, и тогда получается идея доступа к emoji такая: /64/U_1f60d.png. Принцип класть файлы картинок в папки для разных размеров, а для названия файлов используем номер emoji, в Unicode.
Плюсы
Загружаются только необходимые emoji, не грузим ничего лишнего.
Минусы:
Сильно забивается сеть большим количеством запросов, а это очень страшно. Например, из-за этого у нас могут встать на паузу какие-то другие более важные запросы (контентные картинки, скрипты или основные шрифты).
Бандл файл для всех 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?
Комментарии (10)
Squoworode
18.01.2022 08:58+3Волосатое сердце
Читал я как-то раз в интернете, что в античные времена этот символ обозначал ягодицы...
staticmain
18.01.2022 09:21+8Наши пользователи (операторы), постоянно стараются как-нибудь оживить диалог с клиентом, найти с ним общий язык и emoji для этого подходят прекрасно. Без них сейчас не обходится ни одна беседа. ????
Каждый раз когда официальная техподдержка шлет мне смайлики на той стороне представляются 12-летние дети, которые у мамы телефон украли.
devlev
18.01.2022 10:54+1Чем обоснован ваш выбор в пользу PNG, вместо более современного формата для вектороной графики SVG?
Вы проверяли как выглядет ваши смайлики на ретина дисплеях?
Делаете запас по пикселям для ретина дисплеев? (к примеру картинка 64px показывается как 32px)
И какое максимальное разрешение сохраняете для больших эмоджи? (у вас на скрине большой эмоджи в чате без другого текста)
danilkinkin Автор
18.01.2022 11:41Векторная графика довольно ограничена с точки зрения стиля. Хотя эмодзи которые мы используем с некоторыми ограничениями возможно отрисовать в векторе. В основном наш выбор был обусловлен тем, что мы нашли готовый атлас эмодзи (мы используем эмодзи от google)
Но в принципе, если вектор позволяет реализовать все ваши хотелки, то можно использовать svg
JustDont
18.01.2022 14:16+1Да, тоже хотел поднять этот вопрос. Так-то у svg огромное количество преимуществ:
- однозначно будет меньше весить, эмодзи "виндового" стиля — меньше чем 32px растр
- можно однократно внедрить на страницу через <symbol>, а потом использовать сколько угодно раз
Но конечно если нашли готовый растровый атлас и не нашли векторного — то добывать где-то вектор будет не очень оправдано.
Насчет ограничения на стили рисовки — я б поспорил. Насколько я знаю, все текущие растровые атласы эмодзи ничего особенного не требуют, максимум — цветовые градиенты (в которые svg прекрасно может). Другое дело, что "навороченные" смайлы в svg могут очень существенно вырасти в размерах, я где-то видел усеченный набор эппловских смайлов в векторе, и оно по размерам вплотную приближалось к 64px растровым иконкам этих же смайлов.
mskotyn
19.01.2022 07:47А теперь включаем мозг и задумываемся, что же на самом деле видят абоненты с их зоопарком платформ-приложений-настоек, если косяки вылезли даже при развертывании в контролируемом окружении рабочего места оператора.
Mabu
19.01.2022 09:57Я на своём компьютере привык видеть эмоджи так, как они настроены у меня в системе.
Зачем мне переучиваться и видеть эмоджи так, как они выглядят на вашем компьютере?
Evengard
Кхм. Вообще-то существует третий способ. Он геморройный, но он вполне валидный, а главное наиболее близкий к "нативному".
Использовать таки ttf-шрифт и подгружать его через @font-face.
Но там есть своих особенностей куча. Например, Windows поддерживает только emoji закодированные в COLR/CPAL, Linux и Android - SVG и COLR/CPAL, тогда как Apple системы - в SVG либо вообще в своём SBIX формате.
danilkinkin Автор
Я про это упомялу как раз на примере NotoColoEmoji.ttf. Но на текущий момент использовать в проде такой способ практически не возможно, так как весит такой шрифт очень много, например выше упомянутый около 10мб. Но впринципе можно порезать шрифт (вырезать из него неиспользуемые символы), но не уверен насколько это легально
Evengard
В принципе twemoji в COLR/CPAL формате весит 6 мб в ttf, и 2 мб в woff2, что конечно многовато, но уже не настолько. Как плюс - истинно векторные эмодзи и "нативное" использование без js.
Плюс на самом деле они загружаются один раз и дальше попадают в кэш браузера, так что не так всё фатально в плане размера.