B/F cache는 Back/Forward Cache라는 뜻을 가지고 있습니다.
브라우저에서 뒤,앞으로 이동할때 로드를 빠르게 하기위한 동작입니다.
브라우저에서는 이전 페이지를 snap shot을 찍어서 메모리에 올려놓습니다.
사용자가 뒤로 가기를 하면 메모리에서 가져와 그대로 보여주는 것입니다.
이렇게 하면 이전 페이지에서 리소스들의 요청을 보내지 않을 수 있고, 스크립트의 재실행 또한 하지 않습니다. 따라서 사용자에게 빠르게 보여줄 수 있습니다.
브라우저 호환성
safari, firefox에서는 전부 지원되어 왔었고
chrome에서는 버전 86부터 점진적으로 적용해왔다가 버전 96부터는 모든 chrome 유저가 사용할 수 있도록 지원되고 있다고 합니다.
bfcache 기본 사항
bfcache는 페이지의 전체 스냅샷(Javascript 힙 포함)을 저장하는 메모리 내 캐시 입니다.
전체 페이지를 메모리에 넣어놓고 사용하게 됩니다. 이 캐시의 유통기한은 3분 입니다.
해당 문서에서는 bfcache가 적용/적용되지 않은 경우의 비교를 아래와 같이 보여줍니다.
bfcache 미적용
=> 이전 페이지를 로드하기 위해 새 요청 시작, 리소스의 일부 혹은 전체를 다시 다운, 다시 파싱, 다시 실행
bfcache 적용
=> 네트워크에 요청하지 않고 메모리에서 복원하여 보여줌
"캐시" 작동 방식
bfcache에서 사용하는 캐시는 http 캐시와 다릅니다.
bfcache | http 캐시 |
메모리에 있는 전체 페이지의 스냅샷 | 이전에 작성된 요청에 대한 응답만 캐시 |
이전 페이지에서의 모든 요청이 http 캐시 적용이 되어있을 가능성은 적기 때문에 bfcache를 적용한 페이지는 항상 빠를수 있습니다.
근데
스냅샷을 적용할때 setTimeout 같은 비동기 동작을 유발하는 코드들은 스냅샷 적용이 어려울 수 있습니다.
이럴때 브라우저는 타이머나 확인되지않은 모든 약속 작업(기본적으로 Javascript 작업 대기열의 모든 보류 중인 작업)을 일시 중지하고 bfcache에서 복원될때 일시 정지된 작업들을 재개합니다.
또 근데
이런 bfcache가 의도와는 다르게 동작할 수 있습니다.
script 내에서 무조건 실행을 한 후에 다음 동작이 수행되어야 하는 경우가 있을 수 있습니다.
bfcache가 적용되면 메모리에 위치된 javascript 코드는 재실행 되지 않습니다.
그렇다면 bfcache가 적용되어있는지를 판단하고 재동작을 수행해주어야 합니다.
페이지 전환 이벤트에서 이를 확인할 수 있습니다.
bfcache에서 페이지가 복원될 때 관찰
pageshow 이벤트의 persisted 옵션을 확인하면 bfcache로부터 복원된지/아닌지를 확인할 수 있습니다.
window.addEventListener("pageshow", (event) => {
if (event.persisted) {
console.log('bfcache 로부터 복원된거임')
} else {
console.log('정상적으로 로드된거임')
}
})
bfcache가 들어가는걸 관찰
복원될때의 반대 동작도 확인이 가능합니다.
window.addEventListener("pagehide" , (event) => {
if (event.persisted === true) {
console.log("이 페이지는 아마 bfcache에 들어갈 겁니다")
} else {
console.log("이 페이지는 정상적으로 사라질 겁니다.")
}
})
그러면 모든 페이지가 bfcache에 들어갈 수 있는 걸까요?????
bfcache를 적용하기 위해 아래와 같은 경우는 지양하여야 합니다.
- unload 이벤트 사용 금지, unload 리스너는 사용하지 않아야 합니다.
- window.opener 참조를 피해야 합니다.
일부 브라우저에서 window.open(), target=blank 를 사용하면 (rel="noopener"를 지정하지 않음) 열린 페이지에 대한 참조가 가능합니다.
window.opener 참조가 있는 페이지는 bfcache에 넣을수가 없습니다. - 사용자가 다른 곳으로 이동하기 전에 항상 열려 있는 연결 닫기
* 진행 중인 fetch() 또는 XMLHttpRequest가 있는 페이지
* webSocket 또는 webRTC 연결이 있는 페이지
위의 페이지들은 bfcache에 넣지 않습니다.
이전에 tossPayments를 script로 적용할때 toss로부터 기술 지원을 받아 이러한 이슈에 처음 알게 되었던 경험이 있습니다.
애플 로그인도 jsscript로 실행할때 위의 이슈를 미리 알았더라면 적용했을 법 했을텐데 라는 아쉬움이 있네요
아래와 같이 활용할 수 있을것 같네요
somethingTodo()
window.addEventListener("pageshow", (event) => {
if(event.persisted) {
somethingTodo()
}
})
광고 추적같은 경우 위의 요소를 사용하면 bfcache로 인해 카운팅이 안되는 이슈를 방지할 수 있을것 같습니다.
크롬 개발자 도구의 applications 탭에서는 bfcache 적용을 확인하고 테스트 할 수 있는 것으로 알고 있습니다.
출처 : https://web.dev/i18n/ko/bfcache/
'브라우저' 카테고리의 다른 글
브라우저 구성, CRP, reflow, repaint, DOM, layout thrashing, requestAnimationFrame 🌱 (1) | 2022.04.11 |
---|---|
브라우저 캐싱 ❓ (0) | 2022.04.06 |
JWT/JWK (0) | 2021.12.06 |
localStorage, sessionStorage (0) | 2021.11.14 |