Chrome, Opera, Yandex 브라우저에서 사용할 수 있는 Save-Data
클라이언트 힌트 요청 헤더를 사용하면 개발자가 브라우저에서 데이터 절약 모드를 선택한 사용자에게 더 가볍고 빠른 애플리케이션을 제공할 수 있습니다.
경량 페이지 필요성
더 빠르고 가벼운 웹페이지가 더 만족스러운 사용자 환경을 제공하고, 콘텐츠 이해도와 유지율을 높이며, 전환수와 수익을 늘린다는 데는 모두가 동의합니다. Google 연구에 따르면 '최적화된 페이지의 로드 속도는 원래 페이지보다 4배 빠르고 사용하는 바이트 수는 80% 적습니다. 최적화된 페이지가 로드되는 속도가 훨씬 빠르기 때문에 이러한 페이지로 유입되는 트래픽이 50% 증가했습니다."
2G 연결 수는 마침내 감소하고 있지만 2015년에는 2G가 여전히 주류 네트워크 기술이었습니다. 3G 및 4G 네트워크의 보급률과 사용 가능 여부는 빠르게 증가하고 있지만, 관련 소유권 비용과 네트워크 제약조건은 여전히 수억 명의 사용자에게 중요한 요소입니다.
이는 페이지 최적화에 대한 강력한 근거입니다.
프록시 브라우저 및 트랜스코딩 서비스와 같이 개발자가 직접 관여하지 않고도 사이트 속도를 개선할 수 있는 대안 방법이 있습니다. 이러한 서비스는 널리 사용되지만 간단하고(때로는 용납할 수 없는) 이미지 및 텍스트 압축, 보안 (HTTPS) 페이지를 처리할 수 없음, 검색 결과를 통해 방문한 페이지만 최적화 등 상당한 단점이 있습니다. 이러한 서비스의 인기는 웹 개발자가 빠르고 가벼운 애플리케이션과 페이지에 대한 높은 사용자 수요를 적절하게 충족하지 못하고 있음을 보여주는 지표입니다. 하지만 이 목표에 도달하는 것은 복잡하고 때로는 어려운 여정입니다.
Save-Data
요청 헤더
Save-Data
요청 헤더를 사용하여 브라우저가 도와주도록 하는 간단한 기법이 있습니다. 웹페이지는 이 헤더를 식별하여 비용 및 성능 제약이 있는 사용자에게 최적화된 사용자 환경을 맞춤설정하고 제공할 수 있습니다.
지원되는 브라우저 (아래)를 사용하면 사용자가 *데이터 절약 모드를 사용 설정할 수 있습니다. 이 모드를 사용하면 브라우저에 일련의 최적화를 적용하여 페이지 렌더링에 필요한 데이터 양을 줄일 수 있는 권한이 부여됩니다. 이 기능이 노출되거나 광고되면 브라우저는 더 낮은 해상도의 이미지를 요청하거나 일부 리소스의 로드를 지연하거나 이미지 및 텍스트 리소스 압축과 같은 다른 콘텐츠별 최적화를 적용하는 서비스를 통해 요청을 라우트할 수 있습니다.
브라우저 지원
- Chrome 49 이상은 사용자가 모바일에서 '데이터 절약 모드' 옵션을 사용 설정하거나 데스크톱 브라우저에서 '데이터 절약 모드' 확장 프로그램을 사용 설정하면
Save-Data
를 광고합니다. - Opera 35 이상은 사용자가 데스크톱에서 'Opera Turbo' 모드를 사용 설정하거나 Android 브라우저에서 '데이터 절약' 옵션을 사용 설정하면
Save-Data
를 광고합니다. - Yandex 16.2 이상은 데스크톱 또는 모바일 브라우저에서 터보 모드가 사용 설정된 경우
Save-Data
를 광고합니다.
Save-Data
설정 감지
사용자에게 '가벼운' 환경을 제공할 시기를 결정하기 위해 애플리케이션은 Save-Data
클라이언트 힌트 요청 헤더를 확인할 수 있습니다. 이 요청 헤더는 높은 전송 비용, 느린 연결 속도 또는 기타 이유로 인해 데이터 사용량을 줄이려는 클라이언트의 환경설정을 나타냅니다.
사용자가 브라우저에서 데이터 절약 모드를 사용 설정하면 브라우저는 모든 발신 요청 (HTTP 및 HTTPS 모두)에 Save-Data
요청 헤더를 추가합니다.
이 글을 작성하는 시점에서 브라우저는 헤더(Save-Data: on
)에 하나의 *on 토큰만 광고하지만 향후 다른 사용자 환경설정을 나타내기 위해 확장될 수 있습니다.
또한 JavaScript에서 Save-Data
가 사용 설정되어 있는지 감지할 수 있습니다.
if ('connection' in navigator) {
if (navigator.connection.saveData === true) {
// Implement data saving operations here.
}
}
navigator
객체 내에 connection
객체가 있는지 확인하는 것은 매우 중요합니다. connection
객체는 Chrome, Android용 Chrome, Samsung Internet 브라우저에서만 구현되는 Network Information API를 나타내기 때문입니다. 그런 다음 navigator.connection.saveData
가 true
와 같은지만 확인하면 되며, 이 조건에서 데이터 저장 작업을 구현할 수 있습니다.
애플리케이션이 서비스 워커를 사용하는 경우 요청 헤더를 검사하고 관련 로직을 적용하여 환경을 최적화할 수 있습니다.
또는 서버가 Save-Data
요청 헤더에서 광고된 환경설정을 찾아 다른 응답(예: 다른 마크업, 더 작은 이미지 및 동영상 등)을 반환할 수 있습니다.
구현 도움말 및 권장사항
Save-Data
를 사용할 때는 이를 지원하고 사용자가 환경 간에 쉽게 전환할 수 있는 UI 기기를 제공합니다. 예를 들면 다음과 같습니다.- 사용자에게
Save-Data
가 지원된다고 알리고 사용하도록 권장합니다. - 사용자가 적절한 메시지와 직관적인 켜기/끄기 버튼 또는 체크박스로 모드를 식별하고 선택할 수 있도록 합니다.
- 데이터 절약 모드가 선택된 경우 이를 사용 중지하고 원하는 경우 전체 환경으로 되돌리는 쉽고 명확한 방법을 알리고 제공합니다.
- 사용자에게
- 경량 애플리케이션은 열등한 애플리케이션이 아닙니다. 중요한 기능이나 데이터를 생략하지는 않지만 관련 비용과 사용자 환경을 더 잘 인식하고 있습니다. 예를 들면 다음과 같습니다.
- 사진 갤러리 애플리케이션은 더 낮은 해상도의 미리보기를 제공하거나 코드가 적은 캐러셀 메커니즘을 사용할 수 있습니다.
- 검색 애플리케이션은 한 번에 더 적은 결과를 반환하거나, 미디어가 많은 결과의 수를 제한하거나, 페이지 렌더링에 필요한 종속 항목 수를 줄일 수 있습니다.
- 뉴스 중심 사이트는 뉴스를 더 적게 표시하거나 인기가 없는 카테고리를 생략하거나 미디어 미리보기를 더 작게 제공할 수 있습니다.
Save-Data
요청 헤더를 확인하는 서버 로직을 제공하고 사용 설정된 경우 더 가벼운 대체 페이지 응답을 제공하는 것이 좋습니다(예: 필요한 리소스 및 종속 항목의 수를 줄이고 더 공격적인 리소스 압축 적용 등).Save-Data
헤더를 기반으로 대체 응답을 제공하는 경우 Vary 목록(Vary: Save-Data
)에 추가하여 업스트림 캐시가Save-Data
요청 헤더가 있는 경우에만 이 버전을 캐시하고 제공해야 한다고 알리세요. 자세한 내용은 캐시와의 상호작용 권장사항을 참고하세요.
- 서비스 워커를 사용하는 경우 애플리케이션은
Save-Data
요청 헤더의 존재를 확인하거나navigator.connection.saveData
속성의 값을 확인하여 데이터 저장 옵션이 사용 설정된 시점을 감지할 수 있습니다. 사용 설정된 경우 요청을 재작성하여 더 적은 바이트를 가져오거나 이미 가져온 응답을 사용할 수 있는지 고려하세요. - 사용자의 연결 유형 및 기술에 관한 정보와 같은 다른 신호로
Save-Data
를 보강하는 것이 좋습니다 (NetInfo API 참고). 예를 들어Save-Data
가 사용 설정되지 않은 경우에도 2G 연결을 사용하는 모든 사용자에게 가벼운 환경을 제공할 수 있습니다. 반대로 사용자가 '빠른' 4G 연결을 사용하고 있다고 해서 데이터를 절약하는 데 관심이 없는 것은 아닙니다(예: 로밍 중). 또한Device-Memory
클라이언트 힌트로Save-Data
의 존재를 보강하여 메모리가 제한된 기기의 사용자에게 더 적응할 수 있습니다. 사용자 기기 메모리는navigator.deviceMemory
클라이언트 힌트에서도 광고됩니다.
레시피
Save-Data
를 통해 얻을 수 있는 결과는 개발자가 생각해 낼 수 있는 것에만 제한됩니다. 가능한 작업을 알아보려면 몇 가지 사용 사례를 살펴보겠습니다. 이 도움말을 읽으면서 다른 사용 사례를 생각해 낼 수도 있습니다. 자유롭게 실험하고 어떤 기능이 가능한지 확인해 보세요.
서버 측 코드에서 Save-Data
확인
Save-Data
상태는 navigator.connection.saveData
속성을 통해 JavaScript에서 감지할 수 있지만 서버 측에서 감지하는 것이 더 나은 경우가 있습니다. 경우에 따라 JavaScript가 실행되지 않을 수 있습니다. 또한 서버 측 감지는 마크업을 클라이언트로 전송하기 전에 수정하는 유일한 방법이며, 이는 Save-Data
의 가장 유용한 사용 사례 중 일부와 관련이 있습니다.
서버 측 코드에서 Save-Data
헤더를 감지하기 위한 구문은 사용되는 언어에 따라 다르지만 기본 개념은 모든 애플리케이션 백엔드에서 동일해야 합니다. 예를 들어 PHP에서는 요청 헤더가 HTTP_
로 시작하는 색인에서 $_SERVER
슈퍼글로벌 배열에 저장됩니다. 즉, 다음과 같이 $_SERVER["HTTP_SAVE_DATA"]
변수의 존재와 값을 확인하여 Save-Data
헤더를 감지할 수 있습니다.
// false by default.
$saveData = false;
// Check if the `Save-Data` header exists and is set to a value of "on".
if (isset($_SERVER["HTTP_SAVE_DATA"]) && strtolower($_SERVER["HTTP_SAVE_DATA"]) === "on") {
// `Save-Data` detected!
$saveData = true;
}
마크업이 클라이언트로 전송되기 전에 이 검사를 실행하면 $saveData
변수에 Save-Data
상태가 포함되며 페이지 어디서나 사용할 수 있습니다. 이 메커니즘을 사용하여 사용자에게 전송하는 데이터의 양을 제한하는 방법을 보여주는 몇 가지 예를 살펴보겠습니다.
고해상도 화면에 낮은 해상도 이미지 제공
웹에서 이미지를 사용하는 일반적인 사례는 이미지를 2개씩 제공하는 것입니다. 하나는 '표준' 화면용 이미지 (1x)이고 다른 하나는 고해상도 화면용 이미지(2x)입니다 (예: Retina 디스플레이). 이 고해상도 화면 클래스는 고급 기기에만 국한되지 않으며 점점 더 보편화되고 있습니다. 더 가벼운 애플리케이션 환경을 선호하는 경우 더 큰 (2x) 변형이 아닌 더 낮은 해상도 (1x) 이미지를 이러한 화면에 전송하는 것이 좋습니다. Save-Data
헤더가 있는 경우 이를 실행하려면 클라이언트로 전송하는 마크업을 수정하면 됩니다.
if ($saveData === true) {
// Send a low-resolution version of the image for clients specifying `Save-Data`.
?><img src="butterfly-1x.jpg" alt="A butterfly perched on a flower."><?php
}
else {
// Send the usual assets for everyone else.
?><img src="butterfly-1x.jpg" srcset="butterfly-2x.jpg 2x, butterfly-1x.jpg 1x" alt="A butterfly perched on a flower."><?php
}
이 사용 사례는 데이터를 더 적게 보내 달라고 요청하는 사용자를 수용하는 데 얼마나 적은 노력이 필요한지 보여주는 완벽한 예입니다. 백엔드에서 마크업을 수정하고 싶지 않다면 Apache의 mod_rewrite
와 같은 URL 재작성 모듈을 사용하여 동일한 결과를 얻을 수도 있습니다. 비교적 적은 구성으로 이를 실행하는 방법의 예가 있습니다.
<html>
요소에 클래스를 추가하여 이 개념을 CSS background-image
속성으로 확장할 수도 있습니다.
<html class="<?php if ($saveData === true): ?>save-data<?php endif; ?>">
여기에서 CSS의 <html>
요소에서 save-data
클래스를 타겟팅하여 이미지가 전송되는 방식을 변경할 수 있습니다. 위의 HTML 예와 같이 저해상도 배경 이미지를 고해상도 화면으로 전송하거나 특정 리소스를 완전히 생략할 수 있습니다.
불필요한 이미지 생략
웹에 있는 일부 이미지 콘텐츠는 그저 중요하지 않습니다. 이러한 이미지는 콘텐츠에 멋진 부연 설명을 제공할 수 있지만, 요금제가 적용된 데이터 요금제에서 최대한의 혜택을 누리려는 사용자에게는 바람직하지 않을 수 있습니다. Save-Data
의 가장 간단한 사용 사례에서는 앞의 PHP 감지 코드를 사용하고 중요하지 않은 이미지 마크업을 완전히 생략할 수 있습니다.
<p>This paragraph is essential content. The image below may be humorous, but it's not critical to the content.</p>
<?php
if ($saveData === false) {
// Only send this image if `Save-Data` hasn't been detected.
?><img src="meme.jpg" alt="One does not simply consume data."><?php
}
아래 그림에서 볼 수 있듯이 이 기법은 확실히 눈에 띄는 효과를 줄 수 있습니다.
물론 이미지를 생략하는 것만이 유일한 방법은 아닙니다. Save-Data
에 작업을 실행하여 특정 서체와 같은 중요하지 않은 다른 리소스를 전송하지 않을 수도 있습니다.
필수가 아닌 웹 글꼴 생략
웹 글꼴은 일반적으로 이미지만큼 특정 페이지의 총 페이로드를 차지하지는 않지만 여전히 인기가 높습니다. 데이터를 소량만 소비하지도 않습니다. 또한 브라우저가 글꼴을 가져오고 렌더링하는 방식은 생각보다 복잡합니다. FOIT, FOUT, 브라우저 휴리스틱과 같은 개념이 렌더링을 미묘한 작업으로 만듭니다.
따라서 더 간소한 사용자 환경을 원하는 사용자를 위해 불필요한 웹 글꼴은 제외하는 것이 좋습니다. Save-Data
를 사용하면 비교적 쉽게 할 수 있습니다.
예를 들어 Google Fonts의 Fira Sans를 사이트에 포함했다고 가정해 보겠습니다. Fira Sans는 훌륭한 본문 글꼴이지만 데이터를 저장하려는 사용자에게는 그다지 중요하지 않을 수 있습니다. Save-Data
헤더가 있을 때 <html>
요소에 save-data
클래스를 추가하면 처음에는 중요하지 않은 서체를 호출하지만 Save-Data
헤더가 있으면 이를 선택 해제하는 스타일을 작성할 수 있습니다.
/* Opt into web fonts by default. */
p,
li {
font-family: 'Fira Sans', 'Arial', sans-serif;
}
/* Opt out of web fonts if the `save-Data` class is present. */
.save-data p,
.save-data li {
font-family: 'Arial', sans-serif;
}
이 접근 방식을 사용하면 Google Fonts의 <link>
스니펫을 그대로 둘 수 있습니다. 브라우저가 먼저 DOM에 스타일을 적용한 다음 HTML 요소가 스타일 시트의 리소스를 호출하는지 확인하여 CSS 리소스 (웹 글꼴 포함)를 추측적으로 로드하기 때문입니다. Save-Data
가 사용 설정된 상태에서 사용자가 지나가면 스타일이 지정된 DOM이 Fira Sans를 호출하지 않으므로 Fira Sans가 로드되지 않습니다. 대신 Arial이 사용됩니다. Fira Sans만큼 좋지는 않지만 데이터 요금제를 늘리려는 사용자에게는 더 적합할 수 있습니다.
요약
Save-Data
헤더에는 미묘한 차이가 없습니다. 켜져 있거나 꺼져 있으며 애플리케이션은 이유와 관계없이 설정에 따라 적절한 환경을 제공해야 합니다.
예를 들어 연결 상태가 좋지 않은 경우에도 앱 콘텐츠나 기능이 손실될 것으로 생각하는 사용자는 데이터 절약 모드를 허용하지 않을 수 있습니다. 반대로 일부 사용자는 연결 상태가 양호한 경우에도 페이지를 최대한 작고 단순하게 유지하기 위해 당연히 이 기능을 사용 설정할 수 있습니다. 명시적인 사용자 작업을 통해 명확한 신호가 있을 때까지는 사용자가 완전하고 제한 없는 환경을 원한다고 가정하는 것이 가장 좋습니다.
사이트 소유자와 웹 개발자는 데이터 및 비용 제약이 있는 사용자의 사용자 환경을 개선하기 위해 콘텐츠를 관리할 책임이 있습니다.
Save-Data
에 관한 자세한 내용과 훌륭한 실용적인 예는 사용자 지원 Save Data
을 참고하세요.