웹킷에서 렌더링할 때 이모지 문제 - HTML 렌더링 방식 관련 문제

Apple 기기 및/또는 WebKit 기반 브라우저를 사용하는 많은 사용자들이 토픽을 스크롤할 때 포럼이 사용 불가능할 정도로 문제가 발생한다고 보고하고 있습니다.

여기에서 촬영된 영상 예시를 참고할 수 있습니다.

제대로 된 조사를 해본 결과, 가장 유력한 원인은 WebKit이 이미지 리사이징을 처리하는 방식이… 어떻게 표현할까… 쓰레기 수준이라는 점인 것 같습니다.

하지만 이 과정에서 쿠크된 HTML(cooked html)에서 이모지가 어떻게 렌더링되는지도 알게 되었고, 제가 설정을 놓치고 있어서 이런 문제를 방지할 수 있었을 수도 있으니 명확한 설명이 필요합니다.

초록색으로 표시된 부분은 이모지의 원래 크기입니다.

청록색(azure/cyan/어떤 색이든)으로 표시된 부분은 Discourse가 콘텐츠를 쿠크할 때 기본적으로 추가하는 속성입니다.

빨간색으로 표시된 부분은 제가 작성한 플러그인이 추가한 CSS로, 다음과 같은 역할을 합니다:

  • 이모지를 가져옵니다(이모지가 꽤 많습니다).
  • 모든 이모지가 “20 x 20” 크기가 아니기 때문에 올바르게 렌더링되도록 커스텀 CSS를 추가합니다.

그리고 저는 간단한 테스트를 수행했습니다. 해당 토픽의 DB 내 cooked 필드에서 모든 width="20" height="20" 속성을 제거하고, 사용자들이 다시 토픽을 확인하고 스크롤하며, 새 게시글을 추가하는 사람이 있어도 이모지를 사용하지 않도록 하여 렌더링된 이모지 HTML에 해당 두 속성이 다시 주입되지 않도록 요청했습니다.

어떤가, WebKit에서 문제를 일으키는 원인이 바로 그것인 것 같습니다. 해당 두 속성이 제거된 후 스크롤링에 문제가 없다는 것을 제가 가진 모든 보고가 확인하고 있습니다.

그러면, Discourse가 이 파라미터들을 추가하는 것을 방지하는 방법이 있을까요? 왜 Discourse는 모든 이모지가 "20x20"일 것이라고 가정하며, 게다가 CSS를 사용하는 대신 HTML 속성으로 이를 강제하는 것일까요?

감사합니다

저는 iPad에서는 재현할 수 있었지만, 데스크톱 Chrome에서는 재현하지 못했습니다.

위쪽으로 스크롤하면 타임라인이 이전 게시물로 돌아가서, 그 게시물을 넘겨서 더 위로 스크롤하기가 어렵습니다.

하지만 일관되게 재현하기가 어렵습니다. 1955번 게시물에서 막혔었는데, 그 게시물을 넘겨서 위로 스크롤한 후에는 다시 아래로 내려가서 위로 스크롤해도 막히지 않았습니다 :thinking:

그 이유는 새로운 이모지가 "레이지 로딩(lazy loading)"될 때마다 size 속성이 렌더링되기 때문입니다.

렌더링이 완료된 후에는 문제가 발생하지 않습니다. 하지만 답글이 많고 이모지가 꽤 많이 사용되는 토픽을 보면, 이 동작이 계속 반복되는 것을 확인할 수 있으며, 이로 인해 Discourse를 사용하는 것이 불가능해집니다.

저희는 커스텀 테마에서 이를 "수정"했지만, 기본 테마에서도 이 문제를 해결해야 한다고 생각합니다. 더 나아가, 게시물을 쿡(cook)하는 함수에서 처리하는 것이 더 좋겠습니다. 단순한 CSS를 사용하는 대신 size 관련 HTML 속성이 적용될 이유는 보이지 않기 때문입니다.

iOS의 모든 브라우저가 WebKit을 사용하는 것 같으므로, 이 문제는 주로 Apple 기기에서 발생할 것입니다. 이 분야 전문가가 아니므로 이 내용은 참고용으로만 봐 주십시오. 추가 테스트가 필요합니다.

1개의 좋아요

표준화된 유니코드 이모지는 모두 정사각형에 맞춰져야 하도록 설계되어 있기 때문입니다. 그리고 우리는 웹사이트들이 텍스트나 다른 이모지와 함께 사용할 때 일관된 크기를 유지하기를 원한다고 가정합니다. :teapot: 만약 이 찻주전자가 50x50이었다면, 이 줄과 같은 줄 사이에 거대한 간격이 생겼을 것입니다:

처음 추가되었을 당시의 좋은 설명이 있습니다:

그리고 Multimedia: Images - Learn web development | MDN 의 지원 세부 사항:

이미지의 width와 height 속성이 HTML <img> 요소에 포함되면, 브라우저는 이미지가 로드되기 전에 이미지의 종횡비를 계산할 수 있습니다. 이 종횡비는 이미지를 표시하는 데 필요한 공간을 예약하는 데 사용되며, 이미지가 다운로드되어 화면에 그려질 때 레이아웃 시프트를 줄이거나 심지어 방지합니다. 레이아웃 시프트를 줄이는 것은 좋은 사용자 경험과 웹 성능의 주요 구성 요소입니다.

…

지난 10년간의 개발자 모범 사례에서는 종횡비 매핑 때문에 HTML <img> 요소에서 이미지의 width와 height 속성을 생략하는 것을 권장했을 수 있지만, 현재 이러한 두 속성을 포함하는 것이 개발자 모범 사례로 간주됩니다.

그럼에도 불구하고, 모든 이모지에 대해 기본 크기가 작동하지 않는 경우의 합리적인 예를 들었습니다… 그 오래된 cheers 이모지는 3배 더 넓어서 정사각형에 잘 맞지 않습니다. 다른 앱들이 모든 이모지를 정사각형으로 제한하는 것은 드문 일이 아니므로, 우리의 행동은 그렇게 특이하지 않습니다(예를 들어 Slack과 Discord도 그렇게 합니다)… 하지만 대안적으로, 사용자 정의 이모지에 대해 선택적으로 차원을 설정할 수 있도록 고려할 수 있습니다.

2개의 좋아요

CSS 측면에서는 쉽게 구현할 수 있습니다:

img.emoji {
  width: auto; /* width: 20px; 대체 */
  height: 20px;
  vertical-align: text-bottom;
}

(설명에 대해서는 DEV: add native lazy loading for emojis - Pull Request #15830#issuecomment-1031587082 - discourse/discourse - GitHub 참조.)

더 어려운 작업은 “사용자 정의 이모지” 부분과 이모지 렌더링입니다:

  • 사용자 정의 이모지에는 각 이모지마다 추가 속성이 필요합니다: aspect-ratio(또는 대안으로 height와 width).
  • 이모지 렌더링은 사용자 정의 이모지에 대해 새로운 속성 aspect-ratio를 사용하여 width를 그에 맞게 변경해야 합니다 – height는 20px로 유지됩니다.

사용자 정의 이모지를 위한 빠르고 쉬운 접근 방식:
사용자 정의 이모지의 img 태그에는 height="20"만 설정하고 width는 전혀 설정하지 않습니다 – 이를 통해 aspect-ratio/width 및 height 설정의 이점을 포기하게 됩니다.
CSS: img.emoji { width: auto; }

2개의 좋아요