목록으로
KRDS · 공공웹 AI 진단연구

공공웹 Core Web Vitals 실측 — LCP·INP·CLS, 브라우저가 직접 재는 성능의 언어

공공 웹사이트를 점검하다 보면 꼭 나오는 피드백이 있다. "이 사이트 좀 느린 것 같은데요." 그 말은 틀리지 않는다. 실제로 화면이 늦게 뜨고, 버튼을 눌러도 반응이 없고, 스크롤하면 레이아웃이 갑자기 흔들린다. 문제는 "느린 것 같다"는 말이 보고서에는 쓸 수 없다는 것이다. 담당자가 외주 개발사에 개선을 요청하려면

VViewCheck Insight
·2026.07.20 5분 31
공공웹 Core Web Vitals 실측 — LCP·INP·CLS, 브라우저가 직접 재는 성능의 언어

"빠른 사이트"와 "느린 사이트"의 차이를 숫자로 잡으려 할 때, 우리가 만난 세 가지 지표


들어가며 — "느리다"는 말은 측정이 아니다

공공 웹사이트를 점검하다 보면 꼭 나오는 피드백이 있다. "이 사이트 좀 느린 것 같은데요." 그 말은 틀리지 않는다. 실제로 화면이 늦게 뜨고, 버튼을 눌러도 반응이 없고, 스크롤하면 레이아웃이 갑자기 흔들린다. 문제는 "느린 것 같다"는 말이 보고서에는 쓸 수 없다는 것이다. 담당자가 외주 개발사에 개선을 요청하려면 수치가 필요하다. "어디가 얼마나 느린지"를 숫자로 말해야, 무엇을 어떻게 고쳐야 하는지를 논의할 수 있다.

그래서 우리는 ViewCheck를 만들며 웹 성능을 '숫자로 재는 방법'을 꽤 오래 들여다봤다. 그 과정에서 가장 자주, 가장 깊이 다루게 된 게 Core Web Vitals라는 세 가지 지표다. Google이 2020년부터 공식화한 이 지표들은 이제 웹 성능을 이야기할 때 사실상의 공용어가 됐다. LCP(최대 콘텐츠풀 페인트), INP(다음 페인트까지의 상호작용), CLS(누적 레이아웃 이동) — 이 세 글자 조합이 이 글 내내 등장한다.

다만 미리 말해두고 싶은 게 있다. Core Web Vitals는 좋은 지표이지만 '전부'는 아니다. 이 세 가지를 잘 통과해도 사이트가 훌륭한 건 아닐 수 있고, 세 가지 중 하나가 좋지 않아도 사용자가 특별히 불편함을 느끼지 않는 상황도 있다. 지표는 현실의 일부를 수치로 잘라낸 것이지, 현실 전체는 아니다. 그 전제 위에서, "이 지표들이 무엇을 재고, ViewCheck는 어떻게 수집하며, 공공 웹사이트에 적용할 때 어떤 점을 주의하는가"를 솔직하게 적어보겠다.

두 개의 모니터에 페이지 속도 게이지 대시보드를 띄워두고 집중해서 보는 한국인 개발자.
듀얼 모니터에 속도 게이지 대시보드를 집중해서 바라보는 개발자. "느리다"는 직감을 숫자로 바꾸는 일이 성능 점검의 시작이다.

Core Web Vitals란 무엇인가 — Google이 정의한 세 가지 축

Core Web Vitals는 Google이 실제 사용자 경험을 측정하기 위해 정의한 웹 성능 지표 묶음이다. 2020년에 처음 공식화됐고, 이후 Google 검색 랭킹 신호에 포함되면서 업계 표준처럼 자리 잡았다. 핵심은 "실제 사용자가 느끼는 것"을 숫자로 잡는다는 점이다. 서버 로그나 개발자 도구의 합성 테스트(synthetic test)만으로는 잡히지 않는, 실제 방문자의 브라우저에서 일어나는 일을 측정한다.

현재(2025년 기준) Core Web Vitals의 세 가지 지표는 다음과 같다.

  1. LCP (Largest Contentful Paint, 최대 콘텐츠풀 페인트) — 로딩 성능
  2. INP (Interaction to Next Paint, 다음 페인트까지의 상호작용) — 상호작용 반응성
  3. CLS (Cumulative Layout Shift, 누적 레이아웃 이동) — 시각적 안정성

이 세 가지는 각각 다른 사용자 불만을 수치로 잡는다. "왜 이렇게 늦게 뜨지?"(LCP), "버튼을 눌렀는데 왜 반응이 없지?"(INP), "갑자기 레이아웃이 왜 흔들리지?"(CLS) — 이 세 가지 불평이 숫자로 변한 것이다.

Google web.dev 공식 문서는 Core Web Vitals를 이렇게 정리한다. "Core Web Vitals는 실제 사용자 경험의 뚜렷한 측면을 측정하는 유효하고 현장 측정 가능한 사용자 중심 결과를 나타낸다. 각각은 로딩(LCP), 상호작용(INP), 시각적 안정성(CLS)이라는 웹 사용 경험의 고유한 측면을 측정한다."(Google, "Web Vitals", web.dev, 2024)

왜 이 세 가지인가

성능 지표라고 하면 수십 가지를 나열할 수 있다. TTFB(Time to First Byte), FCP(First Contentful Paint), TTI(Time to Interactive), TBT(Total Blocking Time)… Google이 이 많은 지표 중에서 특별히 세 가지를 'Core'로 묶은 이유가 있다.

Google은 Core Web Vitals 임계값이 어떻게 정해졌는지를 별도 문서로 공개한 적 있다. 핵심 원칙은 두 가지다. 첫째, 사용자 연구에 기반해야 한다. 수백만 건의 실제 사용 데이터를 분석해, "이 수치 이하일 때 사용자가 경험을 '좋다'고 느끼는" 경계를 찾았다. 둘째, 75백분위수로 평가한다. 사이트 방문의 75%가 기준을 충족할 때 '통과'로 인정한다. 극소수의 최상위 사용자나 극소수의 최하위 사용자가 아니라, 대다수의 실제 방문자를 기준으로 삼겠다는 뜻이다.(Google, "How the Core Web Vitals metrics thresholds were defined", web.dev)

그리고 이 세 가지가 선택된 이유는, 측정 가능한 것과 사용자가 실제로 불편을 느끼는 것 사이의 교집합이 이 세 영역에서 가장 뚜렷했기 때문이다. 이론적으로 중요한 지표가 아니라, 실제 데이터에서 사용자 행동에 영향을 미치는 것으로 확인된 지표들이다.


LCP — "언제 봤다고 할 수 있는가"를 재는 지표

정의: 뷰포트 안에 가장 큰 콘텐츠가 렌더링된 시점

LCP는 페이지가 로딩을 시작한 시점부터, 뷰포트(화면에 보이는 영역) 안에서 가장 큰 이미지 또는 텍스트 블록이 렌더링된 시점까지의 시간이다. Google web.dev의 정의를 그대로 옮기면 이렇다. "LCP는 뷰포트 내에서 가장 큰 이미지 또는 텍스트 블록이 렌더링된 시점을 로딩 성능의 기준으로 삼는다. 빠른 LCP는 그 페이지가 유용하다고 사용자에게 확신을 준다."(Google, "Largest Contentful Paint (LCP)", web.dev)

여기서 '가장 큰'의 기준은 픽셀 면적이다. 뷰포트 안에서 가장 큰 면적을 차지하는 요소가 LCP 후보가 된다. 일반적으로 히어로 이미지, 배너 이미지, 헤딩 텍스트 블록이 이 자리를 차지한다.

임계값: 2.5초가 '좋음'의 경계

LCP 임계값은 세 구간으로 나뉜다.

구간 기준 의미
좋음(Good) 2.5초 이하 로딩이 충분히 빠름
개선 필요(Needs Improvement) 2.5초 초과 ~ 4.0초 이하 개선 권고 대상
나쁨(Poor) 4.0초 초과 사용자 이탈 위험 높음

이 기준은 75백분위수로 적용된다. 즉, 사이트에 방문하는 100명 중 75명이 2.5초 이내에 LCP를 경험해야 '좋음'으로 분류된다.

공공 웹사이트에서 LCP를 가장 많이 잡아먹는 것은 주로 두 가지다. 메인 배너 이미지서버 응답 시간이다. 공공 사이트의 메인 화면에는 대형 이미지 슬라이드가 흔하다. 이 이미지가 크고 압축이 안 되어 있으면, 이미지가 다운로드 완료되는 시점이 LCP가 된다. 그리고 공공 기관 서버의 응답 속도가 느리면, 서버가 HTML을 보내주기도 전에 이미 LCP 시계가 많이 달려 있는 상태가 된다.

ViewCheck가 LCP를 측정할 때, 우리는 Playwright(실제 브라우저)로 페이지를 렌더링한다. 개발자 도구나 PageSpeed Insights의 Lighthouse가 하는 것처럼 합성 환경에서 재는 것이 아니라, 실제 브라우저 환경에서 PerformanceObserver API를 통해 LCP 이벤트가 발생하는 시점을 직접 캡처한다. 이렇게 해야 "사용자가 실제로 경험하는 시간"에 더 가까운 값을 얻을 수 있다. 완전히 동일하진 않지만, 랩 테스트(합성) 와 필드 데이터(실제) 사이의 간극을 줄이려는 시도다.

LCP가 느린 공공 사이트의 전형적인 패턴

우리가 여러 공공 사이트를 분석하면서 반복해서 발견하는 패턴이 있다. 공개된 데이터는 아니고 우리 분석 경험에서 나온 관찰이라는 점을 먼저 밝힌다.

첫 번째 패턴은 미압축 배너 이미지다. 메인 히어로 영역에 1920×600px 이상의 이미지를 WebP 대신 PNG/JPEG 원본으로 올려두는 경우가 많다. 이 이미지가 LCP 요소가 되면, 파일 크기 하나가 전체 LCP 값을 결정하게 된다. 2~3MB짜리 이미지가 LCP 후보라면 2.5초 이내 달성은 쉽지 않다.

두 번째 패턴은 render-blocking 리소스다. 헤더에서 대형 CSS 파일이나 동기적으로 로드되는 JavaScript가 브라우저의 렌더링 자체를 막는 경우다. 브라우저가 렌더링을 시작하기도 전에 기다려야 하니, LCP 시계는 그만큼 늦어진다.

세 번째 패턴은 느린 서버 응답이다. TTFB(Time to First Byte)가 800ms를 넘는 경우, 이 시간이 LCP에 그대로 가산된다. 서버가 느리면 아무리 프론트엔드 최적화를 해도 LCP 개선에는 한계가 있다.

이 세 가지 패턴을 알아두면, ViewCheck의 분석 결과에서 "LCP 나쁨"이 뜰 때 어디서부터 살펴봐야 할지 방향을 잡을 수 있다.


INP — FID를 대체한 새 지표, "반응했는가"를 재는 방식

2024년 3월, FID는 역사 속으로

Core Web Vitals 역사에서 꽤 중요한 사건이 2024년 3월에 있었다. 상호작용 반응성을 재는 기존 지표 **FID(First Input Delay, 첫 번째 입력 지연)**가 공식적으로 폐기되고, **INP(Interaction to Next Paint, 다음 페인트까지의 상호작용)**가 그 자리를 대체했다.

Google은 2024년 3월 12일, INP가 공식 Core Web Vital이 됐음을 발표했다. "2024년 3월 12일부로, Interaction to Next Paint(INP)가 First Input Delay(FID)를 대체하는 공식 Core Web Vital이 됐습니다."(Google, "Interaction to Next Paint becomes a Core Web Vital on March 12", web.dev, 2024. 3.)

왜 바꿨을까? FID는 사용자가 처음으로 클릭하거나 탭하는 등 첫 번째 입력을 했을 때의 지연만 잡았다. 그런데 현실에서 사용자가 느끼는 "답답함"은 첫 번째 클릭뿐 아니라, 페이지를 사용하는 내내 발생한다. 폼을 입력하고, 버튼을 누르고, 드롭다운을 열고, 스크롤 중간에 탭을 전환하는 — 이 모든 상호작용에서 반응이 느리면 불만이 쌓인다. FID는 그 전체 그림을 잡지 못했다.

INP는 다르다. 사용자가 페이지와 상호작용하는 모든 클릭·탭·키보드 입력을 관찰하고, 그 중 가장 오래 걸린(혹은 거의 가장 오래 걸린) 지연을 단일 값으로 보고한다. 페이지를 통틀어 가장 나쁜 상호작용 경험이 INP 값이 되는 셈이다.

임계값: 200ms가 '좋음'의 경계

INP 임계값도 세 구간이다.

구간 기준 의미
좋음(Good) 200ms 이하 상호작용이 즉각적으로 느껴짐
개선 필요(Needs Improvement) 200ms 초과 ~ 500ms 이하 사용자가 지연을 느끼기 시작
나쁨(Poor) 500ms 초과 명확하게 느린 것으로 인식됨

Google web.dev는 200ms 기준의 배경을 이렇게 설명한다. "페이지의 INP가 '좋음' 임계값(200밀리초 이하)에 해당한다면, 그 페이지는 사용자의 상호작용에 신뢰할 수 있을 만큼 반응한다고 할 수 있다."(Google, "Interaction to Next Paint (INP)", web.dev)

200ms는 인간의 지각 한계와 관련이 있다. 심리학과 HCI 연구에 따르면, 약 100ms 이내의 반응은 사용자가 "즉각적"으로 느끼고, 100~300ms는 "약간의 지연"을 인식하지만 대개 허용 가능한 수준이며, 그 이상부터는 "느리다"는 인식이 쌓인다. 200ms는 "좋음"과 "괜찮음"의 경계에 잡힌 셈이다.

INP가 공공 사이트에서 왜 어려운가

공공 웹사이트에서 INP 개선이 유독 까다로운 이유가 있다. 첫째, 무거운 자바스크립트다. 공공 사이트 중 상당수는 레거시 코드, 오래된 플러그인, 통계 수집 스크립트, 공공기관 인증 모듈 등이 겹겹이 쌓여 있다. 이 스크립트들이 메인 스레드를 점유하면, 사용자의 클릭이 들어왔을 때 브라우저가 그 클릭을 처리하기 전에 다른 작업을 먼저 끝내야 해서 지연이 생긴다.

둘째, 파일 다운로드·업로드 버튼이다. 공공 사이트에는 서식 다운로드, 민원 신청서 제출 같은 파일 입출력이 많다. 이 버튼을 눌렀을 때의 응답이 느리면, 그 지연이 INP를 끌어내린다.

셋째, 모바일 환경이다. 공공 사이트는 데스크탑에서 개발·테스트되는 경우가 많은데, 실제 사용자의 상당수는 스마트폰으로 접속한다. 모바일 CPU는 데스크탑보다 연산 능력이 훨씬 제한적이라, 같은 자바스크립트라도 처리 시간이 훨씬 길어진다. INP는 모바일과 데스크탑을 구분해서 측정하므로, 모바일 INP가 나쁜 사이트가 생각보다 많다.

노트북 옆에 놓인 스톱워치의 클로즈업. 웹페이지 로딩 성능의 시간적 측면을 상징한다.
200ms, 500ms — INP는 밀리초 단위의 반응성을 잡는다. 스톱워치처럼 정밀하게.

ViewCheck가 INP를 측정하는 방식도 Playwright 기반이다. 다만 INP는 실제 사용자 상호작용이 있어야 측정된다. 순수한 필드 데이터(Chrome UX Report, 이하 CrUX)에서는 실제 방문자의 클릭·탭 데이터가 집계되지만, 합성 환경(Playwright)에서는 클릭 시뮬레이션으로 근사값을 얻는 데 한계가 있다. 그래서 ViewCheck에서 INP는 "측정 가능한 범위 내의 참고 값"으로 제공하며, 정밀한 INP 데이터는 실제 사용자 데이터(CrUX)나 Lighthouse CI 파이프라인과 병행해서 보는 게 더 정확하다. 이 한계는 솔직하게 인정하고 있다.


CLS — 레이아웃이 흔들리지 않는가를 재는 지표

정의: 예기치 않은 레이아웃 이동의 누적값

CLS는 체감상 가장 "별로인" 경험 중 하나를 잡는다. 페이지를 읽고 있는데 갑자기 텍스트가 밀려 내려가거나, 클릭하려던 버튼이 순간 이동해서 엉뚱한 것을 눌러버리거나, 이미지가 뒤늦게 로드되면서 전체 레이아웃이 아래로 밀리거나 — 이런 예기치 않은 레이아웃 이동을 점수로 누적한 것이 CLS다.

Google web.dev의 정의를 그대로 옮기면 이렇다. "Cumulative Layout Shift(CLS)는 중요한 사용자 중심 지표로, 시각적 안정성을 측정하는 데 유용하다. 사용자가 예기치 않은 레이아웃 이동을 얼마나 자주 경험하는지를 수치화하는 데 도움을 준다. CLS가 낮다는 것은 페이지가 안정적임을 보장한다."(Google, "Cumulative Layout Shift (CLS)", web.dev)

CLS는 점수 형태다. 픽셀 크기 × 이동 거리를 기반으로 계산된 무차원 값이다. 숫자 자체보다는 "기준 이하인가 이상인가"로 해석하는 게 실용적이다.

임계값: 0.1 이하가 '좋음'

구간 기준 의미
좋음(Good) 0.1 이하 레이아웃이 시각적으로 안정적
개선 필요(Needs Improvement) 0.1 초과 ~ 0.25 이하 개선 권고
나쁨(Poor) 0.25 초과 사용자가 뚜렷하게 불쾌함을 느낌

Google이 0.1을 기준으로 정한 배경도 사용자 연구에서 나왔다. "내부 테스트에서 0.15 이상의 이동은 일관되게 방해가 된다고 인식됐고, 0.1 이하의 이동은 눈에 띄지만 과도하게 방해가 되지는 않았다."(Google, "How the Core Web Vitals metrics thresholds were defined", web.dev) 0이 이상적이지만 0.1까지는 '좋음'으로 인정하겠다는 것이다.

공공 사이트에서 CLS가 나빠지는 주요 원인

공공 웹사이트에서 CLS를 해치는 패턴도 반복된다.

크기 없는 이미지가 대표적이다. <img> 태그에 widthheight 속성이 없으면, 브라우저는 이미지가 다운로드될 때까지 그 크기를 모른다. 이미지가 로드되면서 그 자리를 차지하기 위해 아래 콘텐츠가 밀려나고, 이것이 CLS로 잡힌다.

늦게 로드되는 광고·위젯도 흔한 원인이다. 공공 사이트에는 SNS 공유 버튼, 날씨 위젯, 팝업 배너 등이 붙어 있는 경우가 많다. 이런 서드파티 요소가 비동기로 나중에 로드되면서 자리를 차지하면 CLS가 올라간다.

웹폰트 렌더링도 주의할 지점이다. 공공 사이트 중 일부는 자체 서버에서 웹폰트를 제공하는데, 폰트 파일이 늦게 도착하면 브라우저가 먼저 대체 폰트(fallback)로 텍스트를 그렸다가 나중에 교체한다. 이 교체 과정에서 텍스트 크기가 달라지면 레이아웃이 흔들린다.

ViewCheck는 Playwright로 페이지를 렌더링할 때 PerformanceObserver의 layout-shift 엔트리를 직접 수집해 CLS를 계산한다. 이 때 중요한 건 세션 창(session window) 기반 계산이다. 2021년 이전의 CLS 계산 방식은 페이지 수명 전체에 걸친 모든 이동을 단순 누적했는데, 이렇게 하면 오래 열어둔 페이지(뉴스 피드, 무한 스크롤)가 지나치게 불리해진다. 현재의 CLS는 세션 창(최대 5초, 갭 1초)을 기준으로 계산해 이 문제를 보정한다. ViewCheck도 이 방식을 따른다.


TTFB와 FCP — Core Web Vitals는 아니지만, 함께 봐야 하는 지표들

Core Web Vitals는 LCP·INP·CLS 세 가지지만, 웹 성능을 이야기할 때 이 셋만 보면 그림이 좁아진다. 특히 공공 사이트의 맥락에서 함께 봐야 하는 두 가지를 짚어두고 싶다.

TTFB (Time to First Byte, 첫 번째 바이트까지의 시간)

TTFB는 사용자의 브라우저가 서버에 요청을 보내고 서버가 첫 번째 바이트를 응답하기까지의 시간이다. "서버가 얼마나 빨리 응답하는가"의 지표다. Core Web Vital은 아니지만, TTFB가 나쁘면 그 위에 있는 모든 지표가 나빠질 수밖에 없다. 서버가 응답을 늦게 보내면, 브라우저가 HTML을 받기까지 기다려야 하고, 그 대기 시간이 LCP에도 더해진다.

Google web.dev에 따르면 TTFB의 '좋음' 기준은 0.8초(800ms) 이하다. 0.8초 초과~1.8초는 개선 필요, 1.8초 초과는 나쁨이다.(Google, "Time to First Byte (TTFB)", web.dev) 공공 사이트 중 일부는 서버 인프라 문제나 CDN 미적용으로 TTFB가 2초를 넘는 경우도 있다. 이런 경우 아무리 이미지를 최적화해도 LCP 개선에는 한계가 있다. ViewCheck는 Playwright의 응답 타이밍 API를 통해 TTFB를 측정하고, SSE로 프론트엔드에 전달한다.

FCP (First Contentful Paint, 첫 번째 콘텐츠풀 페인트)

FCP는 사용자가 브라우저에서 어떤 콘텐츠든 처음으로 보이기 시작하는 시점이다. 흰 화면 → 글자나 이미지가 처음 뜨는 그 순간이다. LCP가 "주요 콘텐츠가 뜨는 시점"이라면, FCP는 그 전에 "뭔가 시작됐음을 알 수 있는 시점"이다. 흰 화면만 보고 기다리는 사용자의 불안감을 줄이는 데 FCP가 관련되어 있다.

FCP의 '좋음' 기준은 1.8초 이하다. FCP도 Core Web Vital은 아니지만, FCP가 늦으면 사용자는 사이트가 동작하지 않는다고 오해하기 쉽다. 공공 사이트에서 "사이트 접속이 안 되는 것 같다"는 민원의 상당수는 실제로 응답이 없는 게 아니라 FCP가 너무 늦어서 발생하는 경우다.

ViewCheck는 LCP·INP·CLS를 주요 Core Web Vitals로 보고하는 동시에, TTFB와 FCP도 부가 지표로 함께 측정·표시한다. "이 두 지표가 나쁘면 Core Web Vitals도 나빠질 가능성이 높다"는 인과 관계를 함께 보여주는 게 실무에서 더 유용하기 때문이다.


측정 방법의 두 가지 갈래 — 랩 데이터 vs 필드 데이터

Core Web Vitals를 이야기할 때 반드시 짚어야 하는 구분이 있다. **랩 데이터(Lab Data)**와 **필드 데이터(Field Data)**다.

랩 데이터: 통제된 환경의 합성 측정

랩 데이터는 Lighthouse, PageSpeed Insights 같은 도구가 제공하는 수치다. 고정된 CPU 성능, 고정된 네트워크 속도, 시뮬레이션된 환경에서 한 번 측정한 값이다. 재현 가능하고, 비교하기 쉽고, 배포 파이프라인에 자동화하기 편하다. 그러나 실제 사용자의 기기 성능·네트워크 환경·사용 패턴과는 차이가 있다.

필드 데이터: 실제 사용자의 브라우저에서 수집

필드 데이터는 실제 사용자의 Chrome 브라우저에서 수집된다. Google의 Chrome UX Report(CrUX)가 대표적이다. 수백만 명의 실제 방문자가 경험한 값을 집계하므로, "실제 사용자가 느끼는 성능"에 가장 가깝다. Google Search Console의 Core Web Vitals 보고서가 CrUX 기반이다. 다만 방문 수가 충분하지 않으면 CrUX 데이터가 없을 수도 있고, 데이터가 수집되기까지 시간이 걸린다.

ViewCheck의 접근: 두 방법의 결합

ViewCheck는 기본적으로 Playwright를 이용한 합성 측정(랩 데이터에 가까운)을 수행한다. 매 분석 시 실제 브라우저를 돌려 PerformanceObserver로 LCP·CLS·FCP·TTFB 등을 직접 캡처한다. 장점은 분석 요청 시점에 바로 수치를 얻을 수 있고, 다중 페이지를 돌며 각 페이지별 수치를 비교할 수 있다는 것이다. 단점은 실제 사용자 트래픽 없이 단일 실행으로 측정한 값이라는 것이다.

그래서 ViewCheck는 이 수치를 "현재 상태의 참고값"으로 제공하고, 가능한 경우 Google Search Console CrUX 데이터와 교차 확인할 것을 권장한다. 도구 하나의 수치만으로 "이 사이트의 성능이 이렇다"고 단정하는 건 항상 조심스럽다.

모던 사무실에서 화면에 표시된 성능 게이지를 손가락으로 가리키며 설명하는 분석가.
화면의 수치를 가리키며 설명하는 분석가. 랩 데이터와 필드 데이터, 두 가지 측정값을 같이 보는 것이 현명하다.

ViewCheck는 어떻게 Core Web Vitals를 수집하는가

이제 ViewCheck가 구체적으로 어떤 방식으로 Core Web Vitals를 수집하는지 조금 더 들여다보자. 입문편이므로 기술적인 세부사항보다는 "어떤 원칙으로 측정하는가"에 초점을 맞춘다.

브라우저를 직접 띄운다

ViewCheck의 크롤러(Railway에 배포된 Node.js 백엔드)는 페이지를 분석할 때 실제 Playwright 브라우저 인스턴스를 띄운다. headless(화면 없는) 크롬이지만, 자바스크립트 실행, CSS 계산, 이미지 렌더링이 모두 실제로 일어난다. HTML 소스만 받는 게 아니라, 사용자가 실제로 브라우저에서 보는 것과 동일한 환경을 시뮬레이션한다.

이게 중요한 이유는, 공공 사이트 중 일부는 자바스크립트로 콘텐츠를 동적으로 로드하기 때문이다. HTML 소스에는 빈 div만 있고 실제 내용은 자바스크립트가 채우는 구조라면, 브라우저 없이는 실제 LCP 요소조차 확인할 수 없다.

PerformanceObserver로 이벤트를 직접 잡는다

브라우저를 띄운 뒤, ViewCheck는 page.evaluate() 또는 page.addInitScript()를 통해 PerformanceObserver API를 페이지 로드 초기에 심는다. 이 옵저버가 largest-contentful-paint, layout-shift, longtask 등의 퍼포먼스 엔트리를 페이지 내에서 직접 캡처한다.

[Playwright 브라우저]
  → 페이지 로드 시작
  → PerformanceObserver 심기
  → 이벤트 수집 (LCP candidate, layout-shift entries...)
  → Navigation Timing API로 TTFB, FCP, DOMContentLoaded 등
  → 수집 완료 → JSON으로 ViewCheck 서버 반환
  → SSE로 프론트엔드에 전달

Navigation Timing API에서는 TTFB(responseStart - navigationStart), FCP(PerformanceEntry의 first-contentful-paint)를 얻는다. DNS 조회 시간, TCP 연결 시간, TLS 협상 시간도 구분해서 측정한다. 이 세분화된 수치가 있으면 "서버가 느린 것인지, 네트워크가 느린 것인지, 클라이언트 렌더링이 느린 것인지"를 구분해서 볼 수 있다.

다중 페이지에서 반복한다

이 측정을 ViewCheck는 메인 페이지 한 장만 하지 않는다. 분석 대상 사이트의 여러 페이지(검색 결과 페이지, 신청 페이지, 게시판, 상세 페이지 등)를 돌며 각 페이지별로 Core Web Vitals를 측정한다. 그리고 이 값들의 분포를 집계해 "사이트 전체의 성능 프로파일"을 만든다.

메인 페이지는 잘 최적화되어 있어도 신청 페이지의 LCP가 6초인 경우가 있다. 반대로 메인의 CLS가 나빠도 실제 사용자가 주로 방문하는 게시판은 안정적인 경우도 있다. 페이지 유형별로 성능이 다르므로, 다중 페이지 측정이 의미를 갖는다. "어느 페이지가 특히 느린지"를 짚어낼 수 있어야, 개선도 그 페이지를 우선순위로 진행할 수 있다.


공공 웹사이트 성능과 행안부 품질관리 지침의 연결

Core Web Vitals는 Google이 정의한 지표다. 그럼 대한민국 공공 웹사이트를 규율하는 공식 기준인 행안부 「전자정부 웹사이트 품질관리 지침」과는 어떤 관계가 있을까?

행안부 지침(고시 제2025-46호, 2025. 6. 25.)은 7대 품질 영역 중 효율성에서 "페이지 로딩 성능"을 다룬다. 지침의 구체적인 점검 기준은 별도의 「품질관리 가이드」에 위임되어 있는데, 이 가이드에서 응답 속도, 페이지 로딩 시간 같은 지표를 언급한다.(행정안전부, 전자정부 웹사이트 품질관리 지침 일부개정 안내, mois.go.kr)

공식 지침이 Core Web Vitals의 임계값을 직접 명시하는 형태는 아니지만, "페이지 로딩이 빠르고, 사용자가 불편 없이 서비스를 이용할 수 있어야 한다"는 방향성에서 Core Web Vitals는 그 기준을 채우는 실무적인 수단이 된다. 실제로 ViewCheck가 측정하는 Core Web Vitals 값은 행안부 효율성 영역의 점검 근거 데이터로 활용할 수 있다.

중요한 건 이 맥락이다. 공공 담당자가 외주 개발사에 "사이트 느립니다"라고 말하는 것보다, "LCP가 4.2초로 나쁨 기준을 초과합니다, 기준값은 2.5초입니다"라고 말하는 게 훨씬 구체적이고 반론하기 어렵다. Google이라는 국제적으로 신뢰받는 기관이 공개한 기준을, 실제 브라우저로 측정한 수치로 제시하는 것 — 이게 ViewCheck의 웹 성능 보고가 단순한 "빠르다/느리다" 판정을 넘어서는 이유다.

ViewCheck LLM 분석 화면에서 웹 성능(Core Web Vitals) 결과 카드. LCP, CLS, TTFB 등 수치와 판정이 표시된 실제 캡처.
ViewCheck LLM 분석의 웹 성능 결과 화면. LCP·CLS·TTFB 등 Core Web Vitals 수치가 카드 형태로 표시되며, 각 지표별 좋음/개선필요/나쁨 판정이 함께 제공된다. — 실제 분석 화면

성능 지표와 실제 사용자 행동 — 숫자가 의미하는 것

Core Web Vitals 수치가 개선되면 실제로 뭐가 달라질까? 이건 "달라질 수도 있다"와 "달라지지 않을 수도 있다" 사이 어딘가다. 직접적인 인과관계를 주장하기는 어렵지만, 상관관계에 대한 연구는 여러 건 있다.

Google이 공개한 Case Study들을 보면 성능 개선과 사용자 지표 개선이 함께 나타나는 사례들이 있다. Google은 수백만 번의 페이지 로드를 분석한 연구에서 "Core Web Vitals 권장 임계값을 충족하는 사이트의 경우, 사용자가 페이지 로딩 완료 전에 이탈할 가능성이 최소 24% 낮다"는 결과를 발표했다.(Google, "The business impact of Core Web Vitals", web.dev) Vodafone은 LCP를 31% 개선해 매출이 8% 증가하는 결과를 봤고, Rakuten 24는 세 가지 Core Web Vitals 모두를 개선해 방문자당 매출이 53% 늘었다고 보고했다.(Google, "The business impact of Core Web Vitals", web.dev)

다만 이 수치들을 공공 사이트에 그대로 적용하는 건 조심스럽다. 공공 사이트는 전자상거래 사이트와 성격이 다르다. "빠른 사이트라서 민원 처리율이 8% 높아졌다"같은 식의 직접 인과를 말하기는 어렵다. 하지만 한 가지는 분명하다. 사이트가 느리면 사용자가 이탈하고, 특히 모바일 환경에서 그 이탈은 더 빠르다. 공공 서비스를 이용하려다 사이트가 느려서 포기하고 오프라인으로 돌아가는 경험은 디지털 전환의 역행이다.

그래서 공공 사이트의 Core Web Vitals 개선은 "사용자가 온라인으로 서비스를 완결할 가능성"을 높이는 데 기여한다는 방향으로 이해하는 게 현실적이다. 전환율 최적화가 아니라, 서비스 완결률 향상이다. 이게 우리가 공공 사이트 성능 분석에서 지향하는 가치다.


75백분위수 기준 — 왜 평균이 아닌가

Core Web Vitals를 평가할 때 Google이 75백분위수를 기준으로 쓰는 이유를 짚어두고 싶다. 이건 실무에서 꽤 중요한 차이를 만든다.

평균을 쓰면 어떤 일이 생길까? 사이트 방문의 95%가 LCP 0.5초로 매우 빠르고, 5%만 LCP 60초라면, 평균은 3.5초 정도로 나온다. '좋음' 범위에 들어온다. 그런데 실제로는 20명 중 1명이 매우 나쁜 경험을 하고 있다. 평균은 그 5%를 숨긴다.

75백분위수를 쓰면 다르다. 방문의 75%가 2.5초 이내여야 '좋음'이다. 즉, **상위 25%의 방문자가 기준을 넘어도 "나쁨"**이 될 수 있다. 대다수(75%)가 좋은 경험을 해야 한다는 뜻이다. 이렇게 하면 "일부 사용자의 나쁜 경험"이 평균에 묻히지 않는다.

이 선택은 공공 서비스에서 더욱 중요한 함의를 갖는다. 공공 서비스는 특정 사용자를 배제해서는 안 된다. 저가형 스마트폰을 쓰는 사람, 3G 네트워크 지역에 사는 사람, 고령자가 사용하는 느린 기기 — 이들이 바로 그 "상위 25%"에 속할 가능성이 높다. 75백분위수 기준은 "빠른 기기를 쓰는 대부분의 사용자는 빠른데, 느린 기기를 쓰는 소수는 엄청 느리다"는 상황을 '통과'로 인정하지 않는다. ViewCheck가 75백분위수 기준을 따르는 것도 이 이유다.


모바일 성능 — 공공 사이트의 가려진 문제

Core Web Vitals는 모바일과 데스크탑을 구분해서 측정한다. Google Search Console의 Core Web Vitals 보고서도 두 탭으로 나뉜다. 그리고 통상적으로 모바일 수치가 데스크탑보다 나쁜 게 일반적이다.

공공 사이트에서 이 격차가 특히 큰 이유가 있다. 먼저 개발·테스트 환경의 편향이다. 공공 사이트는 대부분 데스크탑 브라우저를 기준으로 개발된다. 담당자, 개발사, QA 담당자 모두 고사양 PC에서 사이트를 본다. 그 환경에서는 LCP 1초, INP 100ms로 뜰 수 있다. 그런데 저가 스마트폰에서 3G 네트워크로 같은 사이트를 열면 LCP 5초, INP 600ms가 나올 수 있다. 개발팀이 경험하지 못한 성능이다.

둘째는 자바스크립트 처리 비용이다. 모바일 CPU는 데스크탑 대비 510배 느린 경우도 있다. 데스크탑에서 무거운 JavaScript 번들이 100ms에 실행되면, 중간 사양 모바일에서는 500ms1초가 걸릴 수 있다. 이게 INP와 LCP 모두에 영향을 준다.

셋째는 네트워크 조건이다. 공공 서비스의 주 사용자 중에는 WiFi가 아닌 LTE/3G 환경에서 접속하는 경우도 많다. 이미지나 JavaScript 파일 크기가 조금만 커도 다운로드 시간이 눈에 띄게 늘어난다.

ViewCheck는 Core Web Vitals를 Playwright로 측정할 때 데스크탑 기본 뷰포트(1920×1080 기준)와 함께, 모바일 뷰포트(390×844, iPhone 기준)로도 측정해 비교한다. 데스크탑에서만 테스트해서 "성능 양호"라고 결론 내리는 함정을 피하기 위해서다. 물론 이 시뮬레이션도 실제 모바일 기기·네트워크를 완전히 재현하지는 못한다. 하지만 "모바일 환경도 함께 보겠다"는 방향성이 중요하다.

노트북으로 페이지 로드 성능을 프로파일링하며 아침 커피를 마시는 한국인 개발자.
아침 커피 한 잔과 함께 성능 프로파일링을 들여다보는 개발자. 모바일 환경을 잊지 말아야 한다는 걸, 실측할 때마다 다시 배운다.

"좋음" 기준을 통과하는 것과 "좋은 사이트"의 차이

Core Web Vitals 세 가지가 모두 '좋음'이면 그 사이트는 좋은 사이트인가? 이 질문에 조심스럽게 답해야 한다.

Core Web Vitals는 측정 가능한 것 중 가장 중요한 것들을 잡은 지표다. 그러나 웹 사용 경험 전체를 커버하지는 않는다. LCP가 2.0초여도 화면이 극도로 복잡하고 혼란스러울 수 있다. CLS가 0.05여도 글씨가 너무 작아 읽기 어려울 수 있다. INP가 150ms여도 폼 오류 메시지가 이상한 위치에 뜨거나, 색상 대비가 낮아서 접근성이 무너져 있을 수 있다.

그래서 ViewCheck에서 Core Web Vitals는 24가지 분석 카드 중 하나인 "웹 성능" 카드를 구성하는 데이터다. 이 카드가 "좋음"이라고 해도, KRDS 846규칙 판정, 접근성(KWCAG), 보안, SEO, 반응형 품질 등 다른 카드들이 함께 읽혀야 사이트의 전체 상태를 파악할 수 있다. "성능만 좋으면 됐다"는 식의 판단은 경계해야 한다.

반대로 Core Web Vitals 하나가 기준을 벗어났다고 해서 사이트 전체가 형편없는 것도 아니다. LCP가 3.0초로 '개선 필요'에 해당해도, 접근성은 훌륭하고 보안 헤더는 완벽하고 KRDS 디자인 시스템을 잘 따르는 사이트가 있다. 그런 사이트에서는 LCP를 개선하되, 다른 좋은 부분들을 망가뜨리지 않는 것이 목표가 된다.

지표는 도구다. 도구를 목적 자체로 삼으면 왜곡이 생긴다. 우리가 Core Web Vitals를 측정하는 목적은 "지표 통과"가 아니라, "실제 사용자가 사이트를 쓸 때 얼마나 불편한지를 숫자로 잡아서, 개선의 출발점을 제공하는 것"이다.


ViewCheck의 24개 카드 중 "웹 성능" 카드

ViewCheck LLM 분석의 24기능 중 하나가 "웹 성능" 카드다. 이 카드는 위에서 설명한 Core Web Vitals 수치를 포함해, 접속 성능과 관련된 주요 지표들을 한 눈에 보여준다.

카드에 담기는 주요 내용은 대략 이렇다.

Core Web Vitals (측정된 것):

  • LCP — 최대 콘텐츠풀 페인트 (초 단위, 좋음/개선필요/나쁨 판정)
  • CLS — 누적 레이아웃 이동 (점수, 좋음/개선필요/나쁨 판정)
  • FCP — 첫 번째 콘텐츠풀 페인트 (초 단위)
  • INP — 참고값 (Playwright 환경 한계로 참고 수준)

연결 지표:

  • TTFB — 첫 번째 바이트까지의 시간 (서버 응답 속도)
  • DNS 조회 시간, TCP 연결 시간, TLS 협상 시간 (연결 단계별 분해)
  • 리다이렉트 체인 유무

리소스 분석:

  • 느린 리소스 상위 5개 (다운로드에 가장 오래 걸린 리소스)
  • 리소스 유형별 크기 (이미지·JS·CSS·폰트 등)

이 정보들이 함께 있으면, 담당자가 "서버를 업그레이드해야 하는지", "이미지 최적화부터 해야 하는지", "자바스크립트를 줄여야 하는지"를 방향 잡을 수 있다. 어디서부터 손대야 할지를 모를 때, 이 카드가 출발점이 된다.

물론 "WebVitals 카드를 보고 이렇게 하세요"라고 처방전을 주는 건 ViewCheck의 역할 밖이다. 측정값과 기준값, 그리고 "이 리소스가 특히 느립니다"같은 힌트까지가 우리가 제공할 수 있는 것이고, 실제 개선 방법은 개발사가 판단해야 한다. 도구는 진단까지, 처방은 사람이 — 이게 우리가 생각하는 건강한 분업이다.


다중 페이지로 봐야 하는 이유 — 메인의 성능이 서비스 성능이 아니다

Core Web Vitals를 논할 때 우리가 가장 강조하고 싶은 게 하나 있다. 메인 페이지의 성능이 사이트 전체의 성능을 대표하지 않는다는 것이다.

현실에서 공공 사이트의 성능 점검은 대개 메인 페이지(홈) 하나를 대상으로 이루어진다. PageSpeed Insights에 사이트 주소 넣기, Lighthouse 한 번 돌리기 — 이런 방식이다. 그런데 시민이 실제로 어떤 목적으로 공공 사이트를 방문하는지를 생각해 보면, 메인만 측정하는 게 얼마나 불완전한지를 알 수 있다.

  • 건강보험 민원을 신청하러 온 사람은 메인을 거쳐 신청 폼 페이지로 간다.
  • 공고문을 찾는 사람은 메인에서 검색을 한 뒤 목록 → 상세 페이지로 간다.
  • 주민등록 등본을 뗄 수 있는지 확인하러 온 사람은 민원 분류 → 신청 화면으로 간다.

이 과정에서 성능이 나쁜 페이지는 메인이 아닐 수 있다. 신청 폼 페이지에 무거운 에디터 컴포넌트가 올라가 있어서 LCP가 8초인 경우, 검색 결과 페이지에서 이미지가 뒤늦게 로드되어 CLS가 0.5인 경우 — 이런 문제들은 메인 페이지만 보면 절대 발견할 수 없다.

ViewCheck가 처음부터 다중 페이지 분석을 기본값으로 설계한 이유 중 하나가 이것이다. 성능 측정도 다중 페이지여야 의미가 있다. 모든 주요 페이지 유형(메인, 검색, 목록, 상세, 신청, 로그인)에서 Core Web Vitals를 측정하고, "어느 유형이 특히 느린지"를 집계해야 진짜 문제를 찾을 수 있다.

실제로 우리가 여러 공공 사이트를 분석하면서 발견한 공통 패턴이 있다. 메인은 LCP 2.0초로 양호한데, 민원 신청 페이지에서 LCP 5.5초가 나오는 경우다. 그 신청 페이지에 파일 업로드 컴포넌트와 결제 모듈이 동기 로딩으로 묶여 있어서, 두 모듈이 전부 다운로드될 때까지 LCP가 발생하지 않는 것이다. 메인 성능 점검을 아무리 열심히 해봤자 이 문제는 절대 찾을 수 없다.


Core Web Vitals와 KRDS 846규칙의 교차점

한 가지 흥미로운 연결 지점이 있다. Core Web Vitals는 Google이 정의한 성능 지표이고, KRDS 846규칙은 행안부 기준의 디자인 시스템 준수 규칙이다. 이 둘은 별개처럼 보이지만, 실제로는 겹치는 지점이 있다.

대표적인 예가 이미지 크기와 CLS의 관계다. KRDS DS(디자인 스타일) 규칙 중에는 이미지가 적절한 비율과 크기를 가져야 한다는 항목들이 있다. 이미지가 KRDS 가이드라인에 따라 제대로 크기 속성을 갖추고 있으면, CLS도 낮아질 가능성이 높다. 반대로 KRDS 규칙을 위반해 이미지에 고정 크기 없이 너비 100%로만 처리하면, CLS가 나빠질 수 있다.

타이포그래피 규칙과 CLS도 연결된다. KRDS는 웹폰트(Pretendard GOV)를 권장하며, 폰트 파일을 적절히 로딩하는 방법도 가이드라인으로 제공한다. KRDS 타이포그래피 규칙을 잘 따르고 있다면, 폰트 로딩 관련 CLS도 억제될 가능성이 있다.

이처럼 KRDS 준수가 단순히 "규정 충족"에 그치는 게 아니라, 실제 사용자 경험(Core Web Vitals로 측정되는)과도 연결된다는 점이 흥미롭다. 우리는 이 교차점을 ViewCheck의 분석에서 함께 보여주려 한다. "이 페이지는 KRDS DS-018 위반이 있는데, 이것이 CLS와도 관련될 수 있습니다"처럼 연결 지점을 보여주는 것이다. 아직 모든 규칙에서 이 연결을 자동으로 잡는 건 아니고, 연구 중인 영역이다.


성능 개선의 실제 난이도 — 공공 사이트의 구조적 어려움

Core Web Vitals 수치가 나쁘다는 걸 알았다고 해서 개선이 쉬운 건 아니다. 특히 공공 사이트는 성능 개선 앞에 구조적 장벽이 있다.

첫 번째는 레거시 시스템이다. 공공 사이트 중 상당수는 5~10년 전에 구축된 시스템을 현재도 운영하고 있다. 그 시스템의 아키텍처 자체가 현재의 웹 성능 최적화 기법을 적용하기 어려운 구조인 경우가 있다. CSS 번들링, JS 코드 스플리팅, 이미지 WebP 변환 등 현대적인 최적화 방법이 기존 CMS나 템플릿 구조와 충돌하는 것이다.

두 번째는 서드파티 의존성이다. 공공 사이트에는 통계 수집, 민원 인증, 접근성 보조 도구, 보안 스캐너 등 다양한 서드파티 스크립트와 모듈이 붙어 있다. 이 중 일부는 외부 기관이 제공하는 것이라 담당자가 마음대로 최적화하거나 제거할 수 없다. 그런데 이 서드파티 스크립트들이 render-blocking이라면 LCP와 INP에 직접 영향을 준다.

세 번째는 변경의 파급 효과다. 공공 사이트는 한 부분을 고치면 다른 부분이 망가지는 경우가 종종 있다. 이미지 지연 로딩(lazy loading)을 적용했더니 갑자기 특정 브라우저에서 이미지가 안 뜨거나, JS 번들을 줄였더니 구형 브라우저 지원이 깨지는 식이다. 이런 경험이 쌓이면 담당자와 개발사 모두 "건드리지 말자"는 보수적인 태도를 갖게 된다.

ViewCheck가 이 어려움을 해결해 주는 건 아니다. 우리가 할 수 있는 건 "현재 어느 수치가 기준에서 얼마나 벗어나 있는지"와 "어느 리소스가 가장 큰 영향을 주고 있는지"를 최대한 명확하게 보여주는 것이다. 그 다음은 담당자와 개발사가 해당 구조적 맥락 안에서 판단하고 결정해야 한다. 성능 개선은 진단이 아니라 실행의 영역이고, 실행은 현장 사람들이 해야 한다.

화면 옆에 놓인 속도계 모양의 게이지 소품. 성능 측정과 개선의 간극을 상징한다.
속도계 같은 성능 게이지. 수치를 아는 것과 그것을 개선하는 건 다른 문제다.

Chrome UX Report(CrUX)로 보는 실제 사용자 데이터

ViewCheck가 수행하는 Playwright 기반 합성 측정은 도구 측정값이다. 이것과 다른 차원의 데이터가 Google의 Chrome UX Report(CrUX)다.

CrUX는 Chrome 브라우저를 통해 실제로 사이트를 방문한 수백만 명의 데이터를 집계한 공개 데이터셋이다. "실제 사용자가 느끼는 성능"을 가장 직접적으로 보여준다. Google의 PageSpeed Insights, Search Console, CrUX API를 통해 접근할 수 있다.(Google, "Overview of CrUX", Chrome for Developers)

공공 사이트 담당자라면 Google Search Console의 Core Web Vitals 보고서를 통해 CrUX 기반의 필드 데이터를 확인할 수 있다. 다만 방문자 수가 적은 사이트는 CrUX 데이터 임계값을 충족하지 못해 데이터가 없을 수 있다. 이런 경우 ViewCheck 같은 합성 측정 도구가 대안이 된다.

ViewCheck의 분석 결과와 CrUX 데이터를 함께 보는 것이 이상적이다. 합성 측정에서는 LCP 2.2초로 '좋음'인데 CrUX에서는 LCP가 4.5초로 '나쁨'이라면, 그 차이가 "어떤 환경(기기, 네트워크)을 쓰는 사용자에게 특히 느린지"를 추적하는 단서가 된다. ViewCheck는 이 두 데이터를 교차 분석하는 방향으로 발전시키려 하고 있다. 현재는 합성 측정 중심이고, CrUX 연동은 앞으로의 과제다.


성능 측정의 함정 — 수치 게임을 경계한다

마지막으로 한 가지를 경계하고 싶다. Core Web Vitals 점수를 높이는 것 자체가 목적이 되는 것이다.

실제로 웹 성능 최적화 업계에서 "Core Web Vitals 점수를 좋게 보이게 하는" 기법들이 있다. 예를 들어 LCP 요소가 되는 이미지에만 우선적으로 프리로드를 걸고, 나머지는 지연 로딩해서 LCP 수치만 빠르게 보이게 하거나, CLS를 유발하는 요소를 position:absolute로 처리해 레이아웃 흐름에서 제거하는 식이다. 이렇게 하면 측정 수치는 좋아지지만, 실제 사용자 경험이 개선되지 않거나 오히려 나빠지는 경우도 있다.

공공 기관에서 이 문제는 조달이나 검수 과정에서 생길 수 있다. "납품 전 Lighthouse 90점 이상 달성"이 계약 조건이라면, 개발사는 Lighthouse 점수를 올리는 최단 경로를 택하게 된다. 그 경로가 반드시 "실제 사용자 경험을 개선하는 것"과 일치하지 않을 수 있다.

ViewCheck는 이 함정을 인식하고 있다. 우리가 측정하는 수치가 "게임의 대상"이 되지 않도록, 측정 방법의 원칙(다중 페이지, 75백분위수 기준, 실제 브라우저 렌더링)을 투명하게 공개하는 것이 하나의 방어다. 그리고 성능 카드 하나가 아니라 24개의 다각도 분석을 같이 보여줌으로써, "성능 수치만 좋으면 됐다"는 편향을 줄이려는 것도 같은 맥락이다.


성능 분석이 KRDS 준수와 함께 이야기되어야 하는 이유

행안부 지침의 7대 품질 영역을 다시 떠올려 보자. 호환성, 접근성, 개방성, 접속성, 편의성, 효율성, 신뢰성. Core Web Vitals는 주로 "효율성"과 "접속성" 영역에 해당한다. 그런데 이 7대 영역은 서로 분리된 게 아니다.

접근성(KWCAG)이 좋은 사이트는 대부분 HTML 구조가 깔끔하다. 깔끔한 HTML 구조는 브라우저가 렌더링 트리를 빠르게 만들 수 있게 해줘 FCP·LCP에 도움이 된다. KRDS 컴포넌트 규칙을 잘 따르는 사이트는 불필요한 커스텀 CSS·JS가 적어, 리소스 크기가 줄고 성능이 좋아지는 경향이 있다. 반대로 성능이 나쁜 사이트는 종종 DOM 구조도 복잡하고, ARIA 속성도 부실하고, 이미지 최적화도 안 되어 있다.

이 상관관계가 반드시 인과관계를 의미하지는 않는다. 하지만 "성능만 따로 보고", "접근성만 따로 보고", "KRDS 준수만 따로 보는" 방식으로는 사이트의 전체 건강 상태를 파악하기 어렵다. 그래서 ViewCheck는 Core Web Vitals를 독립된 도구가 아니라 24개 분석 카드 중 하나로, 다른 카드들과 함께 읽히도록 설계한다.

담당자가 "웹 성능" 카드를 본 뒤, "KRDS 846" 카드와 "접근성" 카드를 같이 봤을 때 — "성능이 나쁜 페이지에서 KRDS 위반도 집중되어 있다"는 패턴이 보이면, 그 페이지를 가장 먼저 개선 대상으로 삼는 게 효과적이다. 한 페이지에서 성능 개선과 KRDS 준수 개선을 같이 진행하면, 개발 비용도 아끼고 효과는 더 넓게 볼 수 있다. 이런 통합적 시각이 우리가 24개 카드를 함께 보여주는 이유 중 하나다.


우리가 아직 모르는 것들

솔직하게 적어두고 싶은 게 있다. ViewCheck의 Core Web Vitals 측정과 분석에서 우리가 아직 해결하지 못한 부분들이다.

INP의 정확도: 앞에서도 언급했지만, INP는 실제 사용자 상호작용 없이는 정확하게 측정하기 어렵다. Playwright로 클릭을 시뮬레이션해 근사값을 얻지만, 실제 필드 데이터와 얼마나 차이가 나는지를 체계적으로 검증하는 작업이 아직 부족하다. 이 부분은 계속 개선 중이다.

멀티페이지 집계 방식: 다중 페이지에서 측정한 Core Web Vitals를 "사이트 전체"의 수치로 어떻게 표현할 것인가가 쉽지 않다. 페이지별 평균? 중간값? 75백분위수? 각 방식이 다른 그림을 보여주고, 어느 방식이 더 현실에 가까운지 정답이 없다. 현재는 주요 지표를 페이지별로 보여주고, 전체 집계는 중간값을 기본으로 사용하되 페이지별 분포도 함께 볼 수 있게 하는 방향으로 설계하고 있다.

임계값의 공공 적용: Google의 75백분위수 기준이 공공 사이트에도 동일하게 적용돼야 하는지에 대한 의문이 있다. 민간 전자상거래 사이트와 공공 민원 사이트의 사용 패턴이 다를 수 있고, "공공 서비스에서는 더 엄격해야 한다"거나 "공공 서비스의 기술 환경을 감안해 기준이 달라야 한다"는 관점 모두 일리가 있다. 아직 정답을 갖고 있지 않다. 다만 현재는 Google의 공개된 기준을 따르되, 맥락을 함께 설명하는 방향을 택하고 있다.

이 한계들을 적어두는 이유는 "우리가 완벽하다"고 말하고 싶지 않아서다. Core Web Vitals 측정과 해석은 생각보다 많은 판단이 필요하고, 우리도 계속 배우고 있다.


마무리 — 숫자는 대화의 시작이다

다시 처음으로 돌아가자. "이 사이트 좀 느린 것 같은데요." 이 말을 숫자로 바꾸는 것이 Core Web Vitals의 역할이다. LCP 4.2초, CLS 0.18, TTFB 1.2초 — 이 숫자들이 있으면 "느리다는 게 어느 정도인지", "어디서 느린지", "기준 대비 얼마나 벗어나 있는지"를 구체적으로 이야기할 수 있다.

2024년 3월 INP가 FID를 대체한 것은, 단순한 지표 교체가 아니라 "사용자가 느끼는 반응성을 더 잘 잡는 방법"으로의 개선이다. 공공 사이트에서 버튼을 눌렀을 때의 지연, 폼을 작성할 때의 답답함을 더 정밀하게 수치로 잡겠다는 것이다. 이 변화를 ViewCheck도 반영해 INP를 측정 대상에 포함했다.

ViewCheck의 웹 성능 분석이 "LCP 몇 초입니다"로 끝나는 게 아니라, "어느 페이지가 특히 느리고, 어떤 리소스가 원인이며, 다른 품질 영역과 어떻게 연결되는지"까지 함께 보여주려는 이유가 여기에 있다. 숫자는 대화의 끝이 아니라 시작이다. 담당자와 개발사가 그 숫자를 들고 "무엇을 먼저 고칠까"를 논의할 때, 그 대화가 의미 있게 이루어지도록 돕는 것 — 이게 우리가 성능 분석에서 목표하는 것이다.

아직 완성하지 못한 부분도 적었다. INP 측정의 한계, 멀티페이지 집계 방식, 공공 적용 기준의 불확실성. 이런 것들을 숨기고 "우리 도구는 완벽합니다"라고 말하는 게 더 쉬울 수도 있다. 하지만 그런 말은 결국 사용자에게 도움이 되지 않는다. 측정값을 어디까지 신뢰할 수 있고, 어디서 추가 확인이 필요한지를 함께 알려줄 때, 그 숫자가 진짜로 쓸모 있게 된다.

이 시리즈의 다음 편들에서도, 우리가 무엇을 잘하고 무엇을 어렵게 여기는지를 계속 솔직하게 적어갈 예정이다. 공공 웹 성능이라는 주제는, 관련된 사람들 모두가 함께 더 잘 이해해 나가야 하는 영역이라고 믿기 때문이다.


참고문헌

본문에 인용한 출처는 작성 시점에 실재 여부를 검증했다. 공식 기술 문서와 Google 공개 연구, 대한민국 행정안전부 고시를 함께 실었다.

국내 — 공식 기준 / 정책자료

  1. 행정안전부, 「전자정부 웹사이트 품질관리 지침」(행정안전부고시 제2025-46호, 2025. 6. 25. 일부개정). 국가법령정보센터. https://www.law.go.kr/LSW/admRulLsInfoP.do?admRulSeq=2100000191651
  2. 행정안전부, 「전자정부 웹사이트 품질관리 지침」(고시 제2025-46호) 일부 개정 및 「품질관리 가이드」 수정본 안내. 행정안전부 공식. https://www.mois.go.kr/frt/bbs/type001/commonSelectBoardArticle.do?bbsId=BBSMSTR_000000000016&nttId=118636

해외 — Core Web Vitals 공식 문서 (Google web.dev)

  1. Google, "Web Vitals" (Core Web Vitals 공식 개요 — LCP·INP·CLS 정의 및 75백분위수 측정 방식). web.dev, 2024. https://web.dev/articles/vitals
  2. Google, "Largest Contentful Paint (LCP)" (LCP 정의·임계값·측정 방법 — 2.5초 '좋음' 기준 포함). web.dev. https://web.dev/articles/lcp
  3. Google, "Interaction to Next Paint (INP)" (INP 정의·임계값·측정 방법 — 200ms '좋음' 기준 포함). web.dev. https://web.dev/articles/inp
  4. Google, "Cumulative Layout Shift (CLS)" (CLS 정의·임계값·시각적 안정성 측정 — 0.1 '좋음' 기준 포함). web.dev. https://web.dev/articles/cls
  5. Google, "Interaction to Next Paint becomes a Core Web Vital on March 12" (INP가 FID를 대체하는 공식 발표, 2024년 3월 12일). web.dev Blog, 2024. https://web.dev/blog/inp-cwv-march-12
  6. Google, "How the Core Web Vitals metrics thresholds were defined" (CWV 임계값이 사용자 연구 기반으로 정해진 방법론 — 75백분위수 근거 포함). web.dev. https://web.dev/articles/defining-core-web-vitals-thresholds
  7. Google, "Time to First Byte (TTFB)" (TTFB 정의·임계값 — 0.8초 '좋음' 기준). web.dev. https://web.dev/articles/ttfb
  8. Google, "The business impact of Core Web Vitals" (CWV와 사용자 이탈·비즈니스 지표 연구 사례). web.dev Case Studies. https://web.dev/case-studies/vitals-business-impact
  9. Google, "Overview of CrUX" (Chrome User Experience Report 공개 데이터셋 소개). Chrome for Developers. https://developer.chrome.com/docs/crux

#WebVitals#성능#LCP#INP#CLS#공공웹#ViewCheck#KRDS

관련 글

KRDS · 공공웹 AI 진단연구

ViewCheck LLM 분석 리포트 읽는 법 — 점수·등급·근거·우선순위 해석에서 행동까지

분석이 끝나고 화면에 숫자가 떴다. 종합 74점. KRDS 846규칙 중 289개 통과, 228개 미통과, 329개 해당없음. 접근성 68점. 보안 91점. 위반 매트릭스에는 빨간 칸과 노란 칸이 뒤섞여 있다. 그런데 막상 이 결과를 받아 든 담당자의 표정이 묘하다. 뭔가 많이 나왔는데, 무엇을 먼저 봐야 할지 모르겠다.

ViewCheck Insight·2026.07.20
KRDS · 공공웹 AI 진단연구

AI 진단, 어디까지 믿어야 하나 — ViewCheck를 활용하는 사람을 위한 정직한 가이드

2026년 어느 날, 공공기관의 웹 담당자 한 명이 AI 분석 결과를 출력해 상사에게 내밀었다고 상상해 보자. "AI가 분석했더니 우리 사이트 KRDS 준수율이 68점입니다." 상사는 고개를 끄덕이며 "그럼 개선 계획 짜세요"라고 했다. 담당자는 돌아가 개발사에 수정 목록을 전달했다. 문제는, 그 68점이 무엇을 근거로

ViewCheck Insight·2026.07.20
KRDS · 공공웹 AI 진단연구

분석 → 개선 → 재진단, 공공웹 품질을 '점수로 관리'한다는 것 — ViewCheck LLM 분석 활용

공공 웹사이트 품질 진단을 맡은 실무 담당자들과 이야기하다 보면, 어느 지점에서 공통된 표정이 나온다. "진단은 했어요. 그런데 그다음은 어떻게 해야 하죠?" 도구를 돌리면 문제 목록이 나온다. 때로는 수백 개, 때로는 수십 페이지짜리 보고서가 나온다. 그리고 거기서 멈춘다. 문제를 고쳤는지 어떻게 확인하지? 개선 후에

ViewCheck Insight·2026.07.20