크롬 익스텐션: Background Pages 와 Event Pages

발생일: 2014.12.01

키워드: chrome extension, 크롬 익스텐션, 크롬 확장, background pages, event pages, 백그라운드 페이지, 이벤트 페이지

문제:
사전 익스텐션을 대폭 개편하려고 `manifest.json` 포맷을 다시 살펴보다 보니,
백그라운드 페이지가 deprecated 되고 이벤트 페이지라는 것이 생겼더라.

이벤트 페이지는 뭐가 다른 거지?


해결책:

백그라운드 페이지와 이벤트 페이지

크롬 익스텐션에서 브라우저가 열려있는 동안 계속 떠있어야 할 페이지나 스크립트가 있다면,
백그라운드 페이지나 스크립트로 등록해두고 사용하면 됐었다.

{
  "name": "My extension”,
  ...
  "background": {
    "scripts": ["background.js"]
  },
  ...
  "background": {
    "page": "background.html"
  }
  ...
}


헌데, 크롬 22부터 호환 가능한 ‘이벤트 페이지’라는 게 생기고, 백그라운드 페이지는 deprecated 되었다고 한다.
백그라운드 페이지와 이벤트 페이지의 가장 큰 차이점은 라이프 사이클이다.

백그라운드 페이지가 브라우저의 라이프 사이클과 동일했다면,
이벤트 페이지는 필요한 시점에 로드되었다가, 장시간 사용하지 않으면 언로드된다.

백그라운드 페이지에 대비해 메모리를 효율적으로 사용할 수 있는 장점이 있다.
(실제로 익스텐션을 여러 개 설치해보면, 메모리 소모가 엄청나다. >_<)


이벤트 페이지 사용하기

이벤트 페이지를 사용하려면, 아래처럼 `persistence` 속성을 `false`로 설정하면 된다.

{
  "name": "My extension",
  ...
  "background": {
    "scripts": ["eventPage.js"],
    "persistent": false
  },
  ...
}


이벤트 페이지의 라이프 사이클


이벤트 페이지는 ‘필용한’ 때에 로드되는데, 아래와 같은 상황을 예로 들 수 있다.

- 처음 인스톨 되었거나, 새 버전으로 업데이트 된 경우
- 이벤트 페이지가 listen 하고 있는 이벤트가 발생되었을 경우
- 컨텐트 스크립트나 다른 익스텐션이 메시지를 보낸 경우
- 익스텐션의 다른 뷰에서 `runtime.getBackground()`를 호출한 경우

한 번 로드된 이벤트 페이지는, 모든 뷰가 닫히기 전이나 port 등의 커넥션이 끊기기 전엔 언로드 되지 않는다.

모든 작업이나 통신이 종료되고 유휴 상태가 되면, 아래와 같은 과정으로 언로드 된다.

- 유휴 상태가 되면 수 초 이내에 `runtime.onSuspend` 이벤트를 발생한다.
- 그리고 몇 초를 기다린 후에 언로드 된다.
- 만약, 기다리던 중에 다시 이벤트 페이지가 로드되었다면 `runtime.onSuspendCanceled` 이벤트를 발생한다.


주의할 점

이벤트 페이지를 효과적으로 사용하려면 몇 가지 주의할 점이 있다.

- 이벤트 페이지는 업데이트 될 때마다 새로 로드된다.
  이 때 이벤트 핸들러가 있었다면 초기화해줘야 한다. 이벤트 핸들러는 이벤트 페이지의 컨텍스트에 존재하기 때문이다.
  각 이벤트 핸들러에 대한 초기 작업은 `runtime.onInstalled` 이벤트에서 처리하면 된다.
- 메모리에 저장해둔 값이 있었다면, `storage API`를 활용하는 방식으로 전환해라.
- 외부 이벤트에 제한을 두려면, ‘이벤트 필터’를 사용하라.
  예를 들면, `tabs.onUpdated` 대신 이벤트 필터를 제공하는 `webNavigation.onCompleted` 이벤트를 사용하는 것이 좋다.
- 페이지가 내려가기 전에 데이터 정리가 필요하다면, `runtime.onSuspend` 이벤트에서 처리해라.
  그렇지만, 가능한 주기적으로 데이터를 저장하거나 정리하는 걸 추천한다.
- 메시지 포트를 사용하고 있었다면, 사용이 종료된 후에 꼭 닫아줘라.
- `context menus` API를 사용하고 있었다면, `contentMenus.create`에 `onClick` 파라미터를 전달하는 대신,
  `contextMenus.onClicked` 이벤트를 활용하라.
- 페이지가 짧은 시간 안에 로드되었다가 언로드되는 경우에 대한 테스트를 충분히 해보는 것을 권장한다.



음… 이벤트 페이지라…
메모리를 효율적으로 사용할 순 있지만, 제대로 처리하면 예외 케이스 처리 때문에 복잡도가 높아질 것 같긴 하다.

도입할 땐, 좀 진지하게 고민해봐야겠다.


자세한 내용은, 아래 링크를 참고한다.

카테고리

분류 전체보기 (682)
About me. (6)
Daylogs (647)
비공개 (0)
영어공부 (0)
My works - 추억 (29)