Performance Accessibility
3줄 요약
- 프론트 성능은 큰 bundle, 큰 이미지, 느린 API, 불필요한 렌더링, cache 부재가 함께 만드는 사용자 경험 문제다.
- 접근성은 부가 기능이 아니라 semantic HTML, keyboard, focus, label, contrast를 통해 기본 사용성을 보장하는 일이다.
- 개인 프로젝트에서도 이미지 크기, route lazy loading, loading skeleton, keyboard navigation, focus 관리는 결과물의 완성도를 눈에 띄게 올린다.
핵심 정리
- Core Web Vitals는 loading, interactivity, visual stability를 사용자 경험 지표로 본다.
- code splitting과 lazy loading은 초기 화면에 필요 없는 코드를 늦게 받게 한다.
- image optimization은 적절한 크기, 포맷, lazy loading, width/height 지정이 핵심이다.
- semantic HTML은 접근성과 테스트 가능성을 동시에 높인다.
- modal, dropdown, form error는 focus와 keyboard interaction을 반드시 고려한다.
백엔드 개발자가 헷갈리는 지점
- 성능 문제를 프론트 렌더링 문제로만 보기 쉽다.
- 판단 기준은 API 응답 크기, pagination, cache header, 이미지 URL도 함께 본다는 점이다.
- 백엔드 응답 설계가 프론트 성능에 직접 영향을 준다.
- 접근성을 나중에 여유 있을 때 하는 작업으로 보기 쉽다.
- 판단 기준은 button, label, focus 같은 기본은 처음부터 구조에 들어가야 한다는 점이다.
- 나중에 붙이면 구조를 다시 고쳐야 한다.
- lazy loading을 많이 쓰면 무조건 좋다고 생각하기 쉽다.
- 판단 기준은 첫 화면 핵심 자원은 빨리 보여야 하고, 나머지를 늦춰야 한다는 점이다.
개인 프로젝트 기준
- route 단위 lazy loading과 이미지 width/height 지정부터 적용한다.
- 목록 API는 pagination을 기본으로 설계한다.
- 키보드만으로 로그인, 검색, 생성, 삭제 흐름을 한 번 수행해 본다.
- Core Web Vitals는 Lighthouse와 실제 기기 DevTools로 확인한다.
확인 질문
- Core Web Vitals는 무엇을 보려는 지표인가?
- 사용자 관점의 로딩, 상호작용, 시각적 안정성을 보려는 지표다.
- 접근성에서 semantic HTML이 중요한 이유는 무엇인가?
- 브라우저와 보조 기술이 요소의 의미를 이해하고 keyboard interaction을 기본 제공할 수 있기 때문이다.
- 성능을 개선하기 전에 먼저 해야 하는 일은 무엇인가?
- 측정이다. Network, Performance, Lighthouse로 병목을 확인한다.
01. 성능 접근성 실전 상세
이 문서를 통해 아래 질문들에 답할 수 있게 됩니다.
- 프론트 성능 병목을 어디서부터 측정해야 하는가?
- 이미지와 bundle 최적화는 개인 프로젝트에서 어디까지 하면 충분한가?
- 접근성 기본을 지키면 왜 UI 품질과 테스트 가능성이 함께 좋아지는가?
개요
성능과 접근성은 “나중에 하면 되는 고급 주제”처럼 보이지만, 개인 프로젝트의 완성도를 가장 빨리 끌어올리는 기본기다. 큰 이미지 하나, focus가 빠진 modal 하나, label이 없는 input 하나가 사용성을 크게 떨어뜨린다. 백엔드 개발자 입장에서는 API 응답 크기, pagination, cache header가 프론트 성능에 직접 영향을 준다는 점도 중요하다. 화면이 느릴 때 프론트 코드만 탓하면 병목의 절반을 놓칠 수 있다.
원리
브라우저는 HTML을 파싱하고, CSS와 JavaScript를 받아 실행하고, layout과 paint를 수행한다. 초기 렌더링에 필요한 자원이 클수록 화면이 늦게 보인다. JavaScript bundle이 크면 다운로드뿐 아니라 parse와 execution도 오래 걸린다. 이미지 크기가 실제 표시 크기보다 크면 네트워크와 decoding 비용이 낭비된다.
접근성은 semantic HTML을 사용하면 상당 부분 자연스럽게 따라온다. button은 keyboard와 focus 처리가 기본으로 있고, label은 input과 이름을 연결한다. 반대로 div에 onClick을 붙여 버튼처럼 만들면 keyboard, role, focus를 직접 구현해야 한다. 이 차이는 접근성뿐 아니라 테스트 코드의 안정성에도 영향을 준다.
코드로 보는 핵심 예시
route 단위 lazy loading은 초기 bundle을 줄인다.
import { lazy, Suspense } from "react";
const AdminPage = lazy(() => import("./pages/AdminPage"));
function AppRoutes() {
return (
<Suspense fallback={<PageSpinner />}>
<Routes>
<Route path="/admin" element={<AdminPage />} />
</Routes>
</Suspense>
);
}이미지는 layout shift를 줄이기 위해 크기를 명시한다.
function Avatar({ user }: { user: User }) {
return (
<img
src={user.avatarUrl ?? "/images/default-avatar.png"}
width={40}
height={40}
alt={`${user.nickname} 프로필 이미지`}
loading="lazy"
decoding="async"
/>
);
}버튼은 div가 아니라 button으로 만든다.
function DeleteButton({ onDelete }: { onDelete: () => void }) {
return (
<button type="button" onClick={onDelete}>
삭제
</button>
);
}백엔드와 맞춰야 할 지점
- 목록 API는 pagination, projection, 필요한 field만 제공하는 방식을 고려한다.
- 이미지 API는 원본과 썸네일, width/height metadata, cache header를 제공한다.
- 에러 응답은 사용자가 다음 행동을 알 수 있는 메시지와 code를 준다.
- 서버 응답 시간과 프론트 렌더링 시간을 함께 추적한다.
- API 응답에 필요 없는 큰 필드가 섞이면 bundle 최적화보다 먼저 응답 projection을 검토한다.
개인 프로젝트 기준
- 이미지 원본을 그대로 목록 카드에 쓰지 않는다.
- Lighthouse 점수보다 실제 핵심 흐름이 빠르고 안정적인지 본다.
- 키보드로 tab 이동, modal 열고 닫기, form submit을 확인한다.
aria-*를 남발하기보다 semantic HTML을 먼저 쓴다.
실전 팁
- 성능 최적화는 측정 후 한다. memoization을 먼저 넣지 않는다.
- CLS를 줄이려면 이미지와 광고, 동적 영역의 크기를 미리 확보한다.
- modal이 닫힌 뒤 focus가 원래 버튼으로 돌아가는지 확인한다.
- 접근성은 Lighthouse 점수만으로 끝내지 말고 keyboard-only 흐름과 screen reader에 전달될 이름을 확인한다.
- 관련 CSS 함정은 [[02. 백엔드 개발자를 위한 프론트엔드 문법 함정과 디버깅#모바일-viewport와-100vh는-왜-함정일까|모바일 viewport와
100vh는 왜 함정일까?]]와 [[02. 백엔드 개발자를 위한 프론트엔드 문법 함정과 디버깅#overflow는-단순히-스크롤을-만드는-속성일까|overflow는 단순히 스크롤을 만드는 속성일까?]]를 본다.
위험 신호!
- 원본 3MB 이미지를 작은 카드 썸네일로 그대로 로드한다.
- 목록 API가 수천 row를 한 번에 내려준다.
- clickable
div가 많고 keyboard로 조작할 수 없다. - form input에 label이 없고 error가 screen reader에 전달되지 않는다.
확인 질문
확인 질문
- lazy loading을 적용할 때 조심할 점은 무엇인가?
- 첫 화면 핵심 콘텐츠까지 늦게 로드하지 않도록 구분해야 한다.
- 접근성에서 focus 관리는 왜 중요한가?
- keyboard 사용자와 보조 기술 사용자가 현재 위치와 다음 행동을 이해해야 하기 때문이다.
- 프론트 성능을 백엔드와 함께 봐야 하는 이유는 무엇인가?
- API 응답 크기, pagination, cache, 이미지 제공 방식이 렌더링 성능에 직접 영향을 주기 때문이다.