이벤트 페이지

앱과 확장 프로그램은 어떠한 Task와 상태를 관리하기 위해 길게 동작하는 단일 스크립트를 필요로 합니다. 이벤트 페이지가 이러한 일을 해줍니다. 이벤트 페이지는 필요한 시점에만 로드됩니다. 아무런 행동을 하지 않을때는 언로드되며 메모리를 해제합니다.

이벤트 페이지는 크롬 22부터 안정적으로 이용할 수 있고, 특히 저전력 기기에서 성능에 대한 이점이 있다는 것이 중요합니다. 새로 개발을 시작하는 경우 가능한 ‘persistent’ 백그라운드 대신 이벤트 페이지를 사용하십시요. 기존 백그라운드 페이지를 이 새 모델로 교체할 경우에도 마찬가지입니다.

매니페스트

매니페스트에 이벤트 페이지를 등록합니다:

“persistent” 키가 없으면 일반적인 백그라운드 페이지를 가지게 됨으로 주의해야 합니다. ‘Persistence’는 이벤트 페이지가 백그라운드 페이지와 무엇이 다른지 나타냅니다.

라이프타임

이벤트 페이지는 필요할 때 로드되고 필요없을 때 언로드됩니다. 어떠한 조건에서 이벤트 페이지가 로드되는지 예제를 통해 살펴보겠습니다:

  • 앱이나 확장 프로그램이 처음 인스톨되거나, 새 버전으로 업데이트됨(이벤트 등록을 위해)
  • 이벤트 페이지가 이벤트를 리스닝 하다가 이벤트가 발생함
  • 컨텐트 스크립트나 다른 확장 프로그램이 메시지를 보냄(Message Passing)
  • 확장 프로그램의 다른 뷰(예: 팝업)가 runtime.getBackgroundPage를 호출함

한번 로드가 되면 이벤트 페이지는 활성화 되어있는 동안 계속 실행중에 있게 됩니다. (확장 프로그램 API를 호출하거나 네트워크 요청을 발생시키는 등) 또 이벤트 페이지는 눈에 보이는 모든 뷰(예: 팝업 윈도우)와 전체 메시지 포트가 닫힐 때까지 언로드되지 않습니다. 뷰를 연다고 해서 이벤트 페이지가 로드되는 것은 아닙니다. 단지 뷰가 열려있으면 로드된 페이지가 종료되지 않는다는 점을 주의하십시요.

이벤트 페이지는 열려서 처리되자마자 바로 닫힙니다. 이벤트 페이지의 라이프타임을 크롬 작업 관리자로 볼 수 있습니다. 확장 프로그램이 프로세스 목록에 올라가면 이벤트 페이지가 로드되고 언로드 되는 것을 확인할 수 있습니다.

일단 이벤트 페이지가 짧은 대기시간(idle time)에 있는 동안(몇 초), runtime.onSuspend 이벤트가 전달됩니다. 이벤트 페이지는 강제로 언로드 되기전에 이 이벤트를 다루기 위한 몇 초의 시간을 가집니다. 그 시간동안 이벤트 페이지가 로드되는 일반적인 조건이 생긴다면 대기가 취소되고 runtime.onSuspendCancled 이벤트가 전달됩니다.

이벤트 등록

크롬은 앱이나 확장 프로그램에 추가된 리스너의 이벤트 추적을 계속 유지합니다. 이벤트가 전달되면 이벤트 페이지가 로드가 됩니다. 반대로 removeListener를 호출하여 앱이나 확장 프로그램에 있는 모든 이벤트 리스너를 제거하면, 이벤트가 발생해도 크롬이 더 이상 이벤트 페이지를 로드하지 않습니다.

리스너는 이벤트 페이지의 context 안에서만 존재할 수 있어서, 이벤트 페이지가 로드 될 때에 반드시 addListener 를 사용해야 합니다; runtime.onInstalled 를 사용하는 것만으로는 부족합니다.

액션을 통해 이벤트를 등록하는 예제를 구글 메일 체커에서 볼 수 있습니다.

백그라운드 페이지에서 이벤트 페이지로의 전환

다음 체크리스트를 따라 persistent 백그라운드 페이지를 이벤트 페이지로 변경하십시요.

  1. “persistent”: false 를 위에 보이는대로 매니페스트에 추가하세요.
  2. 확장 프로그램이 window.setTimeout()이나 window.setInterval()을 사용한다면, alarms API로 대체하세요.
  3. 유사하게, notifications와 geolocation과 같은 비동기 HTML5 API는 이벤트 페이지가 내려갈 경우에 완료가 되지 않습니다. 그러므로 notifications 같은 동일한 확장 프로그램의 API를 사용하십시요.
  4. 확장 프로그램이 extension.getBackgroundPage를 사용한다면, runtime.getBackgroundPage로 교체하십시요. 새 메서드는 비동기여서 필요하다면 그것이 되돌아가기전에 이벤트 페이지를 시작할 수 있습니다.

이벤트 페이지를 잘 활용한 사례

이벤트 페이지를 사용할 때 여러 팁을 활용하여 미세한 함정에 빠지지 않도록 조심합니다.

  1. 이벤트 페이지가 로드될 때마다 확장 프로그램의 관심 이벤트를 수신하기 위해 등록을 합니다. 이벤트 페이지는 확장 프로그램의 새 버전마다 한번 로드될 것입니다. 그 이후에는 등록한 이벤트가 전달될 때에만 로드됩니다. 이 말은 이벤트 리스너가 이벤트 페이지의 최상위 레벨 범위에 추가되어 있어야 함을 의미합니다. 그렇지 않으면 이벤트 페이지가 리로드 될 때 이용하지 못할수도 있습니다.
  2. 확장 프로그램이 인스톨이나 업데이트 되었을 때 어떤 초기화를 해야 할 경우, runtime.onInstalled 이벤트를 listen 합니다. 이것은 declarativeWebRequest 규칙, contextMenu 진입, 그리고 한번의 초기화 등을 등록하는데 좋습니다.
  3. 브라우저 세션 내내 메모리에서 런타임 상태를 유지하고 싶다면, storage API 또는 IndexedDB를 사용하세요. 이벤트 페이지는 오랫동안 로드된 상태에 있지 않기 때문에, 런타임 상태를 더 이상 전역변수에 의지할 수는 없습니다.
  4. 여러분이 신경쓰고 있는 상황에 대한 이벤트 노티피케이션을 제한하려면 event filters를 사용하세요. 예를 들어, tabs.onUpdated 이벤트를 listen 한다면, 대신 webNavigation.onCompleted 이벤트를 필터와 함께 사용해 보십시요 (tabs API는 필터를 지원하지 않음). 이렇게 하면 여러분이 관심을 가지는 이벤트 시에만 이벤트 페이지가 로드될 것입니다.
  5. 이벤트 페이지가 종료되기 전 마지막 순간에 정리할 필요가 있다면 runtime.onSuspend 를 listen 하십시요. 그러나 그것보다는 정기적으로 꾸준히 정리하는 것을 추천합니다. 그렇게 함으로써 확장 프로그램이 onSuspend를 수신못하고 충돌 나더라도, 일반적으로 데이터를 잃어버리지 않을 것입니다.
  6. message passing을 사용할 때는 사용되지 않는 메시지 포트를 꼭 닫아두십시요. 모든 메시지 포트가 닫히기 전까지 이벤트 페이지는 종료되지 않습니다.
  7. context menus API를 사용할 때는, 문자열인 id 파라미터를 contextMenus.create로 전달하시고, 이 곳에서 contextMenus.onClicked 콜백을 onclick 파라미터 대신 사용하십시요.
  8. 이벤트 페이지는 언로드 후 리로드할 때 몇 초간의 비활성이 발생합니다. 이 때 이벤트 페이지가 정상적으로 동작하는지 테스트 하십시요. 페이지를 로드하는 시간에 공통적으로 하는 실수로는 불필요한 작업을 포함시키는 것 (확장 프로그램이 인스톨 되었을 때 완료되었어야 할), 알람을 세팅하는 것 (이전의 어떠한 알람을 다시 설정), 이벤트 리스너를 추가하지 않는 것이 있습니다.