bfcache(Back/Forward Cache)는 사용자가 페이지를 떠날 때 브라우저가 그 페이지를 없애지 않고 JS 힙까지 포함한 페이지 전체를 메모리에 얼려 두는 캐시다. 뒤로·앞으로 가기를 누르면 다시 로드하지 않고 얼려 둔 상태를 되살려 거의 즉시 보여 준다. 얼어 있는 동안 타이머와 프로미스 처리 같은 JS 실행은 멈춘다.
HTTP 캐시와 다른 점
| | HTTP 캐시 | bfcache | | --- | --- | --- | | 저장하는 것 | 응답(HTML·JS·이미지 파일) | 만들어진 페이지(DOM, JS 힙, 스크롤 위치) | | 돌아왔을 때 | 파일을 받아 페이지를 다시 만든다 | 멈췄던 페이지를 이어서 실행한다 | | 주체 | HTTP 헤더로 서버가 제어 | 브라우저가 스스로 판단 |
Next.js의 캐시나 라우터 캐시 같은 프레임워크 캐시와도 층이 다르다. 그쪽은 "페이지를 다시 만들 재료"를 들고 있고, bfcache는 "떠날 때의 화면 그 자체"를 들고 있다. 앱 안의 소프트 내비게이션은 문서를 떠나지 않으므로 bfcache가 끼어들 일이 없고, 다른 문서로 가는 하드 내비게이션 뒤에 돌아올 때 쓰인다.
감지와 정리: pageshow·pagehide
window.addEventListener('pageshow', (event) => {
if (event.persisted) {
// bfcache에서 복원됨: 오래된 데이터 갱신, 분석 이벤트 다시 보내기
}
})
window.addEventListener('pagehide', () => {
// 떠나기 직전: 임시 UI·애니메이션 정리
})pageshow는 첫 로드와 복원 때 모두 발생하고, 복원이면event.persisted가true다pagehide의persisted는 "캐시에 넣으려 한다"는 뜻일 뿐 보장은 아니다unload는 쓰지 않는다. 데스크톱 Chrome·Firefox에서는unload핸들러가 있으면 bfcache에 들어가지 못한다. 떠날 때의 정리는pagehide에서 한다
복원하면 상태가 굳어 있다
얼린 시점의 화면이 그대로 돌아온다는 점이 함정이다. 축하 애니메이션 canvas가 떠 있는 채로 다른 사이트로 이동했다가 뒤로 오면, 멈춘 애니메이션이 화면에 남아 있다. 페이지를 새로 그리는 게 아니라 이어 붙이기 때문이다. 열려 있던 모달·토스트, 로딩 스피너, 장바구니 수량 같은 값도 마찬가지다. 그래서
- 떠날 때 치워야 할 임시 UI는
pagehide에서 정리하고 - 오래되면 안 되는 데이터는
pageshow의persisted를 보고 다시 불러온다
막는 요인 (2026 기준)
unload핸들러(데스크톱 Chrome·Firefox)window.opener가 남아 있는 창, 진행 중인fetch·XHR, 열려 있는 IndexedDB 연결 등Cache-Control: no-store: 오랫동안 가장 큰 차단 사유였지만, Chrome은 2025년 봄(3~4월 100% 출시)에 안전한 경우 이런 페이지도 bfcache에 넣도록 바꿨다. 쿠키가 바뀌면 내보내고, 보관 시간도 일반 페이지(10분)보다 짧은 3분이다. 다른 브라우저는 여전히 막을 수 있다
Chrome DevTools의 Application → Back/forward cache에서 테스트를 돌리면 이 페이지가 들어갈 수 있는지, 못 들어가면 왜인지 알려 준다(크롬 개발자 도구 팁). 실제 방문에서 복원되지 않은 이유는 NotRestoredReasons API로 모을 수 있다.
출처: web.dev — Back/forward cache · Chrome for Developers — Enabling bfcache for Cache-Control: no-store