Chrome의 메모리 및 에너지 절약 모드에 대해 개발자가 알아야 할 사항

Chrome 108에서는 사용자가 Chrome의 시스템 리소스 활용 방식을 더 세부적으로 제어할 수 있도록 메모리 절약 모드와 에너지 절약 모드라는 두 가지 새로운 모드를 도입했습니다.

이러한 새로운 모드는 주로 사용자에게 표시되는 방식이지만, 사이트의 사용자 환경에 잠재적으로 영향을 미칠 수 있으므로 웹 개발자가 알아두어야 할 몇 가지 사항이 있습니다.

이 게시물에서는 이러한 새로운 모드의 잠재적인 효과와 최상의 환경을 제공하기 위해 웹 개발자가 할 수 있는 작업을 다룹니다.

메모리 절약 모드

메모리 절약 모드를 사용 설정하면 Chrome은 한동안 백그라운드에서 사용되지 않은 탭을 사전에 삭제합니다. 이렇게 하면 활성 탭과 실행 중인 다른 애플리케이션을 위한 메모리가 확보됩니다. 사용자는 특정 사이트의 탭을 삭제하지 않도록 Chrome에 지시할 수 있습니다. 그러나 이는 사용자 환경설정이며 개발자가 제어할 수 있는 항목이 아닙니다.

탭을 삭제해도 제목과 파비콘은 탭 표시줄에 계속 표시되지만 페이지는 탭을 평소에 닫은 것처럼 사라지게 됩니다. 사용자가 해당 탭을 다시 방문하면 페이지가 자동으로 새로고침됩니다.

순수한 콘텐츠 페이지의 경우 탭을 삭제하고 다시 로드해도 사용자 환경에는 영향을 미치지 않을 수 있습니다. 하지만 복잡한 사용자 플로우가 있는 풍부한 상호작용 사이트의 경우, 사용자 플로우가 복잡한 경우 그 중간에 새로고침을 하면 사이트에서 사용자가 중단한 위치로 페이지를 복원할 수 없다면 매우 불편할 수 있습니다.

메모리 절약을 위해 탭을 삭제하는 작업은 Chrome에서 수년간 해왔던 일이지만 시스템이 메모리 압박을 받고 있는 상황에서만 이루어졌습니다. 비교적 드물게 발생하는 이벤트이기 때문에 웹 개발자들은 이 문제가 발생했다는 사실을 모르고 있을 수도 있습니다.

Chrome 108부터 탭 삭제가 더 일반화되므로 사이트에서 이러한 발생을 적절하게 처리할 수 있어야 합니다.

탭 삭제 처리 권장사항

탭 삭제는 웹 개발자에게 새로운 문제가 아닙니다. 사용자는 작업을 완료하기 전에 의도적으로 또는 실수로 페이지를 새로고침할 수 있습니다. 따라서 사이트에서 사용자 상태를 저장하여 사용자가 떠났다가 다시 돌아올 때 사용자 상태를 복원할 수 있도록 하는 것이 항상 중요했습니다.

가장 중요하게 고려할 사항은 사용자 상태를 저장할지 여부가 아니라 시기입니다. 이것이 핵심입니다. 탭이 삭제될 때 발생하는 이벤트가 없으므로 개발자가 이런 사실에 반응할 방법이 없기 때문입니다. 대신 개발자는 이러한 가능성을 예상하고 미리 준비해야 합니다.

사용자 상태를 저장하기에 가장 좋은 시점은 다음과 같습니다.

  • 상태가 변경될 때 주기적으로
  • 탭이 백그라운드로 전환될 때마다 (visibilitychange 이벤트)

상태를 저장하는 가장 나쁜 시간은 다음과 같습니다.

  • beforeunload 이벤트 콜백에서
  • unload 이벤트 콜백에서

이는 상태를 저장하기에 가장 나쁜 시간입니다. 이러한 이벤트는 완전히 불안정하고 탭이 삭제되는 경우를 포함하여 많은 상황에서 실행되지 않기 때문입니다.

페이지 수명 주기 이벤트 다이어그램을 참조하여 페이지가 삭제될 때 실행될 것으로 예상되는 이벤트를 확인할 수 있습니다. 이 다이어그램에서 볼 수 있듯이 탭은 상태를 '삭제됨'으로 상태를 유지합니다.

Page Lifecycle API 상태 및 이벤트 흐름 이 문서 전체에 설명된 상태와 이벤트 흐름을 시각적으로 나타낸 것입니다.

실제로 페이지가 '숨겨진' 상태라면 상태에 있는 경우, 브라우저에서 페이지가 삭제되거나 사용자가 페이지를 종료하기 전에 다른 이벤트가 실행된다는 보장이 없습니다. 따라서 저장되지 않은 사용자 상태를 항상 visibilitychange 이벤트에 저장하는 것이 중요합니다. 이런 경우 다시 한 번 기회를 받지 못할 수 있습니다.

다음 코드는 현재 사용자 상태가 변경될 때마다 또는 사용자가 탭을 백그라운드로 이동하거나 다른 곳으로 이동하는 경우 즉시 현재 사용자 상태를 유지하는 큐의 몇 가지 예시 로직을 간략히 설명합니다.

let state = {};
let hasUnstoredState = false;

function storeState() {
  if (hasUnstoredState) {
    // Store `state` to localStorage or IndexedDB...
  }
  hasUnstoredState = false;
}

export function updateState(newState) {
  state = newState;
  hasUnstoredState = true;
  requestIdleCallback(storeState);
}

document.addEventListener('visibilitychange', () => {
  if (document.visibilityState === 'hidden') {
    storeState();
  }
});

탭이 삭제된 것을 감지

앞서 언급했듯이 탭이 곧 삭제될지 여부를 감지하는 것은 불가능합니다. 하지만 사용자가 탭으로 돌아와 페이지를 다시 로드하면 탭이 삭제되었음을 감지할 수는 있습니다. 이러한 상황에서는 document.wasDiscarded 속성이 true가 됩니다.

if (document.wasDiscarded) {
  // The page was reloaded after a discard.
} else {
  // The page was not reloaded after a discard.
}

사용자가 이러한 상황을 얼마나 자주 경험하는지 파악하려면 애널리틱스 도구를 구성하여 이러한 정보를 수집할 수 있습니다.

예를 들어 Google 애널리틱스에서는 탭 삭제에서 발생한 페이지 조회수의 비율을 확인할 수 있는 맞춤 이벤트 매개변수를 구성할 수 있습니다.

gtag('config', 'G-XXXXXXXXXX', {
  was_discarded: document.wasDiscarded,
});

분석 제공업체인 경우 제품에 기본적으로 이 측정기준을 추가하는 것이 좋습니다.

메모리 절약 모드에서 사이트 테스트

페이지를 로드한 후 별도의 탭이나 창에서 chrome://discards로 이동하여 페이지 삭제가 어떻게 처리되는지 테스트할 수 있습니다.

chrome://discards UI의 목록에서 삭제할 탭을 찾은 다음 작업 열에서 긴급 삭제를 클릭합니다.

탭 삭제 링크의 위치를 보여주는 chrome://discards UI 스크린샷

이렇게 하면 탭이 삭제되어 탭을 다시 방문하고 페이지를 닫았을 때와 동일한 상태로 다시 로드되었는지 확인할 수 있습니다.

현재 Webdriver나 Puppeteer와 같은 테스트 도구를 통해 탭 삭제를 자동화할 수 있는 방법은 없습니다. 하지만 탭 삭제 및 복원은 페이지 새로고침과 거의 동일하므로 사용자 플로우 중에 새로고침 후 사용자 상태가 복원되는지 테스트하면 삭제/복원에도 효과가 있을 수 있습니다. 둘의 주된 차이점은 beforeunload, pagehide, unload 이벤트는 탭이 삭제될 때 실행되지 않는다는 것입니다. 따라서 이러한 이벤트에 의존하여 사용자 상태를 유지하지 않는 한 새로고침을 사용하여 삭제/복원 동작을 테스트할 수 있습니다.

에너지 절약 모드

에너지 절약 모드를 사용 설정하면 Chrome에서 화면 재생 빈도를 줄여 배터리 전원을 절약하며 이는 스크롤 및 애니메이션 충실도와 동영상 프레임 속도에 영향을 미칩니다.

일반적으로 개발자는 에너지 절약 모드를 지원하기 위해 어떤 조치도 취할 필요가 없습니다. 이 모드를 사용 설정하면 애니메이션, 전환, requestAnimationFrame()용 CSS 및 JavaScript API가 디스플레이 새로고침 빈도의 변경사항에 맞게 자동으로 조정됩니다.

이 모드가 문제가 될 수 있는 주요 시나리오는 사이트에서 모든 사용자의 특정 새로고침 빈도를 가정하는 JavaScript 기반 애니메이션을 사용하는 경우입니다.

예를 들어 사이트에서 requestAnimationFrame() 루프를 사용하고 콜백 사이에 정확히 16.67밀리초가 경과할 것으로 가정하는 경우 에너지 절약 모드를 사용 설정하면 애니메이션이 두 배 느리게 실행됩니다.

개발자가 모든 사용자에 대해 기본 화면 재생 빈도를 60Hz로 가정하는 것은 항상 문제가 되었습니다. 이는 대부분의 현재 기기에 해당되지 않기 때문입니다.

디스플레이 새로고침 빈도 측정

디스플레이 새로고침 빈도를 측정하는 전용 웹 API는 없으며 일반적으로 현재 API를 사용하여 측정하는 것은 권장하지 않습니다.

기존 API를 사용하는 최상의 개발자는 연속적인 requestAnimationFrame() 콜백 간의 타임스탬프를 비교하는 것입니다. 이 기능은 대부분의 경우 특정 시점의 새로고침 빈도를 대략적으로 계산하지만, 새로고침 빈도가 변경되는 시점은 알 수 없습니다. 그렇게 하려면 requestAnimationFrame() 설문조사를 지속적으로 실행해야 하며, 이는 사용자의 에너지 또는 배터리 수명 절약이라는 목표를 무효화합니다.

에너지 절약 모드에서 사이트 테스트

에너지 절약 모드에서 사이트를 테스트하는 한 가지 방법은 Chrome 설정에서 모드를 사용 설정하고 기기가 전원에 연결되지 않았을 때 실행되도록 구성하는 것입니다.

연결 해제할 수 있는 기기가 없는 경우 다음 단계에 따라 수동으로 모드를 사용 설정할 수도 있습니다.

  1. chrome://flags/#battery-saver-mode-available 플래그를 사용 설정합니다.
  2. chrome://discards 페이지를 방문하여 절전 모드 전환 링크를 클릭합니다 (중요: 링크가 작동하려면 #battery-saver-mode-available 플래그를 사용 설정해야 함).

에너지 절약 모드 사용 설정 링크의 위치를 보여주는 chrome://discards UI 스크린샷

사용 설정되면 사이트와 상호작용하여 애니메이션 및 전환이 원하는 속도로 실행되는지와 같이 모든 항목이 제대로 표시되는지 확인할 수 있습니다.

요약

Chrome의 메모리 절약 모드 및 에너지 절약 모드는 주로 사용자에게 표시되는 기능이지만 제대로 처리하지 않으면 사이트를 방문하는 환경에 부정적인 영향을 미칠 수 있으므로 개발자에게 영향을 미칩니다.

일반적으로 이러한 새로운 모드는 기존 개발자 권장사항을 염두에 두고 설계되었습니다. 개발자가 오랫동안 웹 권장사항을 따랐다면 사이트는 이러한 새로운 모드에서도 잘 작동합니다.

하지만 사이트에 이 게시물에 나와 있는 관행이 포함되어 있다면 이 두 가지 모드를 사용하는 경우에만 문제가 증가할 가능성이 높습니다.

항상 그렇듯이 만족스러운 환경을 제공하고 있는지 확인하는 가장 좋은 방법은 사용자의 상황과 일치하는 조건으로 사이트를 테스트하는 것입니다.