프론트엔드/성능 최적화

로딩 성능 최적화 - 캐시

정현우12 2023. 4. 28. 18:12

캐시 최적화

캐시 활용 위해서 Cache-Control 설정 필요 -> 빌드된 파일을 서비스하는 서버에서 설정

  • no-cache: 캐시를 사용하기 전에 서버에 검사 후, 사용 결정
  • no-store: 캐시 사용 안 함
  • public: 모든 환경에서 캐시 사용 가능
  • private: 브라우저 환경에서만 캐시 사용, 외부 캐시 서버에서는 사용 불가
  • max-age: 캐시의 유효시간 , max-age = 0 해도 캐시 된 리소스를 버리지 않고 가지고 있는다. 추후 요청시 수정 여부 확인 후 활용

사용 예시

  • cache-control: private, max-age=60

Express를 활용한 간단한 구현 예시

1) 캐시를 전혀 사용하지 않을 때

no-store만 주지 않은 이유는 브라우저 중 no-store으로만 캐시 사용 해제가 안되는 경우가 있다.

const header = {
    setHeaders: (res, path) => {
        res.setHeader('Cache-Control', 'private, no-cache, no-store, must-revalidate')
        res.setHeader('Expires', '-1')
        res.setHeader('Pragma', 'no-cache')
    },
}

app.use(express.static(path.join(__dirname, '../build'), header))
app.get('*', (req, res) => {
    res.sendFile(path.join(__dirname, '../build/index.html'))
})

app.listen(port, () => console.log(`Example app listening at http://localhost:${port}`))
  1. 리소스별 다른 캐시 설정하기
  • HTML: no-cache - 항상 최신 버전 유지하기 위해서 (no-store 안쓰는 이유: 변경 안된 경우 리소스 전체를 no-cache는 다시 다운하지 않기 때문)
  • JS,CSS: public, max-age=31536000 - 빌드시 파일명에 해시 값이 붙어 있다. HTML이 최신 버전으로 유지되면, 자동으로 JS, CSS파일도 자동으로 유지된다.
  • IMG: public, max-age=31536000이미지가 변경되지 않는 경우엔 캐시 적용, 자주 변경되면 캐시 기간 짧게 하거나 해시를 달아 준다.
const header = {
    setHeaders: (res, path) => {
        if(path.endsWith('.html')){
            res.setHeader('Cache-Control', 'no-cache')
        } else if(path.endsWith('.js') || path.endsWith('.css') || path.endsWith('.webp')) {
            res.setHeader('Cache-Control', 'public, max-age=31536000')
        } else {
            res.setHeader('Cache-Control', 'no-store')
        }
    },
}

이런식으로 헤더 설정을 분기를 쳐서 다르게 Cache-Control을 설정한다.

ETag

캐시한 리소스 별 해시 값

브라우저가 리소스가 변경됐는지 확인하기 위해 ETag만 서버에 먼저 보내서 확인