이미지 알기 : 캐싱과 캐싱 피하기

윤슬기·2021년 2월 21일
3
post-thumbnail

캐싱이란

캐싱은 파일 사본을 캐시 혹은 임시 저장소에 저장해서, 보다 빠르게 접근할 수 있도록 하는 하나의 프로세스다. 파일 또는 데이터 사본을 임시 저장하는 위치를 범용적으로 캐시라고 부른다.


브라우저의 캐싱

웹페이지에 접속한 사용자가 웹페이지를 로드할 때, 브라우저는 해당 웹 페이지를 표시하려고 많은 데이터를 요청하고 받는다. 이런 페이지 로드 시간을 줄이기 위해, 브라우저는 웹페이지에 필요한 콘텐츠를 캐싱해 사본을 사용자가 접속중인 기기의 하드 드라이브에 저장한다. 이렇게 하면 다음번에 사용자가 같은 페이지에 접속했을 때, 필요한 대부분의 콘텐츠가 이미 로컬에 저장되어 있기에 페이지가 훨씬 더 빠르게 로드된다. 더불어 서버에 요청하는 데이터양이 줄어 네트워크 트래픽도 줄어든다.

브라우저는 캐싱된 파일의 유효기간이 만료되거나 저장공간에 캐시가 가득 찰 때까지 파일을 저장한다. 캐시는 사용자가 원하는 때에 지울 수도 있다.

캐싱 설정은 각 콘텐츠와 상황에 맞게 조절하는것이 중요하다. 사용자가 그다지 다시 접속할 일이 없는 페이지의 콘텐츠, 매일 바뀔 정보들은 캐싱할 필요가 없다. 또 바뀔 일이 적다고 생각한 콘텐츠를 바꾸어야 할 땐, 사용자의 로컬에 저장된 캐시를 어떻게 피해갈지도 생각해야한다.


캐싱을 제어하는 HTTP 헤더

HTTP 캐시는 브라우저가 서버에 요청할 때 보내는 헤더와, 서버가 브라우저에 반환하는 헤더의 조합으로 결정된다. 브라우저는 별도로 설정하지 않아도 현재 캐시의 상황을 확인해서 자동으로 캐시 관련 헤더를 구성한다.

서버측에서는 파일 확장자 별, 디렉토리 별 등으로 캐시를 다르게 설정할 수 있다. 그런 세부적인 설정을 기본적으로 제공하는 서버도 있고, 알아서 설정해야 하는 서버도 있다.

캐싱과 관련된 HTTP 헤더 값은 세가지다.

  • Cache-Control
    브라우저나 중간 서버들이 어떤 방식으로, 얼마나 길게 응답을 캐싱할지 알리는 값
  • ETag
    브라우저는 유효기간이 만료된 콘텐츠를 발견하면, 작은 토큰을 서버로 보내서 파일이 바뀌었는지 체크합니다. 만약 서버가 같은 토큰을 반환한다면 파일이 변하지 않았다는 이야기므로, 해당 콘텐츠를 그대로 사용한다.
  • Last-Modified
    ETag와 같은 용도로 사용된다. 내용이 아닌 시간을 기반으로 콘텐츠가 변경되었는지 확인한다.

Cache-Control 의 주요 설정값

  • no-cache
    매번 다시 검증해야 하는 리소스용. 브라우저는 사용자에게 캐시된 사본을 보내기 전에, 서버에 검증을 요청한다.
  • no-store
    캐시되지 말아야 할 리소스용. 리소스는 브라우저에 저장되지 않는다. 브라우저는 접속할 때마다 매번 서버에 리소스를 요청한다.
  • max-age=[sec]
    리소스가 유효하다고 판단되는 시간을 초로 설정한다. 유효시간은 요청된 시간부터 계산된다. 앞으로 변경될 가능성이 적어서, 리소스가 오랫동안 캐싱되기를 원할 때는 값을 31536000 로 설정한다. 이는 1년을 초로 계산한 값이다.

캐싱 방지하기

당분간 변하지 않을 리소스들 - 예를 들어 사이트 로고 이미지 - 은 대부분 긴 기간동안 캐싱되도록 설정한다. 예를 들어 웹사이트에서 logo.jpeg 파일을 사용하고 있다고 하자.

<img src="/images/logo.jpeg" />

만약 사용자가 해당 이미지를 로컬에 캐싱한 상태라면, 이 이미지를 삭제하거나, 변경된 파일을 같은 이름으로 업데이트해도 로컬에 저장된 버전을 보게된다. 바뀐 콘텐츠를 제때 보여주려면, 예전에 캐싱된 이미지를 피해가야한다. 해시값이나 버전명을 파일명 혹은 파라미터로 더해서 브라우저가 값을 새로 받도록 만들 수 있다.


파일명에 해시를 더하기

기본적으로는 파일명을 바꾸는 방법이다. 기본 파일명 뒤에 해시값이나 버전명을 더한다. 이 과정은 대체로 webpack같은 빌더에게 자동으로 맡기게 된다.

<img src="/images/logo.2385124.jpeg" />

webpack의 경우, 설정 가능한 환경이라면 이미지를 사용할 때 import 하여 사용한 후, file-loader혹은 url-loader 를 설정하고 파일명 빌드 옵션을 [name].[contenthash].[ext] 처럼 설정한다. [contenthash] 는 파일이 변경된 경우에만 새로운 해시값을 부여한다.

// 이미지 사용 시 import
import sampleImage from "../images/sample.jpeg";
// webpack loader 설정
  module: {
    rules: [
      {
        test: /\\.(png|jpg|jpeg|svg|gif)$/,
        loader: "url-loader",
        options: {
          name: "[name].[contenthash].[ext]",
          limit: 4000,
        },
      },
    ],
  },

요청 주소 뒤에 해시 파라미터를 더하기

파일명을 그대로 사용하고 싶다면, 요청 주소 뒤에 파라미터를 붙이고 해시값이나 버전명을 할당한다. 그러면 브라우저는 URL이 변경되었다고 인식하고, 서버에 리소스를 새로 요청한다. 파라미터 명이나 값은 임의로 정하면 된다. 파일을 업데이트 할 때, 파라미터를 새로 바꾸어주어야 한다.

<img src="/images/logo.jpeg?version=2.0" />
  • 이미지 경로 뒤에 파라미터를 붙이고 해시값이나 버전명을 할당한다.
    그러면 브라우저는 URL이 변경되었다고 인식하고, 서버에 리소스를 새로 요청한다.
  • 파일을 업데이트 할 때, 파라미터를 새로 바꾸어주어야 한다.

참고한 글

profile
👩🏻‍💻

0개의 댓글