들어가며
우리가 React.js 로 작성한 웹사이트를 클라이언트에서 public하게 접속할 수 있게 하려면
프로젝트를 build하여 웹 서버를 통해 배포해야 한다. (주로 webpack으로 build)
그러나 코드가 변경되었을 때마다
모든 파일을 새롭게 빌드하여 배포하는 것은 리소스 혹은 네트워크 측면에서 매우 비효율적일 것이다.
이 과정을 최대한 효율적으로 관리하기 위해
번들러(webpack)는 파일명에 해시값을 부여하고, 웹서버(Nginx)는 빌드된 파일을 캐시하여 제공한다.
이 과정이 어떻게 이루어지는지 살펴보자.
필요성
위 과정이 필요한 이유는 크게 다음과 같다.
- 버전 관리 및 캐싱 효율성
- 각 빌드 파일에 해시가 포함되면 파일 내용이 변경될 때마다 파일 이름이 변경된다.
- 브라우저와 CDN(Contents Delivery Network)에서 새 파일을 캐시하도록 강제할 수 있다.
- 새로운 버전의 애플리케이션을 배포할 때, 오래된 캐시를 사용자에게 제공해도 문제가 발생하지 않는다.
- 클라이언트 성능 향상
- 클라이언트가 빌드 파일을 다운로드한 후 브라우저에서 캐시한다.
- 재방문시 동일 파일을 재다운로드하지 않고 캐시된 파일을 사용하여 페이지 로드 시간을 줄일 수 있다.
- 보안 강화 및 디버깅 용이
- 파일이 변조되거나 손상된 경우 브라우저에서 감지하고 로드하지 않도록 할 수 있다.
- 특정 버전의 소스 코드와 연결된 해시를 사용하여 문제를 식별하고 해결할 수 있다.
Webpack : Hash Filename
webpack에서는 build 결과 생성된 chunk 이름에 해시값을 부여한다.
webpack.config.js 파일 내 hash 로직
정말 변경이 있는 파일만 해시값이 바뀔까?
파일 확장자에 따라서 그 전략이 다를 것 같은데,
실제 파일 변경 후 빌드를 해서 전후 차이를 살펴보도록 하자.
파일 변경 전후 빌드파일 해시값 비교표. 초록 음영은 css 파일
파일 수정 전후 빌드 디렉토리 내 파일명을 비교하여 표로 정리해 보았다.
특징은 아래와 같았다.
- 파일 수정과 상관없이 파일 번호는 유지된다.
- 수정된 js 파일에 한해, 해시 값이 변경된다.
- css 파일의 경우 항상 변경된다.
Nginx : Cache Setting
- 기본적으로 gitlab의 ci/cd 배포 환경에서는 사용자의 cache를 활용하지 않음
- 다만, nginx 기반 배포 환경에서는 설정을 수정하여 캐시 활성화 가능
- 캐시를 위한 설정 로직을 .nginx.conf 에 추가
캐시 응답 여부 확인
네트워크 탭에서 확인 결과, 변경된 파일을 실제로 새롭게 제공하는 것을 확인할 수 있었다.
변경되지 않은 파일 (위 도표의 main.js)
변경된 파일 (위 도표의 59번 js 파일)
정리
- 빌드 파일에 해시값이 부여되고, 파일 내용에 수정이 있는 경우에만 해시값이 갱신된다.
- 해시값이 동일한 경우, 빌드 파일은 서버에 영구적으로 캐시된다.