Lighthouse 42점에서 98점으로—성능 수치보다 더 중요한 것

Lighthouse 42점에서 98점으로—성능 수치보다 더 중요한 것

WebGL 랜딩페이지 삽질기와 React 컴포넌트 재사용 전략이 함께 가리키는 것—프론트엔드 품질은 도구가 아니라 '문제를 먼저 보는 습관'에서 시작된다.

Lighthouse 최적화 Core Web Vitals WebGL 성능 LCP React 컴포넌트 JSON-LD Framer Motion 프론트엔드 품질
광고

시각적으로 완벽한 페이지가 Lighthouse에서 42점을 받는 이유

"페이지가 예쁘게 보인다"와 "페이지가 잘 동작한다"는 완전히 다른 명제다. dev.to에 공유된 한 개발자의 B2B 3D 랜딩페이지 삽질기가 이 간극을 정확히 짚는다. WebGL 기반 산업용 3D 모델을 품은 페이지, 시각적으로는 흠잡을 데 없었지만 Lighthouse를 돌리는 순간 42/100이라는 점수가 떴다.

문제는 하나가 아니었다. 폰트 웨이트 과잉 로딩, <head> 안에 박힌 300KB WebGL 스크립트, preconnect 태그 전무, 히어로 이미지에 잘못 적용된 loading="lazy", 그리고 가장 치명적인—Particle.js 애니메이션이 <script type="application/ld+json"> 블록에 콜백 코드를 주입해 JSON-LD를 오염시킨 버그. 마지막 케이스는 브라우저 콘솔에 에러 한 줄 없이, Google Search Console이 3개월 동안 조용히 리치 스니펫 인덱싱을 중단했다. 시각적 완성도는 성능 지표와 무관하다는 사실을 가장 잔인한 방식으로 증명한 사례다.

각 문제가 '비(非)명백'했던 이유

다섯 가지 이슈 중 절반 이상이 "당연히 알겠지"라고 생각하기 쉬운 영역에서 터졌다는 점이 핵심이다. 폰트 웨이트 8개를 로딩하는 건 디자이너 요청에 따라 자연스럽게 추가되고, <head>에 스크립트를 두는 건 관성적인 습관이며, 히어로 이미지에 loading="lazy"를 적용하는 건 "모든 이미지에 레이지 로딩"이라는 좋은 의도의 부작용이다. JSON-LD 오염은 JavaScript 런타임 타이밍 이슈와 SEO 구조 데이터가 교차하는 지점—대부분의 프론트엔드 개발자가 평소에 동시에 주시하지 않는 두 영역의 충돌이었다.

수정 결과는 명확하다. 폰트 웨이트를 400;600;700 세 가지로 줄여 약 400ms를 절약하고, type="module" 속성으로 WebGL 스크립트를 자동 defer 처리하고, preconnect 태그를 추가하고, 히어로 이미지에 fetchpriority="high"를 부여하자 점수는 98/100까지 올랐다. 이 개발자는 이후 동일한 문제가 반복되지 않도록 Python CLI web-performance-surgeon을 직접 만들어 오픈소스로 공개했다—문제를 경험한 사람이 도구를 만들 때 그 도구가 가장 날카롭다.

컴포넌트 재사용 전략도 같은 문제에서 출발한다

성능 최적화와 별개처럼 보이지만, React 컴포넌트 설계에서도 동일한 패턴이 반복된다. dev.to의 또 다른 글에서 소개된 React Vibe—Framer Motion과 Tailwind 기반의 copy-paste 친화적 컴포넌트 라이브러리—는 "매 프로젝트마다 navbar, hero section, 기본 애니메이션을 다시 짜는 것에 지쳤다"는 개발자의 좌절에서 시작됐다.

두 케이스의 공통점은 명확하다. 문제가 먼저, 도구는 그 다음이다. Lighthouse 점수를 높이기 위해 Python CLI를 짠 것도, 반복 빌드를 줄이기 위해 컴포넌트 라이브러리를 만든 것도—둘 다 실제로 고통을 겪은 후에 나온 솔루션이다. 사용자 문제가 아닌 기술적 흥미에서 출발한 도구는 종종 쓰이지 않는다.

React Vibe가 흥미로운 지점은 "라이브러리를 설치하라"가 아니라 "복사해서 붙여넣어라"는 철학이다. Framer Motion과 Tailwind가 이미 세팅되어 있다면 추가 의존성 없이 30개 이상의 컴포넌트를 바로 쓸 수 있다. 이는 shadcn/ui가 대중화시킨 소유 기반 컴포넌트 전략의 연장선—패키지에 종속되지 않고 코드를 직접 소유하며 원하는 대로 수정할 수 있는 구조다. 디자인 시스템을 "완성된 라이브러리"가 아니라 "살아있는 실험 단위"로 바라보는 관점과 자연스럽게 맞닿는다.

프론트엔드 품질의 공통 문법

두 방향의 이야기를 하나로 엮으면 이런 명제가 남는다. Core Web Vitals 최적화와 컴포넌트 설계 전략은 모두 '반복되는 고통의 패턴 인식'에서 출발한다. LCP를 망치는 loading="lazy" 히어로 이미지, 매번 새로 짜는 navbar—둘 다 개발자가 한 번씩은 만나고 지나쳐버리는 문제들이다. 차이는 그 패턴을 시스템화하느냐, 아니면 다음 프로젝트에서 또 반복하느냐에 있다.

흥미롭게도 AI 도구가 이 간극을 좁히고 있다. 반복적인 컴포넌트 스캐폴딩이나 성능 이슈 탐지처럼 패턴이 명확한 작업일수록 자동화 가능성이 높다. web-performance-surgeon이 HTML을 파싱해 렌더 블로킹 자원을 찾아내듯, AI 기반 정적 분석 도구가 코드베이스에서 LCP 병목이나 잘못된 lazy loading 패턴을 사전에 감지하는 워크플로우는 이미 현실이다.

지금 당장 점검할 것들

이 두 사례가 주는 실천적 시사점은 간단하다. 다음 프로젝트를 시작하기 전에, 혹은 기존 프로젝트를 배포하기 전에 세 가지를 먼저 확인하라.

첫째, 히어로 이미지에 fetchpriority="high"가 붙어있는가. LCP는 대부분 히어로 이미지가 결정한다. 둘째, 외부 도메인(폰트, CDN, API)에 preconnect가 선언되어 있는가. 도메인당 DNS 조회 + TLS 핸드셰이크 비용은 눈에 보이지 않지만 체감 성능을 크게 잡아먹는다. 셋째, JavaScript 런타임이 <script type="application/ld+json"> 블록에 접근할 경로가 없는가. SEO 구조 데이터 오염은 콘솔 에러도, 시각적 변화도 없이 조용히 인덱싱을 죽인다.

컴포넌트 측면에서는 "이 코드를 다음 프로젝트에서 또 짤 것인가"를 스스로에게 물어보는 습관이 출발점이다. 그 답이 '아마도'라면, 지금이 추출할 타이밍이다.

프론트엔드 품질은 최신 프레임워크나 번들러 설정의 문제가 아닌 경우가 많다. 42점짜리 페이지를 98점으로 만든 수정 사항들은 모두 2010년대에도 알려져 있던 베스트 프랙티스였다. 문제는 도구의 부재가 아니라, 문제를 먼저 보는 습관의 부재다. 좋은 도구는 그 습관을 가진 사람이 지쳐서 만들어낸다.

출처

더 많은 AI 트렌드를 Seedora 앱에서 확인하세요