본문 바로가기
홍TV 홍TV

“캐시버스팅 자동화하기”, 배포할 때마다 ?v=1.0.3 직접 바꾸고 있다면 꼭 보세요

홍TV 읽는 시간 약 12분
4.5
(300)

들어가며

웹사이트를 개발하다 보면 정말 자주 만나는 문제가 있습니다.

분명 CSS를 수정했습니다.

JavaScript도 수정했습니다.

서버에 배포한 것도 확인했습니다.

그런데 이상하게 내 브라우저에서는 예전 화면이 계속 보입니다.

개발자 도구를 열어보면 서버에 있는 파일은 수정된 것 같은데 브라우저는 이전 CSS나 JavaScript를 사용하고 있습니다.

이럴 때 가장 먼저 의심해볼 수 있는 것이 브라우저 캐시입니다.

그래서 많은 개발자가 이런 식으로 처리합니다.

<link rel="stylesheet" href="/css/style.css?v=1.0.1">
<script src="/js/common.js?v=1.0.1"></script>

파일을 수정하면 버전을 바꿉니다.

<link rel="stylesheet" href="/css/style.css?v=1.0.2">
<script src="/js/common.js?v=1.0.2"></script>

이 방법 자체는 간단하고 효과도 있습니다.

문제는 프로젝트가 커지면서 생깁니다.

CSS 파일이 10개이고 JavaScript 파일이 20개라면 배포할 때마다 버전을 하나씩 관리하는 것부터 귀찮아집니다.

그래서 이번에는 캐시버스팅 버전을 자동으로 올리는 방법을 알아보겠습니다.

캐시버스팅이 필요한 이유

브라우저는 웹페이지를 빠르게 보여주기 위해 CSS, JavaScript, 이미지 같은 정적 파일을 캐시에 저장합니다.

예를 들어 사용자가 다음 파일을 처음 요청했다고 해보겠습니다.

/css/style.css

브라우저가 이 파일을 내려받은 뒤 캐시에 저장할 수 있습니다.

그런데 개발자가 서버의 style.css를 수정했습니다.

사용자가 다시 접속했을 때 브라우저가 무조건 새로운 파일을 받는 것은 아닙니다.

캐시 정책에 따라 기존 파일을 사용할 수 있습니다.

개발자 입장에서는 상당히 당황스럽습니다.

“서버 파일은 수정했는데 왜 사용자 화면은 그대로지?”

이런 상황이 생기는 겁니다.

여기서 캐시버스팅(Cache Busting)을 사용할 수 있습니다.

가장 단순한 방법은 URL 뒤에 버전 값을 붙이는 것입니다.

<script src="/js/common.js?v=1.0.1"></script>

다음 배포에서는

<script src="/js/common.js?v=1.0.2"></script>

처럼 변경합니다.

브라우저 입장에서는 URL이 달라졌기 때문에 새로운 리소스로 판단할 가능성이 높아집니다.

그런데 버전을 사람이 직접 바꾸는 것도 귀찮다

처음에는 별 문제가 없습니다.

1.0.0
1.0.1
1.0.2
1.0.3

하지만 실제 프로젝트에서는 이런 작업이 생각보다 자주 발생합니다.

CSS 한 줄 수정하고 버전 변경.

JavaScript 함수 하나 수정하고 버전 변경.

이미지 변경하고 버전 변경.

배포하면서 다시 버전 변경.

어느 순간 이런 코드가 생깁니다.

<link rel="stylesheet" href="/css/reset.css?v=1.0.7">
<link rel="stylesheet" href="/css/common.css?v=1.0.7">
<link rel="stylesheet" href="/css/main.css?v=1.0.7">

<script src="/js/common.js?v=1.0.7"></script>
<script src="/js/main.js?v=1.0.7"></script>

그리고 개발자가 배포하기 전에

1.0.7 → 1.0.8

을 직접 수정합니다.

한두 번이면 괜찮습니다.

그런데 계속 반복되면 결국 버전 수정하는 것 자체가 하나의 작업이 되어버립니다.

그래서 여기서 캐시버스팅 버전 자동화를 생각하게 됩니다.

방법 1. 배포할 때마다 빌드 번호를 자동 증가시키기

가장 이해하기 쉬운 방법입니다.

예를 들어 현재 버전을 파일에 저장해둡니다.

version.txt

1.0.7

배포 스크립트가 실행되면 자동으로

1.0.8

로 변경합니다.

그리고 HTML을 생성할 때 해당 버전을 넣습니다.

<link rel="stylesheet" href="/css/style.css?v=1.0.8">

JavaScript도 동일합니다.

<script src="/js/common.js?v=1.0.8"></script>

이렇게 하면 개발자가 HTML을 직접 수정할 필요가 없습니다.

방법 2. 현재 시간을 버전으로 사용하기

간단한 프로젝트라면 시간값을 사용하는 방법도 있습니다.

예를 들어

?v=202609142100

같은 방식입니다.

배포 시간이 바뀌면 URL도 바뀝니다.

JavaScript에서 직접 만들 수도 있습니다.

const version = Date.now();

console.log(version);

결과는 대략 이런 형태가 됩니다.

1726318800000

HTML에서는

<script src="/js/common.js?v=1726318800000"></script>

처럼 사용할 수 있습니다.

다만 이 방법은 모든 요청에서 시간이 계속 바뀌는 구조로 만들어버리면 오히려 캐시의 장점을 잃을 수 있습니다.

따라서 페이지가 생성되는 시점 또는 배포 시점에 한 번 결정된 버전을 사용하는 것이 좋습니다.

방법 3. 파일 수정 시간을 이용하기

개인적으로 작은 프로젝트에서 꽤 편하게 사용할 수 있는 방식입니다.

파일이 수정된 시간을 버전으로 사용하는 것입니다.

예를 들어 main.css의 수정 시간이 변경되면

<link rel="stylesheet" href="/css/main.css?v=1726318800">

처럼 새로운 URL을 만들어줍니다.

파일을 수정하지 않았다면 같은 버전을 계속 사용합니다.

파일이 수정되면 버전이 변경됩니다.

이 방식의 장점은 꽤 명확합니다.

파일이 변경된 경우에만 캐시버스팅이 발생합니다.

방법 4. 빌드할 때 파일명 자체에 해시를 넣기

프로젝트가 커졌다면 단순한 ?v=1.0.8보다 이 방식을 많이 사용합니다.

예를 들어 원래 파일이

main.css

였다면 빌드 결과를

main.a83f92c.css

처럼 만드는 방식입니다.

JavaScript도

main.5f8a31d.js

처럼 만들 수 있습니다.

파일 내용이 변경되면 해시값도 변경됩니다.

예를 들어

main.a83f92c.css

main.b71d4e1.css

로 변경됩니다.

브라우저 입장에서는 완전히 다른 파일입니다.

이 방식은 Webpack, Vite 같은 빌드 도구를 사용하는 프로젝트에서 특히 편리합니다.

캐시를 강하게 적용해도 파일명이 변경되기 때문에 새로운 파일을 가져오게 만들 수 있습니다.

그렇다면 어떤 방법을 선택해야 할까?

프로젝트 규모에 따라 생각하면 편합니다.

간단한 HTML 프로젝트라면

style.css?v=1

방식도 충분합니다.

다만 버전을 직접 수정하는 것이 귀찮다면 배포 스크립트에서 자동 증가시키는 방법을 사용할 수 있습니다.

Node.js 같은 환경을 사용한다면 빌드 과정에 포함시키는 것도 좋습니다.

프로젝트가 커지고 번들링을 사용한다면

main.a83f92c.css
main.5f8a31d.js

같은 파일명 해시 방식을 추천합니다.

직접 버전을 올리는 것보다 중요한 것

여기서 한 가지 주의할 점이 있습니다.

캐시 문제가 발생한다고 해서 무조건 캐시를 없애는 방향으로 가면 안 됩니다.

캐시는 웹사이트 성능에 상당히 중요한 역할을 합니다.

문제는 “캐시가 있다”가 아니라 변경된 파일을 사용자가 제대로 가져오지 못하는 것입니다.

따라서 캐시버스팅의 목적은 캐시를 없애는 것이 아닙니다.

변경된 파일만 새로운 파일로 인식시키는 것에 가깝습니다.

예를 들어 파일이 변경되지 않았다면 기존 캐시를 계속 사용하는 것이 효율적입니다.

반대로 파일이 변경됐다면 새로운 버전을 요청하도록 만들어야 합니다.

이 차이를 이해하면 캐시 설정도 훨씬 편해집니다.

실제 개발에서는 배포 과정에 넣는 것이 가장 편하다

제가 캐시버스팅을 직접 관리한다면 가장 먼저 생각할 부분은 HTML을 매번 수정하지 않는 것입니다.

예를 들어 배포 과정에서

1. 소스 수정
2. 빌드
3. 버전 생성
4. HTML에 버전 반영
5. 서버 배포

가 자동으로 실행되도록 만들어놓는 것입니다.

그러면 개발자는 평소처럼 코드를 수정하고 배포만 하면 됩니다.

예를 들어

<script src="/js/main.js?v=${VERSION}"></script>

같은 형태의 템플릿을 사용하고,

배포 과정에서 ${VERSION}을 실제 버전으로 변경하도록 만들 수 있습니다.

더 나아가 빌드 도구에서 파일 해시를 생성하도록 설정하면 버전 관리 자체를 거의 신경 쓰지 않아도 됩니다.

캐시버스팅을 적용했는데도 예전 화면이 나온다면?

이 부분도 실제 개발에서 중요합니다.

캐시버스팅을 적용했는데도 화면이 그대로라면 브라우저 캐시만 의심해서는 안 됩니다.

다음 항목을 같이 확인해야 합니다.

브라우저 캐시
CDN 캐시
웹서버 캐시
프록시 캐시
Service Worker
HTML 자체의 캐시
정적 파일 캐시 정책

특히 PWA나 Service Worker를 사용하는 사이트라면 Service Worker가 이전 파일을 제공하고 있을 가능성도 있습니다.

이 경우 단순히

style.css?v=2

만 바꾸는 것으로 문제가 해결되지 않을 수도 있습니다.

마무리

캐시버스팅은 처음에는 아주 단순한 작업처럼 보입니다.

?v=1

하나 붙이면 끝나는 것처럼 보이기 때문입니다.

하지만 사이트를 계속 운영하다 보면 버전 관리가 생각보다 귀찮아집니다.

특히 CSS와 JavaScript 파일이 많아지면 배포할 때마다 사람이 버전을 수정하는 방식은 실수하기 쉽습니다.

그래서 개인적으로는 프로젝트 규모에 따라 자동화 수준을 결정하는 것이 좋다고 생각합니다.

작은 사이트라면 배포 시 버전 번호를 자동 증가시키고,

조금 더 큰 프로젝트라면 파일 수정 시간이나 빌드 번호를 활용하고,

빌드 시스템을 제대로 사용하는 프로젝트라면 파일명에 해시를 넣는 방식으로 넘어가는 것이 깔끔합니다.

결국 캐시버스팅의 핵심은 캐시를 없애는 것이 아닙니다.

변경되지 않은 파일은 캐시를 최대한 활용하고, 변경된 파일만 새로운 리소스로 인식시키는 것.

이렇게 생각하면 캐시버스팅과 정적 파일 캐시 정책을 훨씬 쉽게 이해할 수 있습니다.

그리고 가능하다면 ?v=1.0.3을 개발자가 직접 바꾸는 것보다 배포 과정에서 자동으로 버전을 생성하도록 만드는 것을 추천합니다.

처음에는 작은 자동화처럼 보이지만 배포 횟수가 늘어날수록 이런 작은 자동화 하나가 개발자의 반복 작업을 꽤 많이 줄여줍니다.

이 게시물이 얼마나 유용했나요?

별점을 클릭하여 평가하세요!

평균 평점 4.5 / 5. 투표 수: 300

아직 투표가 없습니다! 첫 번째로 평가해보세요.

홍TV

홍TV
함께 보면 좋은 글

댓글 0

첫 댓글을 남겨보세요.

error: Content is protected !!

광고 차단 알림

광고 클릭 제한을 초과하여 광고가 차단되었습니다.

단시간에 반복적인 광고 클릭은 시스템에 의해 감지되며, IP가 수집되어 사이트 관리자가 확인 가능합니다.