캐시(Cache)가 웹사이트 속도를 높이는 원리: 브라우저부터 CDN까지 작동 방식 완벽 정리

웹사이트 주소를 입력하고 화면이 뜨기까지 걸리는 시간은 서버의 처리 속도와 물리적 거리에 비례합니다. 캐시(Cache)는 이 시간을 단축하기 위해 한 번 불러온 이미지, CSS, 자바스크립트 파일 등의 데이터를 사용자 PC나 중간 서버에 임시로 저장해 두는 기술입니다. 원본 서버까지 매번 찾아가지 않고 가까운 곳에 저장된 복사본을 가져오므로, 평균 1~2초가 걸리던 로딩 속도가 10~50밀리초(ms) 수준으로 줄어듭니다.

특히 대용량 파일이나 자주 변하지 않는 웹페이지 구성 요소는 캐시의 효과를 가장 크게 봅니다. 웹 브라우저는 네트워크 대역폭을 아끼고 서버는 불필요한 연산 요청을 받지 않아 양쪽 모두의 자원을 절약할 수 있습니다. 캐시가 작동하는 구체적인 원리와 종류는 다양하며, 이를 올바르게 설정하는 것이 웹 성능 최적화의 핵심입니다.

브라우저가 사용자 컴퓨터 하드디스크를 임시 서버로 쓰는 방식

사용자가 웹사이트에 처음 방문하면 웹 브라우저는 서버로부터 텍스트 파일, 이미지, 로고 등 수십 개의 파일을 다운로드합니다. 이때 브라우저는 다운로드한 파일들을 컴퓨터의 임시 저장 공간(디스크 또는 메모리)에 보관합니다. 동일한 페이지를 다시 방문하거나 다른 페이지로 이동할 때, 브라우저는 서버에 파일을 요청하기 전에 로컬 저장소에 해당 파일이 있는지 먼저 확인합니다.

로컬에 파일이 존재하고 유효 기간이 만료되지 않았다면 네트워크 연결을 아예 시도하지 않습니다. 컴퓨터 하드디스크(SSD)나 RAM에서 파일을 즉시 읽어와 화면에 뿌려줍니다. 이 과정을 개발자 도구에서 직접 확인할 수 있습니다. 구글 크롬 브라우저에서 F12를 눌러 개발자 도구를 열고 Network 탭으로 이동한 뒤 웹페이지를 새로고침(F5)해 봅니다.

네트워크 목록의 Size 항목을 보면 숫자가 아닌 (disk cache)(memory cache)라고 표시된 행들을 볼 수 있습니다. 이는 인터넷 망을 타고 물리적인 웹 서버에서 가져온 것이 아니라, 사용자 컴퓨터 내부 저장소에서 파일을 0ms 만에 불러왔다는 의미입니다. 웹 브라우저는 이 방식으로 네트워크 데이터 소모량을 줄이고 렌더링 속도를 극대화합니다.

웹 서버가 브라우저에게 내리는 기간 한정 명령, Cache-Control

컴퓨터에 저장된 파일이 평생 그대로 유지된다면 웹사이트 디자인이 바뀌어도 사용자는 옛날 화면만 보게 됩니다. 이를 방지하기 위해 웹 서버는 파일을 보낼 때 HTTP 응답 헤더에 캐시 유지 기간과 규칙을 명시합니다. 이 명령어가 바로 Cache-Control입니다.

가장 흔히 쓰이는 설정은 Cache-Control: max-age=31536000입니다. 여기서 숫자의 단위는 초(second)입니다. 31,536,000초는 정확히 1년입니다. 로고 이미지나 폰트처럼 1년 동안 바뀔 일이 거의 없는 파일에 이 설정을 부여합니다. 반면, 수시로 변하는 API 데이터나 HTML 파일에는 no-cache 또는 no-store 설정을 붙입니다.

no-store는 브라우저에게 어떤 캐시도 저장하지 말고 매번 새로운 데이터를 받아오라고 강제하는 명령어입니다. 개인정보가 포함된 페이지나 결제 화면에 주로 쓰입니다. 반면 no-cache는 이름과 달리 캐시를 저장하긴 하지만, 사용하기 전에 반드시 서버에 “이 파일이 유효한지” 한 번 물어보라는 명령입니다. 이 미세한 차이를 오해하면 웹사이트의 업데이트가 반영되지 않거나 반대로 서버 트래픽이 폭증하는 문제가 생깁니다.

만약 메인 페이지를 구성하는 index.html 파일에 실수로 1년짜리 캐시를 설정하면, 사이트를 개편해도 사용자들은 1년 동안 이전 메인 페이지만 보게 되는 대참사가 벌어집니다. 따라서 정적 파일의 특성에 맞춰 세밀하게 기간을 조정해야 합니다.

변하지 않은 파일은 재사용하는 유효성 검사 서명, ETag

Cache-Control 기간이 만료되었거나 no-cache 설정이 되어 있다면 브라우저는 서버에 접속해야 합니다. 하지만 서버에 접속했다고 해서 무조건 대용량 파일을 다시 처음부터 다운로드할 필요는 없습니다. 파일 내용이 이전과 완전히 똑같다면 말입니다. 이때 사용하는 도구가 바로 ETag(Entity Tag)입니다.

ETag는 특정 파일의 고유한 해시값(지문과 같은 역할)입니다. 서버는 파일을 전송할 때 헤더에 ETag: "W/5f8d9a2b" 같은 임의의 서명을 붙여 보냅니다. 브라우저는 파일과 함께 이 서명을 저장해 둡니다. 이후 캐시 유효 기간이 지나 서버에 파일을 다시 요청할 때, 브라우저는 헤더에 If-None-Match: "W/5f8d9a2b"라는 질문을 동봉해 보냅니다.

서버는 자신이 가진 현재 파일의 해시값과 브라우저가 보낸 값을 비교합니다. 두 값이 일치한다면 파일이 전혀 수정되지 않았다는 뜻입니다. 이 경우 서버는 본문 데이터를 보내지 않고 304 Not Modified라는 상태 코드만 응답합니다. 본문 데이터가 없으므로 응답 크기는 수백 바이트에 불과하며, 브라우저는 기존에 가지고 있던 캐시 파일을 그대로 재사용합니다.

이 유효성 검증 과정 덕분에 사용자는 기가바이트 단위의 웹사이트 데이터를 매번 새로 받지 않고도 항상 최신 상태를 유지할 수 있습니다. 겉보기에는 서버와 통신하는 것처럼 보이지만 실제 데이터 전송량은 0에 가깝기 때문에 화면 로딩이 끈김없이 매끄럽게 진행됩니다.

대륙 간의 물리적 거리 문제를 해결하는 CDN 캐싱

한국에 있는 사용자가 미국 오레곤주에 서버가 있는 웹사이트에 접속하면 빛의 속도로 전파가 이동하더라도 물리적 거리로 인한 지연 시간(Latency)이 발생합니다. 패킷이 바다 밑 해저 광케이블을 왕복하는 데만 최소 150ms 이상이 걸립니다. 이를 해결하기 위해 전 세계 주요 거점에 캐시 서버를 둔 네트워크가 CDN(Contents Delivery Network)입니다.

Cloudflare나 AWS CloudFront 같은 CDN 서비스를 적용하면, 원본 서버의 파일 복사본이 전 세계 엣지(Edge) 서버에 분산 저장됩니다. 서울에 있는 사용자가 접속하면 오레곤 서버가 아니라 서울 가산동에 있는 CDN 엣지 서버가 응답합니다. 물리적 거리가 몇천 킬로미터에서 수십 킬로미터 수준으로 줄어드는 것입니다.

이를 통해 웹사이트의 첫 번째 바이트를 받는 시간인 TTFB(Time to First Byte)가 획기적으로 개선됩니다. CDN 캐싱은 주로 이미지, 비디오, 대형 자바스크립트 라이브러리에 적용됩니다. 원본 서버의 트래픽 부담을 80% 이상 줄여주기 때문에 대규모 트래픽이 몰려도 서버가 다운되지 않도록 방어하는 역할도 수행합니다.

최근에는 이미지 최적화 기능도 CDN 캐시 단계에서 처리합니다. 사용자의 기기 환경에 맞춰 png 파일을 webp 포맷으로 실시간 변환하여 캐싱해 두는 방식으로 용량을 줄이고 로딩 속도를 한 번 더 끌어올립니다.

데이터베이스 부하를 줄이는 서버 내부 메모리 캐싱

웹사이트의 속도를 느리게 만드는 주범 중 하나는 데이터베이스(DB) 조회입니다. 사용자가 게시판 목록을 누르거나 상품 검색을 할 때마다 웹 서버는 하드디스크에 저장된 DB를 뒤져 결과를 만들어내야 합니다. 사용자가 많아지면 DB 서버의 CPU 사용률이 100%에 도달하며 웹사이트가 마비됩니다.

이 문제를 해결하기 위해 서버 개발자들은 Redis(레디스)나 Memcached(멤버캐시디) 같은 인메모리(In-Memory) 캐시 시스템을 사용합니다. 관계형 데이터베이스(MySQL, PostgreSQL 등)보다 백 배 이상 빠른 RAM 영역에 자주 조회되는 데이터를 키-값(Key-Value) 형태로 저장해 두는 방식입니다.

예를 들어 메인 페이지의 ‘실시간 인기 상품 목록’은 매번 DB에서 정렬 쿼리를 돌릴 필요가 없습니다. 5분에 한 번씩만 DB에서 조회해 Redis 캐시에 올려두고, 사용자가 요청할 때는 Redis에 있는 데이터를 즉시 반환합니다. 컴퓨터의 RAM은 밀리초 미만의 속도로 응답하므로 사용자는 대기 시간 없이 즉각적인 화면을 마주하게 됩니다.

이러한 서버 캐시는 데이터 만료 시간(TTL, Time To Live) 관리가 매우 중요합니다. 너무 길게 잡으면 재고 수량이나 가격 정보가 실제와 달라지는 문제가 생기고, 너무 짧게 잡으면 캐시를 쓰는 의미가 퇴색되므로 데이터의 성격에 맞는 정교한 만료 정책 설계가 뒤따라야 합니다.

개발자의 업데이트가 사용자에게 안 보일 때 대처하는 법

캐시는 웹사이트 속도를 빠르게 만들어 주지만, 치명적인 단점도 존재합니다. 개발자가 버그를 수정하여 app.js 파일을 서버에 새로 올렸는데도, 사용자의 브라우저가 예전 캐시 파일을 계속 사용하면 화면이 깨지거나 기능이 작동하지 않는 오류가 발생합니다.

이 현상이 발생했을 때 일반 사용자가 취할 수 있는 가장 단순한 방법은 강력 새로고침입니다. 윈도우 크롬 기준으로 Ctrl + Shift + R을 누르고, 맥OS에서는 Cmd + Shift + R을 누르면 브라우저는 로컬 캐시를 완전히 무시하고 서버에서 무조건 모든 파일을 새로 내려받습니다. 하지만 모든 사용자에게 일일이 이 단축키를 누르라고 요구할 수는 없습니다.

실제 서비스에서는 이 문제를 해결하기 위해 ‘캐시 버스팅(Cache Busting)’ 기술을 사용합니다. 파일의 이름 뒤에 고유한 버전 번호나 해시값을 붙이는 기법입니다. 예를 들어 <script src="main.js"></script> 대신 웹팩(Webpack) 같은 빌드 도구를 사용하여 <script src="main.a8f9b2.js"></script>처럼 파일명을 빌드할 때마다 동적으로 변경합니다.

파일명이 완전히 바뀌었기 때문에 브라우저는 이를 이전에 다운로드한 적이 없는 완전히 새로운 파일로 인식합니다. 결국 캐시 저장소를 우회하여 새 파일을 즉시 다운로드하게 됩니다. 이 기법을 도입하면 평소에는 브라우저 캐시 기간을 1년으로 길게 설정하여 로딩 속도를 최대로 확보하면서도, 사이트가 업데이트되는 즉시 모든 사용자에게 오류 없이 변경 사항을 반영할 수 있습니다.

Leek
Leek

브라우저 캐시부터 서버·CDN 캐시까지, 웹사이트 속도를 느리게 만드는 원인을 직접 테스트해 보고 기록합니다. 캐시 오류 해결, 워드프레스 캐시 설정, 페이지 로드 속도 개선을 주로 다루며, 개념 설명에 그치지 않고 실제 화면과 수치를 확인한 내용을 쓰려고 합니다.

기사 : 13

댓글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다