Articles

[번역] Strategies for Cache-Busting CSS

Bittersweet- 2023. 3. 16. 16:43
728x90

** 번역에 의역과 오역이 충분히 있을 수 있으므로, 가능하신 분들은 그냥 아래의 링크로 가셔서 원문을 읽어보시길 추천합니다~

 

https://css-tricks.com/strategies-for-cache-busting-css/

 

Strategies for Cache-Busting CSS | CSS-Tricks

Major performance gains are to be had from browser caching CSS. You ensure your server is set up to send headers that tell the browser to hang onto the CSS

css-tricks.com

 

CSS 브라우저 캐싱에서 주요 성능을 향상 시킬 수 있다. 주어진 시간동안 CSS 파일을 파악하도록 브라우저에게 알리는 헤더를 보내도록 서버가 설정되어있는지 확인한다. 대부분의 사이트는 아니더라도 많은 사이트에서 이미 실행하고 있는 모범 사례이다.

캐시 버스팅은 브라우저 캐싱와 관련 있다. 브라우저에 1년된 CSS 파일의 캐시가 있다고 가정하자.(흔하지 않음) 그런데 CSS를 바꾸길 원한다면 기존의 캐시를 버리고 새로운 CSS파일을 무조건 받도록 만들어야 한다.

아래에 몇가지 방법이 있다.

 

 

CSS가 캐시에 저장되는 것을 활용한다.

확인을 위해 아래 CSS파일이 정상적으로 캐시된 headers를 볼 수 있다.

Cache-Control과 Expires를 찾아보자. 나는 server 구성의 전문가가 아니다. H5BP server 구성을 살펴보자. 하지만 이를 수행하기 위한 몇가지 고전적인 Apache/HTAccess 방법이 있다.

<FilesMatch "\\.(ico|pdf|flv|jpg|jpeg|png|gif|js|css|swf)(\\.gz)?$">
  Header set Expires "Thu, 15 Apr 2020 20:00:00 GMT"
</FilesMatch>
<IfModule mod_expires.c>
  ExpiresActive on
  ExpiresByType text/css                  "access plus 1 year"
  ExpiresByType application/javascript    "access plus 1 year"
</IfModule>
  • H5BP(HTML5 BoilerPlate)

필수적인 스타일과 폴리필, 모더나이저 같은 툴을 포함하여 HTML5를 사용함에 있어 크로스 브라우징을 좀 더 쉽게 도와주는 템플릿

  • H5BP/server-configs-apache

github

Apache Server Configs는 서버가 웹 사이트의 성능과 보안을 개선하는데 도움이 되는 구성 스니펫 모음으로 리소스가 올바른 콘텐츠 유형으로 제공되고 필요한 경우, 도메인 간 엑세스가 가능하도록 한다.

 

 

Query Strings

요즘 대부분의 브라우저는 다른 query string이 있는 url을 다른 파일로 보고 새 사본을 다운로드 한다.

대부분의 CDN은 이를 지원하고 권장하기도 한다.

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

수정 한 후 함께 수정한다.

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

여러 곳에서 사용할 서버 측 변수를 설정하여 잠재적으로 더 쉽게 만들 수 있다. 따라서 한번에 수정이 가능하다.

<?php $cssVersion = "3.4.2"; ?>

<link rel="stylesheet" href="global.css?v=<?php echo $cssVersion; ?>">

Semantic Versioning(major.minor.patch)방식을 사용할 수도 있고 상수를 정의할 수도 있다.

 

 

파일 이름 바꾸기

query string이 언제나 먹히진 않는다. 어떤 브라우저들은 각기 다른 query string을 다른 파일이라고 보지 않는다. 그리고 일부 소프트웨어(들은바로는 Squid)는 query string이 있는 파일은 캐시하지 않는다.

Steve Souders는 이 방법을 반대했다.

비슷한 방법으로는 아래와 같이 HTML에서 파일이름을 바꾸는 것이 있다.

<link rel="stylesheet" href="style.232124.css">

말 그대로 프로젝트 내의 파일명을 변경하는 것이 아니라 프로그래밍 방식으로 처리할 수 있다. 파일이 서버에 실제로 존재하지 않기 때문에 올바른 파일로 라우팅하려면 몇가지 트릭을 수행해야 한다. Jeremy Keith는 최근 이에 대한 자신의 기술을 다루었다.

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.+).(\\d+).(js|css)$ $1.$3 [L]

이것은 서버로 하여금 javascript와 css 파일에 있는 숫자를 무시하도록 지시하지만 브라우저는 해당 번호를 업데이트할 때마다 여전히 새 파일로 해석한다.

그는 Twig를 사용해, 그가 쓰는 템플릿은 대충 아래와 같다.

{% set cssupdate = '20150310' %}

<link rel="stylesheet" href="/css/main.{{ cssupdate }}.css">

ASP같은 백엔드 언어에서 그 버전을 상상할 수 있다고 확신한다. 빌드 툴 또는 배포 스크립트가 변수 자체를 업데이트 하도록 레벨을 올려야 한다.

 

 

파일 업데이트 날짜를 기준으로 캐시 무효화 “숫자” 지정

캐시 무효화를 찾아보는 동안, 서버를 이용해서 파일이 언제 업데이트되어 캐시파일이 생성되었는지 숫자를 사용하라는 글을 많이 보았을 것이다. (숫자, 의미, 버스트 캐시로 변경하는 모든 것)

function autoversion($url) {
  $path = pathinfo($url);
  $ver = '.'.filemtime($_SERVER['DOCUMENT_ROOT'].$url).'.';
  return $path['dirname'].'/'.str_replace('.', $ver, $path['basename']);
}
<link href="<?php autoversion('/path/to/theme.css'); ?>" rel="stylesheet">

나는 이 방법을 추천하지 않는다. 모든 페이지뷰에서 이 정보를 파헤치도록 서버에 요청하는 것은 프로덕션에 매우 집약적이고 위험할 것 같다.

과거에는 “데이터 속성에 있는 이미지 치수를 PHP가 출력하도록 하겠다”와 같은 작업을 수행했다. 그것을 찾기 위해서만 서버가 중단된다. 조심하길 바란다.

 

 

ETags

ETags는 좋은 생각으로 보여진다. 왜냐하면 모든 것의 포인트는 만약 브라우저가 이미 파일의 복사본을 가지고 있는지 없는지에 대한 정보를 체크하는 것이기 때문이다.

하지만 대부분이 이렇게 충고했다. “ETags headers를 꺼라”. yahoo를 보면

ETags의 문제점은 일반적으로 사이트를 호스팅하는 특정 서버에 고유하게 만드는 속성을 사용하여 생성된다는 것이다. 브라우저가 한 서버에서 원래 구성 요소를 가져오고 나중에 다른 서버에서 해당 구성 요소의 유효성을 검사하려고 하면 ETags가 일치하지 않는다. 이러한 상황은 서버 클러스터를 사용하여 요청을 처리하는 웹사이트에서 너무 일반적이다.

또 다른 이슈는 그것은 실제 캐싱하는 것처럼 효율적이지 않다는 점이다. ETags를 체크하기 위해서는 네트워크 요청이 여전히 필요하다. 성능에 영향을 미치는 것은 파일 다운로드 뿐만 아니라 모든 네트워크 협상 및 대기 시간 문제이다.

다시한번 말하지만 나는 전문가가 아니다. 하지만 여기 아파치에서 이 부분 일반적으로 끄기를 추천된다.

<IfModule mod_headers.c>
  Header unset ETag
</IfModule>
FileETag None

 

 

프레임워크가 대신 해줌

나는 Rail Asset Pipeline과 Sprockets을 살짝 경험해 본적 있다. 누가 내게 묻는다면, 이것은 꿈같은 시스템이었다. 템플릿에서 스타일 시트를 연결했다.

<%= stylesheet_link_tag "about/about" %>

그리고 HTML은 아래와 같다.

<link href="http://assets.codepen.io/assets/about/about-7ca9d3db0013f3ea9ba05b9dcda5ede0.css" media="screen" rel="stylesheet" type="text/css" />

캐시 버스팅 숫자는 파일이 수정되었을 때만 변경된다. 따라서 캐싱하고자 하는 파일만 캐싱할 수 있게 된다. 이것은 이미지 및 JavaScript에 대한 메서드도 있다.

 

 

워드 프레스

W3 Total Cache와 같은 워드프레스의 페이지 캐싱 도구를 사용하는 경우, 해당 filemtime 비즈니스가 너무 서버 집약적인 것을 두려워해야 한다.

워드프레스의 특별한 테크닉에 대해 포스팅 한 Gilbert Pellegrom 가 이것을 사용한다.

wp_register_style( 'screen', get_template_directory_uri().'/style.css', array(), filemtime( get_template_directory().'/style.css' ) );
wp_enqueue_style( 'screen' );

// Example Output: /style.css?ver=1384432580

워드프레스 플러그인으로 똑같은 일을 수행하는데 모든것이 자동이다.

 

 

Codekit

CodeKit은 파일이름 변경 메서드는 가지고 있지 않지만 설정해 놓은 환경 밑에 쉘 스크립트를 실행시킬 수 있는 방법을 가지고 있다.

Michael Russell은 블로그에 timestamp를 파일에 주입시키는 방법에 대해 포스팅한 적이 있다. 그 방법으로 파일명을 수정할 수 있을 꺼라고 생각한다.

 

 

Build Tools

모든 인기 있는 task runner나 build tool은 파일명을 변경하는 플러그인을 가지고 있다. Sufian Rhazi는 블로그에 Node.js로 파일명을 변경하는 방법에 대해 포스팅했다.

다른 asset에 나의 asset을 연결하는 경우(예를 들어 less 파일에서 연결한 이미지 등) 우리는 전처리기를 둘 수 있다. Ben Nadel 블로그에 방법을 포스팅 했다.

 

 

Async CSS

치명적인 CSS가 더 중요해짐에 따라 CSS의 지연 로딩 문제가 더 중요해지고 있다. CSS의 로딩이 지연되는 다른 이유들도 있다.(print CSS 또는 priming cache)

<aside> ⏰ priming(점화) - 나의 자극에 노출됨으로써 의식적인 지침이나 의도 없이 후속 자극에 대한 반응에 영향을 미치는 현상

</aside>

만약 loadCSS로 CSS를 로딩(또는 링크 태그를 삽입하는 경우) 하고 있다면, 자바스크립트 자체에서 파일 이름을 업데이트 해야 한다. 파일 이름 변경과 다르지만 또 결과적으론 다르지 않다.

 

 

So

빼먹은 것은 없나? 당신의 캐시 무효화 전략은?