goodchuck 블로그

Lighthouse 성능 59점이 다시 재니 94점 — 점수가 흔들리는 이유와 애드센스가 권장 사항을 79점에 묶는 이유

7분 읽기

애드센스 재심사를 앞두고 운영 중인 블로그를 Lighthouse 로 재 봤습니다. 그런데 글 페이지 하나가 성능 59점이 나왔습니다. 첫 화면이 뜨는 데 6.9초라는 결과였습니다. 다시 재니 같은 페이지가 94점이었습니다.

결론부터 적으면 이렇습니다.

  • 59점은 측정이 흔들린 것이었습니다. 코드를 하나도 안 바꾸고 다시 재니 94점이 나왔습니다.
  • 권장 사항(Best Practices) 79점은 애드센스 때문입니다. 광고 스크립트가 쓰는 제3자 쿠키라서, 광고를 켜 두는 한 고칠 수 없습니다.
  • 실제로 고칠 건 색 대비 하나였습니다.

이 글은 그 판단을 어떻게 내렸는지, 숫자를 그대로 옮긴 기록입니다. Lighthouse 12.6.1, 모바일 기본 설정(모의 측정) 기준입니다.

어떻게 쟀나 — npx 한 줄로 운영 주소를 잰다

설치 없이 npx 로 바로 돌렸습니다. 결과는 JSON 으로 받아서 필요한 값만 뽑아 봤습니다.

npx lighthouse https://www.yangtinomad.com/ \
  --quiet --chrome-flags="--headless=new" \
  --only-categories=performance,accessibility,best-practices,seo \
  --output=json --output-path=lh-home.json

JSON 에서 볼 곳은 두 군데입니다.

  • categories — 네 항목 점수(0~1, 100을 곱해 봅니다)
  • audits — 항목별 진단. 점수가 0.9 아래인 것만 걸러 보면 무엇이 깎였는지 바로 보입니다

결과는 이랬습니다.

페이지성능접근성권장 사항SEO
홈959679100
글 A (첫 측정)5910079100
글 A (다시 측정)9410079100
글 B9610079100

59점은 왜 나왔나 — 같은 코드로 다시 재니 94점이었다

첫 측정의 숫자는 이랬습니다.

지표첫 측정다시 측정
First Contentful Paint6.9초2.0초
Largest Contentful Paint8.8초2.9초
Total Blocking Time20ms—
Cumulative Layout Shift00

largest-contentful-paint-element 진단을 보면 가장 큰 요소는 글 제목(h1) 이었고, 시간은 이렇게 나뉘었습니다.

구간시간비율
TTFB (서버 첫 응답)613ms7%
Render Delay (그리기 지연)8,170ms93%

서버 응답은 빨랐는데, 받은 뒤 제목 글자를 그리기까지 8초가 걸렸다는 뜻입니다.

처음엔 글꼴을 의심했습니다

이 블로그는 한글 글꼴(Pretendard)을 글자 묶음별로 쪼개 받는 방식(동적 서브셋)을 씁니다. 제목에 한글이 많으면 여러 조각을 받아야 하니, 글꼴을 다 받을 때까지 제목이 안 보이는 것 아닌가 싶었습니다.

그런데 CSS 를 열어 보니 92개 @font-face 가 전부 font-display: swap 이었습니다. swap 은 글꼴이 오기 전에도 기본 글꼴로 먼저 글자를 그리고, 도착하면 바꿔 끼우는 설정입니다. 글꼴 때문에 제목이 8초 동안 안 보였다고 보기는 어려웠습니다.

그래서 여러 번 쟀습니다

같은 페이지를 다시 재니 94점, 비슷한 다른 글은 96점이었습니다. 코드가 같은데 점수가 35점 차이 나는 건, 페이지 문제라기보다 측정이 흔들린 것으로 봤습니다.

Lighthouse 의 모바일 측정은 실제로 느린 폰을 쓰는 게 아니라, 빠른 컴퓨터에서 받은 기록으로 "느린 폰과 느린 네트워크라면 이랬을 것"을 계산(모의 측정) 합니다. 광고 · 분석 스크립트처럼 매번 다르게 받아지는 것이 섞이면 그 계산이 크게 달라질 수 있습니다. 그래서 점수 하나만 보고 판단하지 않고, 두세 번 재서 비슷하게 나오는 값을 기준으로 삼는 게 안전합니다.

권장 사항은 왜 79점인가 — 애드센스의 제3자 쿠키

네 페이지 모두 권장 사항이 정확히 79점이었습니다. 깎인 항목은 둘이었습니다.

  • Uses third-party cookies — 애드센스 광고 요청(googleads.g.doubleclick.net)이 제3자 쿠키를 씁니다.
  • Issues were logged in the Issues panel — 브라우저 개발자 도구의 Issues 패널에 경고가 기록됐다는 항목입니다. 어떤 경고인지까지는 이번에 열어 보지 않았지만, 같은 측정에서 우리 코드 쪽 오류는 따로 잡히지 않았습니다.

제3자 쿠키는 광고 스크립트가 하는 일이라 우리 코드에서 고칠 방법이 없습니다. 애드센스를 켜 둔 사이트라면 같은 항목으로 깎일 것입니다. 이 블로그는 광고 스크립트를 운영에서만 켜기 때문에, 로컬이나 미리보기에서 재면 이 항목은 나오지 않을 것입니다(운영에서만 켜는 방법).

안 쓰는 JS 253KB 는 누구 것인가 — 대부분 광고와 분석

성능 진단에 "Reduce unused JavaScript — 253KB 절약 가능"이 떴습니다. 파일별로 보면 이렇습니다.

파일전체안 쓰는 양
애드센스 광고 스크립트 (show_ads_impl)169KB123KB
GA4 (gtag/js)181KB76KB
애드센스 로더 (adsbygoogle.js)57KB30KB
이 블로그의 JS 묶음 하나73KB29KB

253KB 중 약 230KB 가 광고와 분석 스크립트입니다. 이 블로그의 코드는 29KB 정도였습니다. 정적으로 굽는 블로그라 브라우저로 가는 우리 JS 는 원래 적습니다.

같은 맥락의 제안이 두 가지 더 있었습니다.

  • preconnect — 광고 · 분석 서버(googleads.g.doubleclick.net 353ms, google-analytics.com 312ms, pagead2.googlesyndication.com 177ms)에 미리 연결해 두라는 제안
  • 캐시 정책 — 애드센스 스크립트와 Vercel 방문 통계 스크립트의 캐시 시간이 짧다는 경고

전부 바깥 서비스가 정하는 것이라 그대로 두었습니다. 성능 점수는 이미 94~96점이라, 광고 스크립트를 더 뒤로 미루는 식의 손질은 애드센스 확인 크롤러가 스크립트를 못 볼 위험만 키운다고 판단했습니다.

실제로 고친 것 — 색 대비 2.72:1

접근성에서 홈만 96점이었습니다. 원인은 하나였습니다.

Element has insufficient color contrast of 2.72
(foreground color: #616972, background color: #23262b, font size: 9.8pt (13px))

홈 카테고리 탭 옆의 글 수 숫자였습니다. 안 고른 탭은 글자가 이미 흐린 색인데, 숫자에 opacity-60 을 한 번 더 걸어서 배경과 거의 구분이 안 됐습니다. 작은 글자의 대비 기준은 4.5:1 입니다.

// 전: 안 고른 탭 숫자를 한 번 더 흐리게
<span className={`text-[13px] font-medium ${t.on ? 'opacity-70' : 'opacity-60'}`}>{t.count}</span>

// 후: 안 고른 탭은 원래의 흐린 글자색 그대로
<span className={`text-[13px] font-medium ${t.on ? 'opacity-70' : ''}`}>{t.count}</span>

디자인을 "조금 더 은은하게" 하려고 투명도를 겹치면, 이미 흐린 색 위에서 기준 아래로 쉽게 떨어집니다. 흐린 글자색이 있으면 그 위에 투명도를 또 얹지 않는 게 안전합니다.

정리 — 고칠 것과 둘 것

진단원인판단
성능 59점 (한 번)모의 측정의 흔들림다시 재서 94~96 확인, 둠
권장 사항 79점애드센스 제3자 쿠키광고를 켜는 한 고칠 수 없음, 둠
안 쓰는 JS 253KB대부분 애드센스 · GA4바깥 스크립트, 둠
preconnect · 캐시 정책광고 · 분석 서버바깥 설정, 둠
접근성 색 대비 2.72:1흐린 글자에 투명도 겹침고침
SEO—모든 페이지 100

Lighthouse 는 진단을 많이 내놓지만, 전부 고칠 대상은 아닙니다. 여러 번 재서 확인하고, 내 코드에서 나온 것만 고치는 순서로 보니, 이번엔 고칠 게 한 줄뿐이었습니다. 이 측정은 모의 측정이라, 실제 방문자 기기에서 잰 값(Search Console 의 Core Web Vitals)은 방문이 쌓인 뒤 따로 확인할 생각입니다.