HTML6 Games설치없는 무료 웹 게임 / devlog

설치 없이, 지금 바로 플레이

브라우저에서 즐기는 무료 미니게임 모음. 로그인하면 기록이 계정에 저장되어 어느 기기에서든 이어서 볼 수 있어요.

게임 목록
게임 목록
모든 개발 이야기

배포했는데 한 시간 동안 예전 페이지가 보였다

2026년 10월 25일 · 운영 · English

새 버전을 배포했는데 한 시간쯤 예전 게임 목록이 그대로 보이는 일이 있었다. 코드는 맞게 배포되어 있었다. 캐시가 문제였다.

이 사이트는 Firebase Hosting 에 올라가 있다. 브라우저는 받은 파일을 얼마 동안 다시 받지 않고 쓸지를 응답의 Cache-Control 헤더로 정한다. max-age=3600 이면 한 시간 동안 서버에 묻지 않고 저장해 둔 것을 쓴다. 그 사이에 배포로 파일이 바뀌어도 브라우저는 모른다. 그래서 페이지가 바뀌는 사이트는 이 값을 신경 써서 정해야 한다.

Firebase Hosting 에서는 firebase.json 의 headers 에 주소 패턴별로 응답 헤더를 정할 수 있다. HTML, JS, CSS 에 캐시 설정을 주려고 이렇게 적었다.

{ "source": "**/*.@(js|css|html|glb)",
  "headers": [{ "key": "Cache-Control", "value": "public, max-age=0, s-maxage=604800" }] }

그런데 이 사이트는 cleanUrls 를 켜서 /ko/games/cloudhop 처럼 확장자 없는 주소를 쓴다. 실제로 열리는 파일은 cloudhop.html 이지만, 패턴은 파일 이름이 아니라 요청한 주소로 고른다. /ko/games/cloudhop 에는 .html 이 없어서 위 규칙에 걸리지 않았다.

규칙에 걸리지 않은 응답에는 Firebase 의 기본 캐시가 붙는다. 기본은 1시간(max-age=3600)이다. 사람들의 브라우저가 한 시간 동안 예전 페이지를 쓰는 것이다. 정작 문제가 된 것은 가장 많이 열리는 페이지(홈, 게임 페이지)가 이 확장자 없는 주소라는 점이었다.

예상하지 못한 일이라 이 문제를 발견하는데 한참이 걸렸다. 큰 문제가 아닐 수 있지만 새로 배포한 것이 나중에야 사용자들에게 적용된다면 여러 문제가 있을 수 있다.

확장자 없는 주소를 따로 잡는 규칙을 추가했다. 점(.)이 없는 모든 주소에 같은 헤더를 준다.

{ "regex": "^[^.]*$",
  "headers": [{ "key": "Cache-Control", "value": "public, max-age=0, s-maxage=604800" }] }

이 규칙은 / 와 /ko/games/cloudhop 처럼 점이 없는 주소에 걸리고, 점이 있는 /portal.js 나 /img/logo.png 에는 걸리지 않는다. 앞서 홈에만 따로 두었던 규칙도 이것으로 합쳤다.

헤더 규칙은 보내는 파일의 이름이 아니라 요청 주소로 고른다. 깔끔한 주소를 쓰는 사이트라면 확장자로 규칙을 적어도 대부분의 페이지가 걸리지 않을 수 있다. 헤더를 바꾼 뒤에는 실제 페이지 주소에 대한 응답 헤더를 한 번 확인해 보는 것이 안전하다.

참고한 문서

다른 글

홈 화면에 추가하기

  1. 화면 아래(아이패드는 위)의 공유 버튼을 누르세요. 네모에서 화살표가 위로 나온 모양이에요.
  2. 목록을 내려 "홈 화면에 추가"를 누르세요.
  3. 오른쪽 위 "추가"를 누르면 홈 화면에 HTML6 Games 아이콘이 생겨요.

Safari 에서만 추가할 수 있어요. 홈 화면에서 열면 주소창 없이 앱처럼 보이고, 인터넷이 끊겨도 열립니다.