Navigator: sendBeacon() 메서드
navigator.sendBeacon()
메서드는 적은 양의 데이터를 포함하는 HTTP POST 요청을 비동기적으로 웹 서버에 보냅니다.
XMLHttpRequest
같은 오래된 기술로 웹 서버에 분석 정보를 전송할 때 생길 수 있는 일부 문제를 피하기 위해 고안됐습니다.
구문
sendBeacon(url)
sendBeacon(url, data)
매개변수
url
-
data 를 받을 서버의 URL 입니다. 상대 주소와 절대 주소 모두 가능합니다.
data
Optional-
ArrayBuffer
,TypedArray
,DataView
,Blob
, 문자열 또는 객체 리터럴,FormData
,URLSearchParams
등, 전송할 데이터를 담은 객체입니다.
반환 값
sendBeacon()
메서드는 사용자 에이전트가 전송할 data
를 대기열에 성공적으로 추가하면 true
를 반환하고, 아니면 false
를 반환합니다.
설명
이 메서드는 분석 정보나 진단 데이터를 서버에 보내기 위해 고안됐습니다.
많은 경우, 사이트에서 분석/진단 데이터 전송을 바라는 시점은 사용자가 다른 페이지로 이동할 때처럼 이탈 순간입니다. 기존 방법으로 분석 정보를 보낼 때의 문제는, 이탈 시 전송의 경우 페이지가 언로딩되기 직전인 순간일 수도 있으므로, 브라우저가 재량에 따라 비동기적인 XMLHttpRequest
요청을 보내지 않을 수도 있다는 점입니다.
과거 웹 페이지들은 데이터를 모두 보낼 수 있을 정도로 페이지의 언로딩을 지연시키기도 했습니다. 정확히는 아래와 같은 기법이 있었습니다.
- 블로킹하도록 동기적
XMLHttpRequest
로 데이터 전송 <img>
태그를 만들고src
를 설정하기. 대부분의 사용자 에이전트는 이미지를 로드하기 위해 페이지 언로드를 미룹니다.- 의미 없는 무한 반복 루프를 몇 초동안 실행하기.
이러한 방법들은 모두 문서의 언로딩을 막으므로 다음 페이지로의 탐색 속도가 저하됩니다. 다음 페이지에는 이를 피하기 위해 할 수 있는 게 없습니다. 따라서 성능 문제는 이전 페이지에 있는데도 새로운 페이지가 느리게 느껴질 것입니다.
sendBeacon()
메서드를 사용하면, 언로딩이나 다음 탐색 지연 없이, 사용자 에이전트가 적절한 순간에 데이터를 비동기적으로 전송합니다. 따라서...
- 데이터가 안정적으로 전송됨
- 비동기적임
- 다음 페이지에 영향을 끼치지 않음
데이터는 HTTP POST 요청으로 보내집니다.
세션 끝에서 분석 정보 보내기
웹 사이트는 대개 사용자가 페이지에서 이탈할 때 진단이나 분석 정보를 보내고자 합니다. 가장 안정적인 방법은 visibilitychange
이벤트에서 데이터를 전송하는 것입니다.
document.addEventListener("visibilitychange", function logData() {
if (document.visibilityState === "hidden") {
navigator.sendBeacon("/log", analyticsData);
}
});
unload와 beforeunload 지양
과거에는 많은 웹 사이트들이 세션 끝에 분석 정보를 보내기 위한 용도로 unload
나 beforeunload
를 사용했습니다. 그러나 이 방법은 극히 불안정합니다. 많은 경우, 특히 모바일에서, 브라우저는 unload
, beforeunload
, pagehide
등의 이벤트들을 전송하지 않습니다. 예를 들어, 아래의 세 경우에는 이 이벤트들을 수신할 수 없습니다.
- 사용자가 페이지를 불러오고 상호작용합니다.
- 사용자가 이탈할 때, 탭을 닫지 않고 다른 앱으로 전환합니다.
- 사용자가 나중에 기기의 앱 관리자를 통해 브라우저를 닫습니다.
추가적으로, unload
이벤트는 최신 브라우저들에서 구현된 뒤로/앞으로 캐시(bfcache)와 호환되지 않습니다. Firefox를 포함한 일부 브라우저들에서는 unload
이벤트 처리기가 포함되어 있는 페이지를 bfcache에서 제외함으로써 호환성 문제를 해소하므로, 성능이 저하됩니다. Safari와 Chrome 등 나머지 브라우저들은 사용자가 하나의 탭에서 다른 페이지로 탐색하는 경우 unload
이벤트를 아예 전송하지 않습니다.
Firefox는 beforeunload
처리기로도 페이지를 bfcache에서 제외합니다.
pagehide를 대비책으로 사용하기
visibilitychange
를 지원하지 않는 브라우저들을 지원하려면 pagehide
이벤트를 사용하세요. beforeunload
, unload
와 같이 pagehide
도 특히 모바일에서 불안정합니다. 하지만 적어도 bfcache와는 호환됩니다.
예제
다음 예제에서는 sendBeacon()
을 호출해 분석 정보를 전송하는 visibilitychange
이벤트 처리기를 지정합니다.
document.addEventListener("visibilitychange", function logData() {
if (document.visibilityState === "hidden") {
navigator.sendBeacon("/log", analyticsData);
}
});
명세서
Specification |
---|
Beacon # sendbeacon-method |
브라우저 호환성
BCD tables only load in the browser
같이 보기
visibilitychange
이벤트.- Beacon API 개요.
- Don't lose user and app state, use Page Visibility에서는 왜
beforeunload
/unload
대신visibilitychange
를 사용해야 하는지 자세히 설명합니다. - Page Lifecycle API에서는 웹 애플리케이션에서 페이지의 수명 주기 동작을 처리하는 최선의 방법들을 제시합니다.
- PageLifecycle.js: 페이지 수명 주기의 브라우저간 불일치를 처리하기 위한 JavaScript 라이브러리입니다.
- Back/forward cache. 뒤로/앞으로 캐시가 뭔지, 다양한 페이지 수명 주기 이벤트에서 이 캐시가 갖는 의미가 뭔지 설명합니다.