AI가 내 WordPress 테마를 만들었다. 그 후 나는 AI가 남긴 성능 버그를 발견했다.
요약
AI를 활용해 WordPress 테마를 제작했으나, 모바일 성능 점수(Lighthouse)가 하락하는 버그가 발생했습니다. AI가 HTML 구조와 뷰포트의 공간적 관계를 오해하여 첫 번째 이미지를 히어로 이미지로 잘못 판단한 것이 원인이었습니다.
핵심 포인트
- AI는 HTML 소스 순서와 실제 시각적 레이아웃을 혼동할 수 있음
- AI 생성 코드에 대한 인간의 코드 리뷰와 성능 검증이 필수적임
- LCP 최적화를 위해 fetchpriority와 loading 속성 관리가 중요함
- 모바일 환경의 대역폭 제한과 크리티컬 패스 병목 현상 주의
저는 소위 "개발자 지망생"이라고 불리는 사람입니다. 제 주력 분야는 SEO(검색 엔진 최적화)이지만, 새로운 것을 시도하고 무언가 고장 났을 때 직접 손을 대어 해결하는 것을 좋아합니다.
프로젝트는 충분히 간단했습니다. 제가 사람들에게 계속 추천하는 90년대 고전 PC 게임들을 전문으로 다루는 WordPress 사이트를 만드는 것이었습니다. 테마를 직접 코딩하는 대신, 제가 원하는 레이아웃을 설명하고 AI에게 홈페이지 콘텐츠를 제공한 뒤, 처음부터 커스텀 테마를 만들어 달라고 요청했습니다.
공정하게 말하자면, AI는 꽤 괜찮은 결과물을 내놓았습니다. 사이트는 모바일과 데스크톱 모두 Lighthouse 점수 100/100을 기록하며 출시되었습니다. 깔끔한 HTML, 빠른 로딩 속도, 눈에 띄는 엉망인 부분도 없었습니다.
그러다 제가 홈페이지에 몇 가지 작은 콘텐츠 수정을 가한 뒤 테스트를 다시 실행했더니, 모바일 점수가 89점으로 떨어졌습니다. 데스크톱은 여전히 깔끔하게 100점을 유지했습니다.
이것은 심오한 성능 전쟁 이야기는 아닙니다. 해결 방법은 단 하나의 이미지 속성(attribute)을 수정하는 것이었습니다. 하지만 그 속성이 왜 잘못된 위치에 들어가게 되었는지를 살펴보면, 왜 AI가 생성한 코드에 여전히 인간의 코드 리뷰(code review)가 필요한지에 대해 많은 것을 시사합니다.
증상: 시각적 우선순위 vs DOM 순서
데스크톱 점수는 완벽한데 모바일 점수가 89점이라는 것은 전형적인 스로틀링(throttling) 동작입니다. 빠른 데스크톱 연결은 PageSpeed의 시뮬레이션된 4G 및 중급 사양의 모바일 하드웨어가 즉각적으로 드러내는 크리티컬 패스(critical path) 병목 현상을 쉽게 가려버립니다. 점수 하락은 특정 에셋(asset)이 초기 대역폭을 불필요하게 점유하며 경쟁하고 있음을 나타냈습니다.
모바일 보고서는 LCP(Largest Contentful Paint) 경로에 있는 이미지 하나를 정확히 지목했습니다. 바로 Disney의 Aladdin 스크린샷이었습니다.
그것은 이상한 점이었습니다. 왜냐하면 그 이미지는 초기 화면에 보이지 않기 때문입니다. 홈페이지는 약 25행에 달하는 거대한 게임 데이터 테이블과 함께 열리며, 실제 레이아웃은 bestclassicpcgames.com에서 확인할 수 있습니다. 모바일 뷰포트(viewport)에서 해당 테이블은 화면을 완전히 차지하며 실제 게임 섹션들을 폴드(fold) 아래 깊숙이 밀어냅니다. Aladdin 스크린샷은 소스 코드상에서는 첫 번째 이미지이지만, 시각적으로는 초기 뷰포트 근처에도 없습니다.
버그: 단순한 휴리스틱(Heuristic)
테마 템플릿을 확인해 보니 문제가 드러났습니다:
<img src="..." alt="Aladdin video game" width="800" height="450" fetchpriority="high">
코드는 유효하지만, 가정이 틀렸습니다. AI는 단순한 휴리스틱 (Heuristic)에 의존했습니다. 즉, HTML 소스 코드의 첫 번째 이미지 태그가 히어로 이미지 (Hero image)일 것이라고 가정했습니다.
표준적인 블로그 레이아웃에서는 그 논리가 보통 통합니다. 하지만 뷰포트 계층 구조 (Viewport hierarchy)를 변경하는 거대한 HTML 테이블에 대한 공간적 인식 (Spatial awareness)이 부족했기 때문에, AI는 모바일 브라우저가 숨겨진 에셋 (Asset)을 다운로드하느라 제한된 초기 대역폭을 낭비하도록 강제했습니다.
해결책은 즉각적이었습니다:
<img src="..." alt="Aladdin video game" width="800" height="450" loading="lazy">
캐시 유령 쫓기 (Chasing the Cache Ghost)
코드 업데이트는 정확했지만, 첫 번째 재테스트 결과는 여전히 89점을 기록했고 렌더링된 소스에는 fetchpriority="high"가 표시되었습니다.
저는 환상적인 최적화 레이어, WordPress 필터, 또는 플러그인 충돌을 찾느라 20분을 허비한 후에야 제가 서버 측 캐시 (Server-side cache)에 의해 가스라이팅을 당하고 있었다는 사실을 깨달았습니다. 템플릿은 이미 수정되었지만, 캐싱 레이어는 수정 전의 HTML을 즐겁게 서빙하고 있었습니다.
캐시를 제대로 비우고 나자 문제가 사라졌습니다. 모바일 점수는 LCP (Largest Contentful Paint) 1.0초와 함께 안정적인 100점으로 돌아왔습니다. 이는 유용한 교훈을 주었습니다. 성능 저하 (Performance regression)를 추적하기 전에, 테스트 도구가 실제로 당신이 변경한 코드를 보고 있는지 확인해야 한다는 점입니다.
AI 테마 감사를 위한 시사점
여기서 AI가 "실패"한 것은 아닙니다. 단순히 소스 순서에 기반하여 합리적인 추측을 했을 뿐입니다. 하지만 AI는 렌더링된 페이지에 대한 시각적 및 문맥적 인식 (Contextual awareness)이 부족하기 때문에, 기술적으로는 결함이 없지만 당신의 에셋 전달 전략을 완전히 뒤엎는 코드를 작성할 수 있습니다.
만약 테마나 컴포넌트의 스캐폴딩 (Scaffolding)을 위해 LLM을 사용하고 있다면, 리뷰 파이프라인에 간단한 전역 grep 과정을 추가하세요:
fetchpriority및loading="lazy"감사 (Audit): DOM 순서가 아닌 실제 뷰포트 계층 구조 (Viewport hierarchy)를 기준으로 이를 검증하세요. 무거운 레이아웃 요소, 데이터 테이블 또는 히어로 슬라이더 (Hero sliders) 아래에 묻혀 있는 이미지를 주의 깊게 살펴보세요.- 테스트 환경 격리: 디버깅 중 발생하는 패닉을 방지하기 위해, 항상 서버 캐싱 레이어 (Server caching layers)를 퍼지 (Purge)하고 깨끗한 상태에서 테스트하여 오래된 코드를 감사하는 일을 피하세요.
AI가 생성한 코드는 배포하기에 충분히 깔끔하지만, 그 구조적 가정 (Structural assumptions)이 실제와 일치하는지 확인하기 위해서는 여전히 인간의 검증이 필요합니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기