Проблема с эмодзи при рендеринге в Webkit — проблема с отображением HTML

У нас много пользователей с устройствами Apple и/или браузерами на базе WebKit, которые сообщают о проблемах при прокрутке тем, из-за чего форум становится непригодным для использования.

Пример, записанный на видео здесь.

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

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

На зелёном фоне показан исходный размер эмодзи.

На голубом/циановом/каком-то другом фоне — атрибуты по умолчанию, добавляемые Discourse при обработке контента.

На красном фоне — CSS, добавляемый моим плагином, который:

  • импортирует эмодзи (их довольно много)
  • добавляет кастомный CSS для их корректного отображения, так как они не все имеют размер «20 на 20»

Теперь я провёл простой тест. Из поля cooked в базе данных для этой темы я удалил все атрибуты width="20" height="20" и попросил пользователей снова попробовать открыть тему, прокручивать её, отвечать, даже если кто-то добавляет новые сообщения, но без использования эмодзи, чтобы не добавлять снова эти два атрибута в рендеримый HTML эмодзи.

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

Так вот, есть ли способ предотвратить добавление Discourse этих параметров? Почему Discourse предполагает, что каждый эмодзи будет размером «20x20», и, кроме того, принудительно устанавливает это через HTML-атрибуты вместо использования CSS?

Спасибо.

Мне удалось воспроизвести это на iPad, но не на Chrome для рабочего стола.

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

Однако мне трудно воспроизвести это стабильно. Я застрял на сообщении #1955, но после того, как мне удалось прокрутить вверх мимо него, если я возвращался вниз и снова прокручивал вверх, оно больше не блокировало меня :thinking:

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

После рендеринга проблема исчезает. Однако, если вы пролистываете тему с множеством ответов, где эмодзи используются довольно часто, вы постоянно будете наблюдать это поведение, что сделает использование Discourse невозможным.

Нам удалось «исправить» это в нашей пользовательской теме, но, на мой взгляд, это должно быть устранено и в теме по умолчанию, а ещё лучше — в функции, которая обрабатывает посты, поскольку я не вижу причин применять эти HTML-атрибуты, связанные с размером, вместо использования простого CSS.

Добавлю, что все браузеры для iOS, по-видимому, используют WebKit, поэтому проблема будет актуальна в основном для устройств Apple. Я не эксперт в этой области, поэтому относитесь к этому с долей скептицизма. Потребуется дополнительное тестирование.

1 лайк

Это потому, что все стандартизированные эмодзи Unicode предназначены для размещения в квадрате, и мы предполагаем, что сайты хотят, чтобы их эмодзи были одинакового размера и гармонично сочетались с текстом и другими эмодзи :teapot: если этот чайник был бы размером 50x50, это создало бы огромные пробелы между строками, как здесь:

Хорошее объяснение было дано при первоначальном добавлении:

С дополнительными деталями из Multimedia: Images - Learn web development | MDN

Когда атрибуты width и height изображения включены в HTML-элемент <img>, браузер может вычислить соотношение сторон изображения до его загрузки. Это соотношение сторон используется для резервирования пространства, необходимого для отображения изображения, что уменьшает или даже предотвращает смещение макета при загрузке и отрисовке изображения на экране. Снижение смещения макета является важным компонентом хорошего пользовательского опыта и производительности веб-сайтов.

Хотя лучшие практики разработчиков за последнее десятилетие могли рекомендовать опускать атрибуты width и height изображения в HTML-элементе <img> из-за сопоставления соотношения сторон, включение этих двух атрибутов считается лучшей практикой разработчика.

Тем не менее, у вас есть разумный пример случая, когда размер по умолчанию не подходит для всех эмодзи… этот старый эмодзи «cheers» в три раза шире, поэтому он не помещается красиво в квадрат. Не редкость, когда другие приложения ограничивают все эмодзи квадратами, поэтому наше поведение здесь не слишком необычно (например, это делают и Slack, и Discord)… но альтернативно мы могли бы рассмотреть возможность разрешения для пользовательских эмодзи опционально задавать размеры.

2 лайка

Со стороны CSS это легко реализовать:

img.emoji {
  width: auto; /* замена width: 20px; */
  height: 20px;
  vertical-align: text-bottom;
}

(См. объяснение на DEV: add native lazy loading for emojis by rr-it · Pull Request #15830 · discourse/discourse · GitHub)

Более сложная часть работы связана с «пользовательскими эмодзи» и их отображением:

  • для каждого пользовательского эмодзи нужен дополнительный атрибут: aspect-ratio (или в качестве альтернативы height и width).
  • отображение эмодзи должно использовать новый атрибут aspect-ratio для пользовательских эмодзи, чтобы соответствующим образом изменять width — при этом height остаётся равным 20px.

Быстрый и простой подход для пользовательских эмодзи:
Для тегов img пользовательских эмодзи устанавливайте только height="20" и не указывайте width вообще — тем самым отказываясь от преимущества задания соотношения сторон/ширины и высоты.
CSS: img.emoji { width: auto; }

2 лайка