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

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

이러한 새로운 모드는 주로 사용자를 대상으로 하지만 사이트의 사용자 환경에 영향을 미칠 수 있으므로 웹 개발자가 알아야 하는 몇 가지 의미가 있습니다.

이 게시물에서는 이러한 새로운 모드의 잠재적 영향과 웹 개발자가 최상의 환경을 제공하기 위해 취할 수 있는 조치를 다룹니다.

메모리 절약 모드

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

탭이 삭제되면 탭 제목과 favicon은 탭 스트립에 계속 표시되지만 페이지 자체는 탭이 정상적으로 닫힌 것처럼 사라집니다. 사용자가 해당 탭을 다시 방문하면 페이지가 자동으로 새로고침됩니다.

순수한 콘텐츠 페이지의 경우 탭을 삭제하고 새로고침해도 사용자 환경에 영향을 미치지 않을 수 있지만, 복잡한 사용자 흐름이 있는 풍부한 양방향 사이트의 경우 사이트에서 페이지를 사용자가 중단한 지점으로 정확하게 복원할 수 없는 경우 흐름 중간에 새로고침하면 매우 불편할 수 있습니다.

메모리를 절약하기 위해 탭을 삭제하는 작업은 Chrome에서 오랫동안 해왔던 작업이지만 시스템에 메모리 부족 문제가 있는 경우에만 실행되었습니다. 비교적 드물게 발생하는 문제이므로 웹 개발자가 이러한 문제가 발생하고 있는지 인지하지 못했을 수 있습니다.

Chrome 108부터 탭 삭제가 더 일반적으로 이루어지므로 사이트에서 이러한 상황을 적절하게 처리하는 것이 중요합니다.

탭 삭제를 처리하기 위한 권장사항

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

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

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

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

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

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

이러한 이벤트는 완전히 신뢰할 수 없으며 탭이 삭제되는 경우를 비롯한 많은 상황에서 실행되지 않으므로 상태를 저장하기에 가장 좋지 않은 시점입니다.

페이지 수명 주기 이벤트 다이어그램을 참고하여 페이지가 삭제될 때 실행될 이벤트를 확인할 수 있습니다. 이 다이어그램에서 볼 수 있듯이 탭은 이벤트가 실행되지 않고도 '숨김' 상태에서 '삭제됨' 상태로 전환될 수 있습니다.

페이지 수명 주기 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의 메모리 절약 모드 및 에너지 절약 모드는 주로 사용자 대상 기능이지만 제대로 처리되지 않으면 사이트 방문 환경에 부정적인 영향을 미칠 수 있으므로 개발자에게도 영향을 미칩니다.

일반적으로 이러한 새로운 모드는 기존 개발자 권장사항을 고려하여 설계되었습니다. 개발자가 오랫동안 웹 권장사항을 준수해 왔다면 사이트가 이러한 새 모드에서 계속 잘 작동합니다.

하지만 사이트에 이 게시물에서 언급한 관행이 포함되어 있다면 사용자에게 문제가 발생할 수 있으며 이 두 가지 모드를 사용 설정하면 문제가 더 커질 수 있습니다.

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