PHpullh
학습 로드맵/프론트엔드

HTML / CSS / JavaScript

🖥️ 프론트엔드 학습 로드맵

브라우저가 화면을 그리는 방식과 상태를 다루는 방식, 이 두 가지가 이 로드맵의 전부입니다.

웹 개발 로드맵과 무엇이 다른가

이 사이트에는 이미 웹 개발 학습 로드맵이 있습니다. 그쪽은 화면부터 서버, 데이터베이스, 배포까지 한 줄로 훑는 풀스택 경로입니다. 이 문서는 그 경로에서 브라우저 안쪽만 떼어내 다섯 배쯤 자세히 들어갑니다. 서버 프레임워크, ORM, 배포 파이프라인은 여기서 다루지 않습니다. 대신 브라우저가 마크업과 스타일을 받아 픽셀을 그리기까지 무슨 일이 일어나는지, 사용자의 클릭이 어떻게 화면 변화로 이어지는지, 그 변화가 왜 자꾸 어긋나는지를 다룹니다. 서버까지 포함한 전체 그림이 먼저 필요하다면 웹 개발 로드맵을 한 바퀴 돌고 오시는 편이 낫습니다.

프론트엔드가 시작하기 어려운 이유는 배울 게 많아서가 아니라, 배울 것의 목록이 매년 바뀌는 것처럼 보여서입니다. 실제로 바뀌는 건 도구 이름이고, 그 아래에서 요구하는 능력은 십 년째 같습니다. 문서 구조를 정확히 표현할 수 있는가, 화면에 보이는 것이 왜 그 모양인지 설명할 수 있는가, 지금 화면이 무엇을 근거로 그려졌는지 단 하나의 출처로 말할 수 있는가. 그래서 이 로드맵은 특정 프레임워크의 학습 순서를 따르지 않고, 프레임워크를 바꿔도 그대로 남는 것만 다섯 단계로 배치했습니다. 반대로 여기서 의도적으로 빼는 것도 분명히 해 두겠습니다. 서버 사이드 렌더링의 세부 전략, 모노레포 구성, 디자인 시스템 설계, 애니메이션 연출, 그리고 프레임워크 내부 구현입니다. 전부 실무에서 만나는 주제지만, 앞의 다섯 단계가 서 있지 않으면 배워도 남지 않습니다.

브라우저 쪽 다섯 단계

  1. HTML 시맨틱과 CSS 레이아웃
  2. JavaScript와 DOM
  3. 상태 관리와 컴포넌트 사고
  4. 접근성과 폼
  5. 성능과 빌드

아래 기간은 주당 10시간 기준입니다. 숫자는 참고만 하고, 각 단계의 "완료 기준"을 통과했는지로 판단하세요. 브라우저가 주소창의 문자열을 받아 화면을 그리기까지의 큰 그림이 아직 흐릿하다면 웹사이트를 열면 무슨 일이 일어나는가를 먼저 읽고 오면 1단계가 훨씬 수월합니다.

1단계 · HTML 시맨틱과 CSS 레이아웃 — 화면이 그 모양인 이유 설명하기

태그를 외우는 단계가 아닙니다. 문서를 읽는 주체가 사람만이 아니라는 감각을 잡는 단계입니다. 제목 계층을 h1부터 순서대로 쓰는 것, 목록은 목록 태그로 쓰는 것, 버튼처럼 눌리는 것은 div가 아니라 button으로 쓰는 것. 이 세 가지만 지켜도 4단계에서 할 일의 절반이 미리 끝납니다. 그다음이 레이아웃입니다. 박스 모델, 일반 흐름, 그리고 Flexbox와 Grid를 각각 언제 쓰는지 구분하는 것까지가 범위입니다. 한 축으로 늘어놓는 것은 Flexbox, 행과 열이 동시에 의미를 갖는 것은 Grid라는 기준 하나면 대부분의 화면이 해결됩니다.

여기서 반드시 같이 익힐 것이 개발자 도구입니다. 요소를 선택해 적용된 스타일과 무시된 스타일을 보고, 박스 크기가 어디서 왔는지 확인하고, 요소를 감싼 부모의 크기를 되짚는 습관입니다. 이 습관이 없으면 이후 모든 단계에서 "왜 이렇게 나오지"에 시간을 흘려보내게 됩니다.

기간: 3~4주. 완료 기준은 임의의 화면을 보고 어떤 요소가 어떤 태그이고 어떤 배치 방식으로 짜였을지 종이에 그릴 수 있으며, 내가 만든 화면이 어긋났을 때 개발자 도구만으로 원인을 짚을 수 있는 상태입니다. 체크포인트는 뉴스 기사 페이지 한 장을 이미지 없이 마크업만으로 재현하는 것입니다. 목차, 본문, 사이드바, 각주가 있고 화면 폭이 좁아지면 사이드바가 본문 아래로 내려가야 합니다. 자주 막히는 곳은 부모 요소의 높이가 자식을 감싸지 못하거나 반대로 화면 밖으로 넘치는 상황입니다. 대개 원인은 하나입니다. 어딘가에 무심코 넣은 고정 높이나 position 값이 그 요소를 일반 흐름에서 빼내 버린 것입니다. 값을 하나씩 지워 보면서 어느 선언이 흐름을 끊었는지 찾는 연습을 이 단계에서 해 두세요.

2단계 · JavaScript와 DOM — 화면을 코드로 만지기

언어 문법과 DOM 조작은 다른 주제인데 자주 섞여서 학습됩니다. 분리해서 봅시다. 언어 쪽에서 필요한 범위는 값과 참조의 차이, 배열과 객체 다루기, 함수와 클로저, 그리고 비동기입니다. 특히 비동기는 프론트엔드에서 피할 수 없어서 이 단계 안에 반드시 넣어야 합니다. 문법이 흔들린다면 JavaScript 기초와 JavaScript 비동기를, 다른 언어를 이미 아는 상태라면 비동기 처리 비교가 빠릅니다.

DOM 쪽에서는 요소를 찾고, 속성과 텍스트를 바꾸고, 이벤트를 듣는 것이 기본입니다. 여기서 놓치면 안 되는 개념이 이벤트가 위로 전파된다는 사실입니다. 목록 항목 백 개에 각각 핸들러를 다는 대신 부모 하나에 달고 어디서 발생했는지 판별하는 방식이 왜 나은지 이해하면, 나중에 프레임워크가 왜 그렇게 동작하는지도 자연스레 읽힙니다. 그리고 네트워크. 서버에 요청을 보내고 JSON을 받아 화면에 그리는 흐름을 손으로 한 번은 짜 봐야 합니다. 요청과 응답의 구조는 API 요청과 응답 이해하기와 HTTP 비교에 정리되어 있습니다.

EVENT DELEGATION — 항목마다 핸들러를 달지 않기

// 목록 전체에 한 번만 등록합니다.
list.addEventListener('click', (e) => {
  const item = e.target.closest('[data-id]');
  if (!item || !list.contains(item)) return;

  // 항목이 나중에 추가되어도 그대로 동작합니다.
  toggleDone(item.dataset.id);
});

// 요청 실패는 예외가 아니라 기본 경로로 취급합니다.
async function loadNotes() {
  const res = await fetch('/api/notes');
  if (!res.ok) throw new Error('HTTP ' + res.status);
  return res.json();
}

기간: 5~7주. 완료 기준은 라이브러리 없이 목록을 서버에서 받아 그리고, 항목을 추가·삭제하고, 요청이 실패했을 때 화면에 그 사실을 표시하는 페이지를 빈 파일에서 만들 수 있는 상태입니다. 체크포인트는 검색어를 입력하면 목록이 걸러지는 화면입니다. 입력할 때마다 요청을 보내지 말고 잠깐 기다렸다 보내는 처리까지 직접 넣어 보세요. 자주 막히는 곳은 응답이 도착하는 순서가 요청 순서와 다를 때입니다. "서"를 치고 "서울"을 쳤는데 "서"의 응답이 늦게 도착해 화면을 덮어씁니다. 요청마다 순번을 붙여 마지막 요청의 결과만 반영하거나 이전 요청을 취소해야 합니다. 이 버그는 로컬에서는 거의 재현되지 않아서, 네트워크를 느리게 설정해 두고 시험해야 발견됩니다.

3단계 · 상태 관리와 컴포넌트 사고 — 화면을 상태의 함수로 보기

2단계 방식으로 화면이 커지면 반드시 무너집니다. 같은 정보가 여러 곳에 흩어져서 한쪽만 갱신되기 때문입니다. 3단계의 목표는 도구를 배우는 게 아니라 관점을 바꾸는 것입니다. 화면은 상태를 넣으면 결과가 나오는 함수이고, 이벤트는 상태를 바꿀 뿐 화면을 직접 건드리지 않는다는 관점입니다. 이걸 잡으면 어떤 프레임워크를 써도 코드 모양이 비슷해지고, 못 잡으면 어떤 프레임워크를 써도 같은 문제가 반복됩니다.

실무에서 여기서 갈리는 판단은 대개 세 가지입니다. 이 값이 진짜 상태인가 아니면 다른 상태에서 계산해 낼 수 있는 값인가, 이 상태는 어느 범위까지 알려져야 하는가, 서버에서 받아 온 데이터를 화면 상태와 같은 통에 담아도 되는가. 마지막 질문의 답은 대체로 "아니오"입니다. 서버 데이터는 언제든 낡을 수 있고 다시 받아와야 하는 반면, 열림/닫힘 같은 화면 상태는 그렇지 않습니다. 이 둘을 섞으면 새로고침 로직이 화면 상태를 날려 버리는 문제가 생깁니다.

프레임워크는 이 시점에 하나 고르면 됩니다. 어느 것을 고르든 상관없다는 말이 무책임하게 들리겠지만, 실제로 이 단계에서 배우는 것의 대부분은 프레임워크가 아니라 상태 설계입니다. 주변에 물어볼 사람이 있는 쪽을 고르는 게 학습 속도에는 훨씬 큰 영향을 줍니다. 타입을 붙이면 상태 구조가 눈에 보이므로 TypeScript를 이 단계쯤 얹는 것도 좋은 선택입니다.

기간: 5~7주. 완료 기준은 화면 하나를 놓고 상태 목록을 먼저 적은 다음 컴포넌트를 나눌 수 있고, 어떤 값이 파생 값이라 상태로 두면 안 되는지 이유를 대며 판단할 수 있는 상태입니다. 체크포인트는 장바구니 화면입니다. 수량 변경, 항목 삭제, 합계, 쿠폰 적용까지 넣되 합계와 할인 금액은 절대 따로 저장하지 마세요. 자주 막히는 곳은 서버에서 받은 목록을 컴포넌트 안에 복사해 두고 편집하다가, 서버 갱신 후 화면이 옛 값으로 되돌아가는 현상입니다. 원본과 복사본 중 무엇이 진짜인지 정해지지 않아 생기는 문제이고, 해결책은 복사본을 없애거나 편집 중인 항목만 따로 관리하는 것입니다.

4단계 · 접근성과 폼 — 마우스 없이도 끝까지 되는가

접근성은 마지막에 얹는 마감재가 아니라 1단계 마크업의 결과입니다. 여기서는 그 결과를 점검하고 부족한 부분을 메웁니다. 키보드만으로 화면의 모든 기능에 도달할 수 있는지, 포커스가 지금 어디 있는지 눈으로 보이는지, 모달을 열었을 때 포커스가 그 안에 갇히고 닫으면 원래 자리로 돌아오는지. 이 세 가지가 실무에서 가장 자주 깨지는 지점입니다. ARIA 속성은 나중 문제입니다. 원칙은 단순합니다. 표준 요소로 되는 일에 ARIA를 쓰지 않는 것입니다.

폼은 프론트엔드에서 가장 지저분한 영역이고, 그래서 실력이 드러납니다. label과 입력을 연결하는 것, 오류 메시지를 해당 입력 옆에 두고 프로그램적으로도 연결하는 것, 언제 검증할지 정하는 것(입력 중에는 조용히, 포커스를 벗어나면 알려 주기), 제출 중 버튼을 잠가 중복 전송을 막는 것. 그리고 클라이언트 검증은 사용자를 돕기 위한 것일 뿐 신뢰의 근거가 아니라는 점은 반드시 기억해야 합니다. 서버 쪽 검증까지 포함한 이야기는 애플리케이션 보안 학습 로드맵에서 이어집니다.

기간: 3~4주. 완료 기준은 마우스를 뽑고 키보드만으로 자기 화면의 모든 흐름을 처음부터 끝까지 완료할 수 있고, 각 입력의 오류 상태가 화면과 보조 기술 양쪽에 전달되는 상태입니다. 체크포인트는 다단계 회원가입 폼입니다. 단계 이동, 뒤로 갔을 때 입력값 유지, 필드별 오류 표시, 제출 실패 시 첫 오류 필드로 포커스 이동까지 넣으세요. 자주 막히는 곳은 커스텀 드롭다운입니다. div로 흉내 낸 선택 상자는 키보드로 열리지 않고, 위아래 키가 먹지 않고, 화면 낭독기에서는 아무 의미 없는 글자 뭉치로 읽힙니다. 직접 만들기로 했다면 키보드 조작과 상태 전달까지 책임져야 하며, 그럴 여력이 없다면 표준 select를 쓰는 편이 낫습니다.

5단계 · 성능과 빌드 — 언제 느려지는지 알기

성능은 두 종류로 나눠 봐야 합니다. 처음 화면이 뜨기까지의 로딩 성능과, 뜬 뒤 조작에 반응하는 렌더링 성능입니다. 원인도 처방도 다릅니다. 로딩 쪽은 대개 내려받는 양의 문제입니다. 번들에 뭐가 들어 있는지 확인하고, 첫 화면에 필요 없는 코드를 나중에 받도록 미루고, 이미지 크기와 형식을 정리하고, 웹폰트가 글자를 가리지 않게 하는 정도로 상당 부분이 해결됩니다. 렌더링 쪽은 필요 없는 갱신의 문제입니다. 상태 하나가 바뀔 때 화면의 어느 범위까지 다시 그려지는지 측정해 보면, 대개 3단계의 상태 배치가 잘못된 결과라는 걸 알게 됩니다.

중요한 순서는 측정이 먼저라는 것입니다. 브라우저 성능 탭에서 기록을 남기고 어디에 시간이 쓰였는지 본 다음 손대야 합니다. 이 순서를 지키지 않으면 체감상 아무 차이 없는 최적화에 며칠을 씁니다. 빌드 도구는 이 단계에서 처음 제대로 볼 필요가 생깁니다. 소스를 어떻게 묶는지, 어떤 파일이 캐시되고 어떤 파일이 매번 새로 받아지는지, 배포된 코드에서 나온 오류를 원래 소스 위치로 되짚으려면 무엇이 필요한지 정도가 실무에 바로 쓰이는 범위입니다. 코드 자체의 실행 비용이 궁금해지면 JavaScript 성능을 참고하세요.

기간: 3~4주. 완료 기준은 자기 페이지의 로딩을 측정해 상위 세 개의 병목을 이름으로 댈 수 있고, 그중 하나를 고쳐 수치가 실제로 움직이는 것을 확인한 상태입니다. 체크포인트는 3단계에서 만든 장바구니 화면의 첫 로딩을 절반으로 줄이는 작업입니다. 손대기 전후의 측정값을 기록으로 남기고, 무엇이 얼마나 기여했는지 한 줄씩 적어 보세요. 자주 막히는 곳은 개발 서버에서만 측정하는 것입니다. 개발 빌드는 압축도 안 되어 있고 개발용 코드가 그대로 들어 있어서, 여기서 잰 숫자는 실제 사용자가 겪는 것과 거의 관계가 없습니다. 반드시 배포용 빌드를 만들고, 네트워크와 CPU를 낮춘 조건에서 재야 합니다.

지금은 미뤄도 되는 것

프론트엔드에서 목록에 올라오는 주제는 끝없이 늘어나지만, 첫 바퀴에서 빼도 손해가 없는 것들이 분명히 있습니다.

  • 서버 사이드 렌더링과 렌더링 전략 비교. 첫 화면 속도와 검색 노출이 실제 문제가 되었을 때 고르는 선택지입니다. 그 상황을 겪기 전에 배우면 용어만 남고, 상황이 오면 반나절이면 이해됩니다.
  • 상태 관리 라이브러리. 3단계에서 프레임워크가 기본으로 주는 수단만으로 버텨 보세요. 그 수단이 왜 부족한지 몸으로 겪은 다음에 라이브러리를 읽어야 그 설계가 무슨 문제를 푸는지 보입니다.
  • 디자인 시스템과 컴포넌트 라이브러리 제작. 재사용할 화면이 아직 몇 개 없는 시점에 추상화를 만들면, 나중에 그 추상화를 걷어내는 데 더 오래 걸립니다. 같은 화면 조각을 세 번째 복사할 때가 신호입니다.
  • E2E 테스트 자동화. 다만 테스트 자체를 미루라는 뜻은 아닙니다. 3단계의 상태 계산 함수처럼 입력과 출력이 분명한 부분에 작은 테스트를 붙이는 일은 오히려 시간을 아껴 줍니다. 시작하는 방법은 아주 작은 케이스로 테스트 시작하기에 있습니다.

프레임워크를 고르는 문제로 돌아와서

이 로드맵을 통과하면 프레임워크 선택이 왜 생각만큼 중요한 결정이 아닌지 스스로 알게 됩니다. 다섯 단계에서 다룬 것 중 프레임워크에 종속된 지식은 3단계의 문법 일부뿐입니다. 나머지는 브라우저가 문서를 다루는 방식, 상태와 화면의 관계, 입력을 받아 검증하는 방식, 그리고 무엇이 시간을 잡아먹는지에 대한 감각이고, 이건 도구를 갈아타도 그대로 따라옵니다. 반대로 이 다섯 가지가 비어 있으면 어떤 프레임워크로도 같은 곳에서 막힙니다.

다음 걸음은 목표에 따라 갈립니다. 서버 쪽까지 스스로 만들고 싶다면 백엔드 로드맵이나 웹 개발 로드맵으로 이어지고, 만든 화면을 실제 사용자에게 열어 줄 계획이라면 보안 로드맵을 먼저 한 바퀴 도는 편이 안전합니다. 어떤 프로젝트로 연습할지부터 막힌다면 끝낼 수 있는 첫 프로젝트 고르기가 도움이 됩니다.