# navigator.sendBeacon vs fetch + keepalive

사용자가 페이지를 떠날 때마다 백엔드에 몇가지 요청을 보내려고 할 때, 두가지 정도의 접근 방식이 존재한다.

바로 [navigator.sendBeacon](https://navigator.sendBeacon) 또는 fetch + keepalive 방식이다.

# 두 방식의 트레이드 오프

## [Navigator.sendBeacon](https://Navigator.sendBeacon) 

### [Navigator.sendBeacon](https://Navigator.sendBeacon)의 장점

- 페이지가 언로드될 때 데이터를 전송하도록 특별히 설계되었다.

- 우선순위가 낮은 비동기식으로 페이지 언로드 프로세스를 차단하지 않는다. (네트워크 탭의 우선순위 참고)

- 브라우저는 페이지가 닫힌 후에도 데이터 전송을 완료한다.

- 간편한 API 인터페이스로 사용할 수 있다.

- POST 메서드를 주로 지원하기 때문에, 자동으로 POST 메서드를 사용한다.

- 응답을 처리할 필요없으며, 단방향 데이터에 이상적이다.

### Navigator.sendBeacon의 제약사항

- POST 요청만을 지원한다.

- 응답 내용을 받을 수 없다.

- 크기 제한이 있다. (크롬의 경우 약 64KB)

- 사용자 커스텀 헤더 지원을 하지 않는다.

### 사용 예시

```javascript
javascriptCopywindow.addEventListener('unload', () => {
  navigator.sendBeacon('/api/log', JSON.stringify({
    event: 'page_exit',
    duration: performance.now()
  }));
});
```

## Fetch + keepalive

### Fetch + keepalive의 장점

- 모든 HTTP 메서드 (GET, POST, PUT 등)을 지원한다.

- 사용자 커스텀 헤더를 허용한다.

- 응답 내용에 대한 처리가 가능하다.

- 데이터 크기에 제한이 없다.

- 더 유연한 에러 핸들링이 가능하다.

### Fetch + keepalive의 제약사항

- [Navigator.sendBeacon](https://Navigator.sendBeacon) 보다 조금 더 복잡한 구현 요소를 가진다.

- 수동으로 옵션을 활성화 시켜줘야한다.

- [Navigator.sendBeacon](https://Navigator.sendBeacon) 에 비해 브라우저 호환성이 약간 낮은 편이다.

### 사용 예시

```javascript
javascriptCopywindow.addEventListener('unload', () => {
  fetch('/api/sync', {
    method: 'POST',
    keepalive: true,
    headers: {
      'Content-Type': 'application/json',
      'Authorization': 'Bearer token'
    },
    body: JSON.stringify({
      data: 'important_data'
    })
  });
});
```

## 글을 마치며

간단한 분석 및 로깅 시나리오를 위해 [navigator.sendBeacon](https://navigator.sendBeacon) 을 선택하고, 요청에 대한 더 많은 제어가 필요하거나 응답을 처리해야할 경우에는 Fetch + keepalive 전략이 매우 좋은 선택인 것 같다. 중요한 데이터의 경우 페이지 언로드를 기다리지 않고 사용자 상호작용 중 동기화 하는 로직 (로컬 스토리지를 이용하여 Ack 로직과 로드 로직을 만드는 등) 고려하는 편이 좋을 것 같다는 생각이 든다.

For the site tree, see the [root Markdown](https://slashpage.com/timmy.md).
