piffy
3월 19, 2023, 11:13오후
1
사이트의 웹 바이탈, 특히 LCP를 개선하려고 합니다. 현재 LCP 시간이 약 2.7초(2.5초 미만이어야 함)로 나타나고 있습니다. Optimize Largest Contentful Paint | Articles | web.dev 에 따르면:
구체적으로 LCP는 사용자가 페이지 로드 시작부터 뷰포트 내에서 가장 큰 이미지 또는 텍스트 블록이 렌더링될 때까지의 시간을 측정합니다.
문제를 제가 작성한 배너 테마 컴포넌트로 좁혔습니다. “above-main-container” 위젯으로 마운트하는 배너 이미지가 사실상 모든 페이지에서 화면에 페인팅되는 가장 큰 객체입니다.
코드
<script type="text/discourse-plugin" version="0.8">
const h = require("virtual-dom").h;
api.createWidget("my-banner", {
tagName: "div",
html() {
return h("img.banner-center", {src: settings.banner_image, fetchpriority: "high", style: "aspect-ratio: 925 / 359 ; width: 100%"})
}
});
</script>
<script type="text/x-handlebars" data-template-name="/connectors/above-main-container/banner">
{{mount-widget widget="my-banner"}}
</script>
제 생각에는 다음과 같은 일이 일어나고 있는 것 같습니다. 이미지를 담는 div가 JS를 통해 마운트되므로, Discourse 페이지가 새로고침될 때 이 JS 코드가 실행되기까지 선행 조건들이 여러 단계로 수행되어야 합니다. 이로 인해 배너가 2.5초 이후에 가져와지며 LCP 지표에 악영향을 주고 있습니다.
코드에서 볼 수 있듯이 fetchpriority="high"를 사용하여 배너 이미지를 우선시하도록 시도했습니다. 하지만 이는 근본적인 타이밍 문제를 해결하지 못한다고 생각합니다.
이 특정 테마 컴포넌트의 렌더링을 우선시하는 방법에 대한 조언이 있을까요? 플러그인으로 전환하는 것이 더 나은 방법일까요? 배너를 가능한 한 가장 초기에 주입할 수 있는 다른 방법이 있을까요? 감사합니다!
piffy
3월 21, 2023, 8:47오후
2
아마도 내 질문이 너무 세세한 것일 수 있습니다. 혹시 답을 아시는 분이 계신다면 더 쉬운 질문을 드릴게요:
페이지가 다시 로드될 때, 플러그인에서 렌더링된 요소가 테마 컴포넌트보다 먼저 렌더링됩니까?
Falco
(Falco)
3월 21, 2023, 9:10오후
3
만약 배너가 Introducing Discourse Splash - A visual preloader displayed while site assets load 에서 사용된 요소보다 크다면, LCP(최대 콘텐츠 페인트)에서 문제가 발생할 것입니다.
주된 문제가 이미지 자산의 다운로드라고 생각되면, 테마의 HEAD 요소에 다음과 같은 코드를 추가할 수 있습니다.
<link rel="prefetch" href="http://example.com/myimage.webp" />
piffy
3월 21, 2023, 9:17오후
4
요즘 좀 고생하고 있네요 하하하
CDN으로 전환해 봤는데 효과가 없었어요. 말씀드렸듯이, 배너를 가져오는 호출이 너무 늦게 실행되는 것 같고, 실제 페치 시간의 문제는 아닌 것 같습니다. 그래도 프리페치를 시도해 보겠습니다. 차이가 있을지 한번 확인해 봐야죠!
해결책을 찾은 동안까지 임시로 로그인한 사용자만 배너를 표시하도록 했습니다. 구글은 LCP를 주로 검색 트래픽 기준으로 계산하는 것 같은데, 제 경우에는 그 트래픽이 대부분 비로그인 사용자들입니다.
Falco
(Falco)
3월 21, 2023, 9:22오후
5
LCP는 구글 크롬을 사용하는 모든 사용자, 즉 Android, Windows, MacOS, Linux 및 크롬북에서 수집됩니다.
해당 기기에서 로그인하지 않은 사용자의 페이지뷰가 로그인한 사용자보다 많다면, 네 LCP는 해당 비로그인 사용자의 성능을 반영하게 됩니다.
piffy
3월 21, 2023, 9:34오후
6
알아두면 좋겠네요.
스플래시 화면 애니메이션을 더 크게 만들면 이 문제를 우회할 수 있을까요?
Falco
(Falco)
3월 21, 2023, 9:57오후
7
이것은 매우 복잡한 문제입니다.
먼저 확인해 본 결과, 스플래시 화면은 이미 전체 화면(높이 100vh, 너비 100%)을 사용하고 있습니다.
하지만 Discourse 부팅 속도가 충분히 빠른 일부 사용자의 경우 스플래시 화면이 표시되지 않을 수 있습니다. 이 경우 LCP는 충분히 큰 요소에 의해 결정됩니다. 질문자님의 경우 배너가 해당 요소이므로, 배너에 종속됩니다.
prefetch 메타 태그를 사용해 보시고, 해당 자산이 매우 잘 최적화되어 있는지, 그리고 모든 자산이 사용자의 위치에 가까운 PoP(Edge Point of Presence)를 통해 CDN으로 전달되고 있는지 확인해 보시기 바랍니다.
piffy
3월 22, 2023, 12:00오전
9
지금쯤이면 이미 필수 기능이 된 거죠. 사용자들도 정말 좋아합니다.
piffy
3월 22, 2023, 1:47오전
11
물론 항상 줄이거나 다른 방법으로 처리할 수는 있지만, 미관을 해치지 않는 해결책을 선호합니다.
piffy
3월 22, 2023, 3:36오전
12
Falco:
이미지 에셋 다운로드가 주요 문제라고 생각되면, 테마의 HEAD 요소에 다음과 같은 코드를 추가할 수 있습니다.
<link rel="prefetch" href="http://example.com/myimage.webp" />
이 해결책을 시도해 보았지만 안타깝게도 차이가 없었습니다. sanity check를 위해 배너 이미지를 매우 작은 이미지로 교체해 보았지만 LCP에도 차이가 없었습니다. 제안해 주셔서 감사합니다.
테마 구성 요소가 페이지에 주입되는 내부 작동 방식은 정확히 알지 못하지만, 배너 구성 요소가 주입될 시점에는 이미 너무 늦은 것 같습니다. 다음으로 플러그인으로 시도해 볼 예정입니다.
piffy
4월 12, 2023, 4:54오후
13
이상적이지는 않지만 이 방법으로 잘 작동하고 있습니다.
비슷한 문제를 겪고 계신 분이 있다면 참고해 주세요.