[Javascript] (BFCache이슈) IOS/Chrome 뒤로가기 자바스크립트 오류(History Back Error)
안녕하세요. 갓대희 입니다. 이번 포스팅은 [ Javascript 뒤로가기 BF Cache 에러 ] 입니다. : )
0. 들어가기 앞서
- 예전 Safari, Firefox 브라우저에서, 나와 같은 경우 아이폰 웹뷰 Safari의 경우에 BFCache 때문에 페이지 개발 방식에 따라 뒤로가기시 스크립트 로드가 되지 않아 정상 동작하지 않는 경우가 있었다.
- 다만, 이젠 크롬에도 BFCache가 도입되었고 또다시 크롬에서도 BFCache때문에 고통을 겪게 되었다. 그리고 예전글에서 가이드 했던 내용 중 Deprecated 된 API도 있기 떄문에 다시 정리하고자 한다.
https://developer.chrome.com/docs/web-platform/bfcache-notrestoredreasons/?hl=ko
- 대부분은 내용은 web 데브의 내용을 재해석 하였다.
https://web.dev/articles/bfcache?hl=ko
1. BFCache
BF Cache( Back-Forward Cache )란?
- 사용자가 브라우저에서 뒤로가기/앞으로가기 했을 경우 이전 페이지를 전체 캐싱해서 in memory로( 자바스크립트 heap 영역까지 ) 가지고 있는 것, 즉 페이지 전체의 스냅샷을 저장하는 캐싱 기능이다.
- BFCache를 사용하는 예시가 BFC ache를 사용하지 않은 예시보다 훨씬 빠를 수 밖에 없다.
( 이번엔 BFCache의 장점을 살펴보려는 내용은 아니기 때문에 간단히 넘어간다. )
- 하지만 네트워크에 전혀 연결하지 않고, 메모리로부터 해당 웹페이지를 복원하기 때문에 개발자들에게는 매우 난처한 상황을 만들기도 한다.
BF Cache 동작 여부 확인 방법 (BFCache 테스트 방법)
- 내가 확인하려는 페이지에서 BFCache가 작동했는지 직접 테스트 해볼 수 있다.
※ 크롬에서 98버전 이후 부터 BFCache 적용 가능여부를 테스트 할 수 있으니 참고 하자.
※ 테스트 방법 참고 - https://developer.chrome.com/ko/blog/new-in-devtools-98/#bfcache
- Application > Background Services > Back/forward cache 를 클릭 하고 뒤로가기 또는 앞으로 가기를 클릭 하면 다음과 같이 BF Cache 동작 여부를 직접 확인할 수 있다.
- 미동작 했을때에는 관련 사유를 알려 준다.
( 내가 테스트한 사이트에는 캐시를 저장하지 말라고 하는 cache-control : no-store가 적용되어 있어 미동작 하였다. )
2. Javascript 코드로 BFCache 감지 방법
BF Cache로 개발자들이 겪는 상황
- BF Cache를 잘 사용하면 좋겠지만, BFCache가 적용되면
window.onload, $(document).ready()와 같은 onLoad 이벤트가 동작하지 않기 때문에 개발자의 의도와 다른 페이지를 보여줄 수 있다.
BF Cache 감지 방법
- 혹시 긴글에 지쳐 정답만 알고 싶은 경우 다음을 활용해보면 될 것 같다.
window.onpageshow = (e) => {
const navigation = window.performance.getEntriesByType('navigation');
if (e.persisted || (navigation.length && (navigation[0]).type === 'back_forward')){
// 캐싱되면 안되는 동작 추가
}
};
1) BFCache를 감지하는데 사용되는 기본 이벤트는 페이지 전환 이벤트(pageshow 및 pagehide)이다.
이 이벤트는 BFCache 기간만큼 오랫동안 사용되었고, 모든 브라우저에서 지원다.
- 혹시나 호환성 체크 해보았지만, IE11에서 조차 동작 한다.
https://caniuse.com/page-transition-events
▶ pageshow
- pageshow 이벤트는 다음 2가지 상황에서 발생한다.
1) 페이지가 처음 로드될 때
2) 페이지가 bfcache에서 복원될 때마다 load 이벤트 직후에 실행된다.
└ persisted : BFache에서 복원되면 true, 그렇지 않은 경우 false를 반환한다.
- 이를 통해 다음과 같이 BFCache로 부터 복원되었음을 감지할 수 있다.
window.addEventListener('pagehide', (event) => {
if (event.persisted) {
console.log('This page *might* be entering the bfcache.');
} else {
console.log('This page will unload normally and be discarded.');
}
});
▶ pagehide
- pagehide 이벤트는 다음 2가지 상황에서 발생한다.
1) 페이지가 정상적으로 언로드 될 때
2) 브라우저가 bfcache 하려고 시도할 때
└ persisted : 이 속성이 false라면 페이지가 bfcache에 들어가지 않을 것이 확실하다. true라면 브라우저가 캐시 하려고 시도한 것 이다.
※ 하지만 위에서 테스트 해봤듯이, 크롬과 같이 다른 캐싱 방지 요소에 의해 결과적으로 캐시되지 않을 수도 있기 때문에 100% 보장할 수 없다. 이때문에 pageshow 이벤트를 활용 하려고 한다.
뒤로가기 감지 방법
- 대부분 앞으로 가기보다는 뒤로가기 행동에서 문제를 겪게 되는 고민을 하였을 것 이다.
- 위에서 BFCache는 감지 할 수 있었고 이제 뒤로 가기이벤트만 감지하면 된다.
※ 예전 나도 글을 썼었고, 뒤로가기의 경우 다음 방법을 사용했었다.
- window.performance.navigation.type
window.performance && window.performance.navigation.type == 2
// 또는 다음과 같은 예시
window.performance && window.performance.navigation.type == window.performance.navigation.TYPE_BACK_FORWARD
- 하지만 이제 해당 API는 deprecated되었다. 검색해 볼 수도 있지만 IntelliJ를 사용하면 친절히 알려주기도 한다.
- 해당 api는 deprecated 되었며 Performance.navigation을 활용하라고 한다. (자세한 내용은 하기 링크 참고)
https://developer.mozilla.org/en-US/docs/web/api/performancenavigation
- PerformanceNavigationTiming 으로 대체 되었고 자세한 내용은 하기 참고.
https://developer.mozilla.org/en-US/docs/Web/API/PerformanceNavigationTiming
최종 BFCache 동작 및 뒤로가기 동작 감지
- 나의 경우 위와 같은 과정과 내용을 조합하여 다음과 같이 BFCache 동작을 감지 하였고, 정상동작할 수 있도록 처리 완료 하였다.
window.onpageshow = (e) => {
const navigation = window.performance.getEntriesByType('navigation');
if (e.persisted || (navigation.length && (navigation[0]).type === 'back_forward')){
// 캐싱되면 안되는 동작 추가
}
};
나와 같이 BFCache로 고통을 겪는 분들에게 조금이나마 도움이 되면 좋겠다.
혹시라도 잘못 작성한 내용이 있다면 꼭 댓글로 알려주시면 감사합니다!! :-)