들어가며
페이지에 진입할 때마다 특정 자바스크립트가 실행되어야 하는데, 처음 해당 페이지에 진입할 때는 정상적으로 자바스크립트가 실행되지만 뒤로가기를 통해 재진입했을 때에는 자바스크립트가 실행되지 않는 문제가 발견되었다. 뒤로가기에서는 자바스크립트가 항상 실행되지 않는걸까?
뒤로가기를 위한 캐시, BFCache
크롬에서는 뒤로가기로 재진입을 해도 정상적으로 자바스크립트 코드가 다시 실행되는 것을 확인할 수 있었다. 하지만 사파리나 파이어폭스에서는 자바스크립트 코드가 다시 실행되지 않았다. 파이어폭스나 사파리에서 이런 현상이 일어나는 이유는, 뒤로가기를 할 경우 보다 빠른 반응을 위해 BFCache 를 사용해서 저장해놓은 이전 페이지를 바로 로드하기 때문이다.
특히 onLoad 이벤트에 주요 자바스크립트 코드를 걸어놓은 경우, BFCache를 타게되면 페이지 진입시에 해당 자바스크립트 코드가 항상 재실행되는 것을 보장하기가 어려워지게 된다. 물론 대부분의 경우에는 재실행이 필요하지 않지만, 새로운 페이지에서 진행한 작업이 뒤로가기로 왔을 때 재진입한 페이지에도 영향을 주는 경우, 자바스크립트로 이 부분을 최신화하고 싶을 수 있을 것이다. 이런 경우 BFCache 로 인해 화면 업데이트가 되지 않으면 문제가 될 수 있다.
pageshow/pagehide 이벤트
새롭게 진입하든, 뒤로가기로 재진입하든 항상 발생하는 이벤트는 없을까? MDN의 BFCache에 대한 설명 페이지에서는 pageshow/pagehide 이벤트를 대안으로 제시하고 있다. pageshow 이벤트의 경우 뒤로가기로 재진입한 경우에도 발생하는 이벤트이므로 페이지가 열릴 때마다 수행되어야하는 코드가 있다면 이 이벤트에 바인딩하는 것이 더 바람직하다. pageshow 이벤트가 load 이벤트에 대응한다면, unload 이벤트에는 pagehide 이벤트가 비슷한 기능을 하게 된다.
window.onpageshow = function (event) { if (event.persisted) { console.log('BFCahe로부터 복원됨'); } else { console.log('새로 열린 페이지'); } };
콜백으로 넘겨지는 event 파라메터의 속성 중 persisted 가 true 인 경우, BFCache로 부터 복원된 상태, 즉 뒤로가기 등으로 재진입한 상태임을 알 수 있기 때문에 좀더 정밀한 컨트럴이 가능해진다.
jQuery를 사용하는 경우, 콜백의 파라메터가 한번 감싸지기 때문에 아래와 같이 originalEvent 를 통해 persisted 속성에 접근할 수 있다.
$(window).bind("pageshow", function (event) { if (event.originalEvent.persisted) { console.log('BFCahe로부터 복원됨'); } else { console.log('새로 열린 페이지'); } });
마치며
뒤로가기의 빠른 반응을 위해 BFCache에 이전 페이지가 저장되고 이로 인해 자바스크립트 코드가 재실행되지 않을 수 있다는 것을 확인했다. 그리고 그 대안으로 pageshow 이벤트를 살펴보았다.
브라우저마다 반응이 다른 케이스 한 가지를 더 알게 되었다. 매진입시마다 반드시 실행되어야하는 자바스크립트 코드가 있다면 pageshow 이벤트를 적절히 활용하는 것이 필요해보인다.