프론트엔드 성능 2021: 자산 최적화
게시 됨: 2022-03-10이 가이드는 프론트엔드 성능 모니터링 , 세션 재생 및 제품 분석을 결합하여 더 나은 고객 경험을 구축하는 데 도움이 되는 서비스인 LogRocket의 친구들로부터 친절하게 지원되었습니다. LogRocket 은 다음을 포함한 주요 지표를 추적합니다. DOM 완료, 첫 번째 바이트까지의 시간, 첫 번째 입력 지연, 클라이언트 CPU 및 메모리 사용량. 지금 LogRocket의 무료 평가판을 받으십시오.
목차
- 준비하기: 계획 및 측정항목
- 현실적인 목표 설정
- 환경 정의
- 자산 최적화
- 빌드 최적화
- 배달 최적화
- 네트워킹, HTTP/2, HTTP/3
- 테스트 및 모니터링
- 빠른 승리
- 한 페이지에 모든 것
- 체크리스트 다운로드(PDF, Apple Pages, MS Word)
- 다음 가이드를 놓치지 않으려면 이메일 뉴스레터를 구독하세요.
자산 최적화
- 일반 텍스트 압축에는 Brotli를 사용하십시오.
2015년에 Google은 모든 최신 브라우저에서 지원되는 새로운 오픈 소스 무손실 데이터 형식인 Brotli를 도입했습니다. Brotli용 인코더와 디코더를 구현하는 오픈 소스 Brotli 라이브러리에는 인코더에 대해 미리 정의된 11가지 품질 수준이 있으며 품질 수준이 높을수록 더 나은 압축률을 위해 더 많은 CPU가 필요합니다. 느린 압축은 궁극적으로 더 높은 압축률로 이어지지만 여전히 Brotli는 빠르게 압축을 풉니다. 압축 수준이 4인 Brotli는 Gzip보다 작고 압축 속도가 빠릅니다.실제로 Brotli는 Gzip보다 훨씬 더 효과적인 것으로 보입니다. 의견과 경험은 다르지만 사이트가 이미 Gzip으로 최적화되어 있는 경우 크기 축소 및 FCP 타이밍에서 최소 한 자릿수 개선과 기껏해야 두 자릿수 개선을 기대할 수 있습니다. 사이트에 대한 Brotli 압축 절감 효과를 추정할 수도 있습니다.
브라우저는 사용자가 HTTPS를 통해 웹사이트를 방문하는 경우에만 Brotli를 허용합니다. Brotli는 광범위하게 지원되며 많은 CDN(Akamai, Netlify Edge, AWS, KeyCDN, Fastly(현재는 패스스루), Cloudflare, CDN77)에서 지원하며 아직 지원하지 않는 CDN에서도 Brotli를 활성화할 수 있습니다. (서비스 워커와 함께).
문제는 높은 압축 수준에서 Brotli로 모든 자산을 압축하는 데 비용이 많이 들기 때문에 많은 호스팅 제공자가 생성하는 막대한 비용 오버헤드 때문에 전체 호출에서 이를 사용할 수 없다는 것입니다. 사실, 가장 높은 압축 수준에서 Brotli는 너무 느려서 서버가 자산을 동적으로 압축할 때까지 응답을 보내기 시작하는 데 걸리는 시간으로 인해 파일 크기의 잠재적인 이득이 무효화될 수 있습니다. (그러나 정적 압축으로 빌드 시간에 시간이 있다면 물론 더 높은 압축 설정이 선호됩니다.)
그러나 이것은 바뀔 수 있습니다. Brotli 파일 형식에는 내장된 정적 사전 이 포함되어 있으며 여러 언어로 된 다양한 문자열을 포함할 뿐만 아니라 해당 단어에 여러 변환을 적용하는 옵션도 지원하여 다양성을 높입니다. 그의 연구에서
Content-Type
Hanau는 "기본값보다 사전의 더 전문화된 하위 집합"을 사용하고 압축기에 HTML, JavaScript 또는 CSS용 사전. 결과는 "제한된 사전 사용 접근 방식을 사용하여 높은 압축 수준에서 웹 콘텐츠를 압축할 때 무시할 수 있는 성능 영향(일반적으로 12%에 비해 1%에서 3% 더 많은 CPU)"이었습니다.게다가 Elena Kirilenko의 연구를 통해 이전 압축 아티팩트를 사용하여 빠르고 효율적인 Brotli 재압축 을 달성할 수 있습니다. Elena에 따르면 " 일단 Brotli를 통해 압축된 자산이 있고 콘텐츠가 미리 사용 가능한 콘텐츠와 유사한 동적 콘텐츠를 즉석에서 압축하려고 하면 압축 시간을 크게 개선할 수 있습니다. "
얼마나 자주 경우입니까? 예를 들어 JavaScript 번들 하위 집합 을 전달하는 경우(예: 코드의 일부가 이미 클라이언트에 캐시되어 있거나 WebBundles와 함께 제공되는 동적 번들이 있는 경우). 또는 미리 알려진 템플릿을 기반으로 하는 동적 HTML 또는 동적으로 부분집합된 WOFF2 글꼴 을 사용합니다. Elena에 따르면 콘텐츠의 10%를 제거하면 압축률이 5.3%, 압축 속도가 39% 향상되며, 콘텐츠의 50%를 제거하면 압축률이 3.2%, 압축률이 26% 빨라집니다.
Brotli 압축이 점점 더 좋아지고 있으므로 정적 자산을 동적으로 압축하는 비용을 우회할 수 있다면 노력할 가치가 있습니다. Brotli는 HTML, CSS, SVG, JavaScript, JSON 등 모든 일반 텍스트 페이로드에 사용할 수 있습니다.
참고 : 2021년 초 현재 HTTP 응답의 약 60%가 텍스트 기반 압축 없이 전달되며, 30.82%는 Gzip으로, 9.1%는 Brotli로 압축합니다(모바일 및 데스크톱 모두). 예를 들어, Angular 페이지의 23.4%는 압축되지 않습니다(gzip 또는 Brotli를 통해). 그러나 종종 압축을 켜는 것은 스위치를 살짝 눌러 성능을 향상시키는 가장 쉬운 방법 중 하나입니다.
전략? 최고 수준에서 Brotli+Gzip을 사용하여 정적 자산을 사전 압축하고 수준 4-6에서 Brotli를 사용하여 즉석에서 (동적) HTML을 압축합니다. 서버가 Brotli 또는 Gzip에 대한 콘텐츠 협상을 올바르게 처리하는지 확인하십시오.
- 적응형 미디어 로딩과 클라이언트 힌트를 사용합니까?
그것은 오래된 뉴스의 땅에서srcset
,sizes
및<picture>
요소와 함께 반응형 이미지를 사용하는 것은 항상 좋은 일입니다. 특히 미디어 풋프린트가 많은 사이트의 경우 적응형 미디어 로딩(이 예에서는 React + Next.js)을 사용하여 한 단계 더 나아가 느린 네트워크 및 저메모리 장치에 가벼운 경험을 제공하고 빠른 네트워크 및 높은 - 기억 장치. React의 맥락에서 우리는 서버의 클라이언트 힌트와 클라이언트의 react-adaptive-hooks를 사용하여 이를 달성할 수 있습니다.반응형 이미지의 미래는 클라이언트 힌트의 광범위한 채택으로 극적으로 바뀔 수 있습니다. 클라이언트 힌트는
DPR
,Viewport-Width
,Width
,Save-Data
,Accept
(이미지 형식 기본 설정 지정용) 등의 HTTP 요청 헤더 필드입니다. 그들은 사용자의 브라우저, 화면, 연결 등의 세부 사항에 대해 서버에 알려야 합니다.결과적으로 서버는 적절한 크기의 이미지 로 레이아웃을 채우는 방법을 결정할 수 있으며 이러한 이미지만 원하는 형식으로 제공할 수 있습니다. 클라이언트 힌트를 사용하여 리소스 선택을 HTML 마크업에서 클라이언트와 서버 간의 요청-응답 협상으로 이동합니다.
Ilya Grigorik이 얼마 전에 언급했듯이 클라이언트 힌트는 그림을 완성합니다. 반응형 이미지의 대안이 아닙니다. "
<picture>
요소는 HTML 마크업에서 필요한 아트 방향 제어를 제공합니다. 클라이언트 힌트는 리소스 선택 자동화를 가능하게 하는 결과 이미지 요청에 대한 주석을 제공합니다. Service Worker는 클라이언트에서 전체 요청 및 응답 관리 기능을 제공합니다."서비스 작업자는 예를 들어 요청에 새 클라이언트 힌트 헤더 값을 추가 하고, URL을 다시 작성하고 이미지 요청을 CDN으로 가리키고, 연결 및 사용자 기본 설정 등에 따라 응답을 조정할 수 있습니다. 이는 이미지 자산뿐만 아니라 거의 모든 다른 요청에 대해서도 마찬가지입니다.
클라이언트 힌트를 지원하는 클라이언트의 경우 이미지에서 42% 바이트 절약을 측정할 수 있고 70번째 백분위수 이상에 대해 1MB 이상 더 적은 바이트를 측정할 수 있습니다. Smashing Magazine에서도 19-32% 개선을 측정할 수 있습니다. 클라이언트 힌트는 Chromium 기반 브라우저에서 지원되지만 Firefox에서는 아직 고려 중입니다.
그러나 일반 반응형 이미지 마크업과 클라이언트 힌트에 대한
<meta>
태그를 모두 제공하는 경우 지원 브라우저는 반응형 이미지 마크업을 평가하고 클라이언트 힌트 HTTP 헤더를 사용하여 적절한 이미지 소스를 요청합니다. - 배경 이미지에 반응형 이미지를 사용합니까?
우리는 반드시 해야 합니다! 이제 Safari 14와 Firefox를 제외한 대부분의 최신 브라우저에서 지원되는image-set
을 사용하여 반응형 배경 이미지도 제공할 수 있습니다.background-image: url("fallback.jpg"); background-image: image-set( "photo-small.jpg" 1x, "photo-large.jpg" 2x, "photo-print.jpg" 600dpi);
기본적으로 우리는 조건부로
1x
설명자가 있는 저해상도 배경 이미지,2x
설명자가 있는 고해상도 이미지,600dpi
설명자가 있는 인쇄 품질 이미지를 제공할 수 있습니다. 그러나 브라우저는 보조 기술에 배경 이미지에 대한 특별한 정보를 제공하지 않으므로 이상적으로는 이러한 사진이 단지 장식일 것입니다. - WebP를 사용합니까?
이미지 압축은 종종 빠른 승리로 간주되지만 실제로는 여전히 많이 활용되지 않습니다. 물론 이미지는 렌더링을 차단하지 않지만 낮은 LCP 점수에 크게 기여하며 매우 자주 사용되는 장치에 비해 너무 무겁고 너무 큽니다.따라서 최소한 이미지에 WebP 형식을 사용하여 탐색할 수 있습니다. 사실, WebP 사가는 작년에 Apple이 Safari 14에서 WebP에 대한 지원을 추가하면서 거의 끝나가고 있습니다. 따라서 수년간의 토론과 토론 끝에 오늘 현재 WebP는 모든 최신 브라우저에서 지원됩니다. 따라서 필요한 경우(Andreas Bovens의 코드 스니펫 참조) 또는 콘텐츠 협상(
Accept
헤더 사용)을 사용하여<picture>
요소와 JPEG 폴백을 사용하여 WebP 이미지를 제공할 수 있습니다.WebP에도 단점 이 없는 것은 아닙니다. WebP 이미지 파일 크기는 동등한 Guetzli 및 Zopfli와 비교되지만 형식은 JPEG와 같은 프로그레시브 렌더링을 지원하지 않습니다. 따라서 WebP 이미지는 네트워크를 통해 더 빨라질 수 있지만 사용자는 좋은 ol' JPEG로 완성된 이미지를 더 빨리 볼 수 있습니다. JPEG를 사용하면 WebP의 경우와 같이 절반이 비어 있는 이미지가 아니라 데이터의 절반 또는 4분의 1로 "적절한" 사용자 경험을 제공하고 나머지는 나중에 로드할 수 있습니다.
결정은 목표에 따라 달라집니다. WebP를 사용하면 페이로드를 줄이고 JPEG를 사용하면 인지된 성능을 개선할 수 있습니다. WebP에 대한 자세한 내용은 Google Pascal Massimino의 WebP Rewind 토크에서 확인할 수 있습니다.
WebP로 변환하려면 WebP Converter, cwebp 또는 libwebp를 사용할 수 있습니다. Ire Aderinokun은 이미지를 WebP로 변환하는 방법에 대한 매우 자세한 자습서도 제공합니다. Josh Comeau도 현대 이미지 형식 수용에 대한 그의 글에서 그렇습니다.
Sketch는 기본적으로 WebP를 지원하며 Photoshop용 WebP 플러그인을 사용하여 Photoshop에서 WebP 이미지를 내보낼 수 있습니다. 그러나 다른 옵션도 사용할 수 있습니다.
WordPress 또는 Joomla를 사용하는 경우 WordPress용 Optimus 및 Cache Enabler 및 Joomla의 자체 지원 확장(Cody Arsenault를 통해)과 같이 WebP 지원을 쉽게 구현하는 데 도움이 되는 확장이 있습니다. React, 스타일이 지정된 구성 요소 또는 gatsby-image를 사용하여
<picture>
요소를 추상화할 수도 있습니다.아 - 뻔뻔한 플러그! — Jeremy Wagner는 WebP에 관한 모든 것에 관심이 있는지 확인하고 싶을 수도 있는 WebP에 대한 Smashing 책을 출판했습니다.
- AVIF를 사용합니까?
큰 소식을 들었을 수도 있습니다. AVIF가 출시되었습니다. AV1 비디오의 키프레임에서 파생된 새로운 이미지 형식입니다. 손실 및 무손실 압축, 애니메이션, 손실 알파 채널을 지원하고 선명한 선과 단색(JPEG의 문제)을 처리할 수 있는 동시에 더 나은 결과를 제공하는 개방형 로열티 프리 형식입니다.사실, WebP 및 JPEG와 비교하여 AVIF는 훨씬 더 나은 성능 을 보여 동일한 DSSIM에서 최대 50%까지 파일 크기를 중앙값으로 절약합니다(인간의 시각을 근사하는 알고리즘을 사용하는 두 개 이상의 이미지 간의 유사성). 실제로 Malte Ubl은 이미지 로딩 최적화에 대한 철저한 게시물에서 AVIF가 "매우 중요한 방식으로 JPEG보다 일관되게 성능이 뛰어납니다. 이것은 JPEG보다 항상 더 작은 이미지를 생성하지 않으며 실제로는 실제 네트워크일 수 있는 WebP와 다릅니다. 점진적 로딩에 대한 지원 부족으로 인한 손실"
아이러니하게도 AVIF는 대형 SVG보다 훨씬 더 나은 성능을 발휘할 수 있지만 물론 SVG를 대체하는 것으로 보여서는 안 됩니다. 또한 HDR 색상 지원을 지원하는 최초의 이미지 형식 중 하나입니다. 더 높은 밝기, 색 비트 깊이 및 색 영역을 제공합니다. 유일한 단점은 현재 AVIF가 프로그레시브 이미지 디코딩(아직?)을 지원하지 않고 Brotli와 유사하게 높은 압축률 인코딩이 디코딩은 빠르지만 현재 상당히 느리다는 것입니다.
AVIF는 현재 Chrome, Firefox 및 Opera에서 지원되며 Safari에서도 곧 지원될 예정입니다(Apple이 AV1을 만든 그룹의 구성원이기 때문에).
그렇다면 요즘 이미지를 제공하는 가장 좋은 방법 은 무엇입니까? 일러스트레이션 및 벡터 이미지의 경우 (압축) SVG가 의심할 여지 없이 최고의 선택입니다. 사진의 경우
picture
요소와 콘텐츠 협상 방법을 사용합니다. AVIF가 지원되는 경우 AVIF 이미지를 보냅니다. 그렇지 않은 경우 먼저 WebP로 폴백하고 WebP가 지원되지 않는 경우 폴백으로 JPEG 또는 PNG로 전환합니다(필요한 경우@media
조건 적용).<picture> <source type="image/avif"> <source type="image/webp"> <img src="image.jpg" alt="Photo" width="450" height="350"> </picture>
솔직히 말해서
picture
요소 내에서 몇 가지 조건을 사용할 가능성이 더 큽니다.<picture> <source type="image/avif" /> <source type="image/webp" /> <source type="image/jpeg" /> <img src="fallback-image.jpg" alt="Photo" width="450" height="350"> </picture>
<picture> <source type="image/avif" /> <source type="image/webp" /> <source type="image/jpeg" /> <img src="fallback-image.jpg" alt="Photo" width="450" height="350"> </picture>
애니메이션 이미지를 정적 이미지로 교체하여 보다 적은 움직임을
prefers-reduced-motion
고객을 위해 더 나아갈 수 있습니다.<picture> <source media="(prefers-reduced-motion: reduce)" type="image/avif"></source> <source media="(prefers-reduced-motion: reduce)" type="image/jpeg"></source> <source type="image/avif"></source> <img src="motion.jpg" alt="Animated AVIF"> </picture>
<picture> <source media="(prefers-reduced-motion: reduce)" type="image/avif"></source> <source media="(prefers-reduced-motion: reduce)" type="image/jpeg"></source> <source type="image/avif"></source> <img src="motion.jpg" alt="Animated AVIF"> </picture>
몇 달 동안 AVIF는 상당한 주목을 받았습니다.
- DevTools의 렌더링 패널에서 WebP/AVIF 폴백을 테스트할 수 있습니다.
- Squoosh, AVIF.io 및 libavif를 사용하여 AVIF 파일을 인코딩, 디코딩, 압축 및 변환할 수 있습니다.
- 작업자의 AVIF 파일을 디코딩하고 캔버스에 결과를 표시하는 Jake Archibald의 AVIF Preact 구성 요소를 사용할 수 있습니다.
- 지원하는 브라우저에만 AVIF를 제공하기 위해 PostCSS 플러그인을 315B 스크립트와 함께 사용하여 CSS 선언에서 AVIF를 사용할 수 있습니다.
- CSS 및 Cloudlare 작업자를 통해 새로운 이미지 형식을 점진적으로 제공하여 반환된 HTML 문서를 동적으로 변경하고
accept
헤더에서 정보를 추론한 다음 적절하게webp/avif
등의 클래스를 추가할 수 있습니다. - AVIF는 이미 Cloudinary에서 사용할 수 있으며(사용 제한 있음) Cloudflare는 이미지 크기 조정에서 AVIF를 지원하며 Netlify에서 사용자 지정 AVIF 헤더로 AVIF를 활성화할 수 있습니다.
- 애니메이션과 관련하여 AVIF는 Safari의
<img src=mp4>
만큼 성능이 뛰어나 GIF 및 WebP보다 성능이 우수하지만 MP4는 여전히 더 나은 성능을 제공합니다. - 일반적으로 애니메이션의 경우 Chromium 기반 브라우저가
<img src=mp4>
를 지원할 것이라고 가정하고 AVC1(h264) > HVC1 > WebP > AVIF > GIF입니다. - AVIF에 대한 자세한 내용은 Netflix의 Aditya Mavlankar의 차세대 이미지 코딩을 위한 AVIF 강연과 Cloudflare의 Kornel Lesinski의 The AVIF Image Format 강연에서 확인할 수 있습니다.
- 모든 AVIF에 대한 훌륭한 참조: AVIF에 대한 Jake Archibald의 포괄적인 게시물이 도착했습니다.
그렇다면 미래의 AVIF는 ? Jon Sneyers는 동의하지 않습니다. AVIF는 Google과 Cloudinary에서 개발한 또 다른 무료 공개 형식인 JPEG XL보다 성능이 60% 더 낮습니다. 사실, JPEG XL은 전반적으로 훨씬 더 나은 성능을 보이는 것 같습니다. 그러나 JPEG XL은 아직 표준화의 마지막 단계에 불과하며 아직 어떤 브라우저에서도 작동하지 않습니다. (좋은 ol' Internet Explorer 9에서 나오는 Microsoft의 JPEG-XR과 혼동하지 마십시오).
- JPEG/PNG/SVG가 제대로 최적화되어 있습니까?
영웅 이미지가 엄청나게 빠르게 로드되는 것이 중요한 랜딩 페이지에서 작업할 때 JPEG가 프로그레시브이고 mozJPEG(스캔 수준을 조작하여 시작 렌더링 시간을 개선함) 또는 Google의 오픈 소스인 Guetzli로 압축되었는지 확인하십시오. 지각 성능에 중점을 두고 Zopfli 및 WebP의 학습을 활용하는 인코더입니다. 유일한 단점: 느린 처리 시간(메가픽셀당 1분의 CPU).PNG의 경우 Pingo를 사용할 수 있고 SVG의 경우 SVGO 또는 SVGOMG를 사용할 수 있습니다. 웹 사이트에서 모든 SVG 자산을 빠르게 미리 보고 복사하거나 다운로드해야 하는 경우 svg-grabber도 이를 수행할 수 있습니다.
모든 단일 이미지 최적화 기사에 명시되어 있지만 벡터 자산을 깨끗하고 긴밀하게 유지하는 것은 항상 언급할 가치가 있습니다. 사용하지 않는 자산을 정리하고 불필요한 메타데이터를 제거하고 아트웍(및 SVG 코드)의 경로 포인트 수를 줄이십시오. ( 고마워, 제레미! )
다음과 같은 유용한 온라인 도구도 있습니다.
- Squoosh를 사용하여 최적의 압축 수준(손실 또는 무손실)에서 이미지를 압축, 크기 조정 및 조작합니다.
- Guetzli.it을 사용하여 Guetzli로 JPEG 이미지를 압축하고 최적화하십시오. 이는 가장자리가 선명하고 색상이 단색인 이미지에 적합합니다(그러나 약간 느릴 수 있음).
- 반응형 이미지 중단점 생성기 또는 Cloudinary 또는 Imgix와 같은 서비스를 사용하여 이미지 최적화를 자동화합니다. 또한 많은 경우에
srcset
및sizes
만 사용하면 상당한 이점을 얻을 수 있습니다. - 반응형 마크업의 효율성을 확인하려면 뷰포트 크기 및 장치 픽셀 비율에 대한 효율성을 측정하는 명령줄 도구인 이미징 힙을 사용할 수 있습니다.
- GitHub 워크플로에 자동 이미지 압축을 추가할 수 있으므로 압축되지 않은 이미지가 프로덕션에 도달할 수 없습니다. 이 작업은 PNG 및 JPG와 함께 작동하는 mozjpeg 및 libvips를 사용합니다.
- 저장 공간을 내부적으로 최적화하기 위해 Dropbox의 새로운 Lepton 형식을 사용하여 JPEG를 평균 22%까지 손실 없이 압축할 수 있습니다.
- 자리 표시자 이미지를 일찍 표시하려면 BlurHash를 사용하세요. BlurHash는 이미지를 가져오고 이 이미지의 자리 표시자를 나타내는 짧은 문자열(20-30자만!)을 제공합니다. 문자열은 JSON 객체의 필드로 쉽게 추가할 수 있을 만큼 충분히 짧습니다.
이미지 최적화만으로는 효과가 없는 경우가 있습니다. 중요한 이미지의 렌더링을 시작하는 데 필요한 시간을 개선하려면 덜 중요한 이미지를 지연 로드 하고 중요한 이미지가 이미 렌더링된 후에 로드할 스크립트를 연기합니다. 가장 확실한 방법은 하이브리드 지연 로딩입니다. 네이티브 지연 로딩과 지연 로드를 사용할 때 사용자 상호 작용을 통해 트리거된 가시성 변경을 감지하는 라이브러리(나중에 살펴볼 IntersectionObserver 사용)입니다. 추가로:
- 중요한 이미지를 미리 로드하여 브라우저가 너무 늦게 발견하지 않도록 하십시오. 배경 이미지의 경우 그보다 더 공격적으로 이미지를 추가하려면
<img src>
를 사용하여 이미지를 일반 이미지로 추가한 다음 화면에서 숨길 수 있습니다. - 예를 들어 돋보기 구성 요소에서 소스를 교환하기 위해
sizes
를 조작하기 위해 미디어 쿼리에 따라 다른 이미지 표시 치수를 지정하여 Sizes 속성으로 이미지 교환을 고려하십시오. - 전경 및 배경 이미지에 대한 예기치 않은 다운로드를 방지하기 위해 이미지 다운로드 불일치를 검토합니다. 기본적으로 로드되지만 표시되지 않을 수 있는 이미지(예: 회전 목마, 아코디언 및 이미지 갤러리)에 주의하십시오.
- 이미지의
width
와height
를 항상 설정해야 합니다. CSS의aspect-ratio
속성과 이미지의 가로 세로 비율과 크기를 설정할 수 있는intrinsicsize
크기 속성에 주의하십시오. 따라서 브라우저는 페이지 로드 중 레이아웃 점프를 피하기 위해 미리 정의된 레이아웃 슬롯을 조기에 예약할 수 있습니다.
모험심을 느낀다면 기본적으로 CDN에 있는 실시간 필터인 Edge 작업자를 사용하여 HTTP/2 스트림을 자르고 재정렬하여 네트워크를 통해 이미지를 더 빠르게 보낼 수 있습니다. 에지 작업자는 사용자가 제어할 수 있는 청크를 사용하는 JavaScript 스트림을 사용하므로(기본적으로 스트리밍 응답을 수정할 수 있는 CDN 에지에서 실행되는 JavaScript임) 이미지 전달을 제어할 수 있습니다.
서비스 워커를 사용하면 유선상의 항목을 제어할 수 없으므로 너무 늦었지만 Edge 워커에서는 작동합니다. 따라서 특정 방문 페이지에 대해 점진적으로 저장된 정적 JPEG 위에 이를 사용할 수 있습니다.
충분하지? 음, 다중 배경 이미지 기술을 사용하여 이미지에 대한 인식 성능을 향상시킬 수도 있습니다. 대비를 사용하여 재생하고 불필요한 세부 사항을 흐리게 처리(또는 색상 제거)하면 파일 크기도 줄일 수 있습니다. 아, 화질을 잃지 않고 작은 사진을 확대 해야합니까? Letsenhance.io 사용을 고려하십시오.
지금까지 이러한 최적화는 기본 사항만 다룹니다. Addy Osmani는 이미지 압축 및 색상 관리의 세부 사항에 대해 매우 자세히 설명하는 Essential Image Optimization에 대한 매우 상세한 가이드를 게시했습니다. 예를 들어, 이미지의 불필요한 부분을 흐리게 처리 하여(가우스 흐림 효과 필터를 적용하여) 파일 크기를 줄일 수 있으며, 결국에는 색상을 제거하거나 사진을 흑백으로 변환하여 크기를 더욱 줄일 수도 있습니다. . 배경 이미지의 경우 Photoshop에서 0~10% 품질로 사진을 내보내는 것도 절대적으로 허용될 수 있습니다.
Smashing Magazine에서는 이미지 이름에 접미사
-opt
를 사용합니다(예:brotli-compression-opt.png
; 이미지에 해당 접미어가 포함될 때마다 팀의 모든 사람들은 이미지가 이미 최적화되었음을 압니다.아, 그리고 웹에서 JPEG-XR을 사용하지 마십시오. "CPU에서 JPEG-XR의 소프트웨어 측 디코딩 처리는 특히 SPA의 맥락에서 바이트 크기 절약의 잠재적인 긍정적 영향을 무효화하고 심지어 더 큽니다." 그러나 Cloudinary/Google의 JPEG XL과 혼합).
- 동영상이 제대로 최적화되어 있습니까?
지금까지 이미지를 다루었지만 좋은 GIF에 대한 대화는 피했습니다. GIF에 대한 우리의 사랑에도 불구하고 이제는 영원히 (적어도 우리 웹사이트와 앱에서) GIF를 버려야 할 때입니다. 렌더링 성능과 대역폭 모두에 영향을 미치는 무거운 애니메이션 GIF를 로드하는 대신 애니메이션 WebP(GIF가 대체)로 전환하거나 반복되는 HTML5 비디오로 완전히 교체하는 것이 좋습니다.이미지와 달리 브라우저는
<video>
콘텐츠를 미리 로드하지 않지만 HTML5 비디오는 GIF보다 훨씬 가볍고 작은 경향이 있습니다. 옵션이 아닌가요? 글쎄, 우리는 적어도 Lossy GIF, gifsicle 또는 giflossy를 사용하여 GIF에 손실 압축을 추가할 수 있습니다.Colin Bendell의 테스트에 따르면 Safari Technology Preview의
img
태그 내의 인라인 비디오는 파일 크기가 매우 작을 뿐만 아니라 GIF에 상응하는 것보다 최소 20배 더 빠르게 표시하고 7배 더 빠르게 디코딩합니다. 단, 다른 브라우저에서는 지원하지 않습니다.좋은 소식의 나라에서 비디오 형식은 수년에 걸쳐 크게 발전 했습니다. 오랫동안 우리는 WebM이 모든 것을 지배하는 형식이 되기를 바랐고 WebP(기본적으로 WebM 비디오 컨테이너 내부에 있는 하나의 정지 이미지)가 오래된 이미지 형식을 대체할 것입니다. 실제로 Safari는 현재 WebP를 지원하고 있지만, 요즘 WebP와 WebM이 지원을 받고 있음에도 불구하고 획기적인 발전은 일어나지 않았습니다.
그래도 우리는 대부분의 최신 브라우저에 WebM을 사용할 수 있습니다.
<!-- By Houssein Djirdeh. https://web.dev/replace-gifs-with-videos/ --> <!-- A common scenartio: MP4 with a WEBM fallback. --> <video autoplay loop muted playsinline> <source src="my-animation.webm" type="video/webm"> <source src="my-animation.mp4" type="video/mp4"> </video>
그러나 아마도 우리는 그것을 완전히 다시 방문할 수 있을 것입니다. 2018년, Alliance of Open Media는 AV1 이라는 새로운 유망한 비디오 형식을 출시했습니다. AV1은 H.265 코덱(H.264의 발전)과 유사한 압축을 갖지만 후자와 달리 AV1은 무료입니다. H.265 라이선스 가격 책정으로 인해 브라우저 공급업체는 성능이 비슷한 AV1을 대신 채택하게 되었습니다. AV1(H.265와 마찬가지로)은 WebM보다 두 배 더 압축 합니다.
실제로 Apple은 현재 HEIF 형식과 HEVC(H.265)를 사용하고 있으며 최신 iOS의 모든 사진과 동영상은 JPEG가 아닌 이러한 형식으로 저장됩니다. HEIF 및 HEVC(H.265)가 웹에 제대로 노출되지 않은 반면(아직?), AV1은 — 그리고 브라우저 지원을 얻고 있습니다. 따라서
<video>
태그에AV1
소스를 추가하는 것이 합리적입니다. 모든 브라우저 공급업체가 참여하는 것처럼 보이기 때문입니다.현재 가장 널리 사용 및 지원되는 인코딩은 MP4 파일에서 제공하는 H.264이므로 파일을 제공하기 전에 MP4가 다중 패스 인코딩으로 처리되고 frei0r iirblur 효과(해당되는 경우)로 흐려지고 moov 원자 메타데이터는 파일의 헤드로 이동되는 반면 서버는 바이트 제공을 허용합니다. Boris Schapira는 FFmpeg가 비디오를 최대로 최적화하기 위한 정확한 지침을 제공합니다. 물론 대안으로 WebM 형식을 제공하는 것도 도움이 될 것입니다.
비디오 렌더링을 더 빠르게 시작해야 하지만 비디오 파일이 여전히 너무 큽 니까? 예를 들어 방문 페이지에 큰 배경 비디오가 있을 때마다? 사용하는 일반적인 기술은 가장 첫 번째 프레임을 먼저 정지 이미지로 표시하거나 비디오의 일부로 해석될 수 있는 크게 최적화된 짧은 반복 세그먼트를 표시한 다음 비디오가 충분히 버퍼링될 때마다 재생을 시작하는 것입니다. 실제 영상. Doug Sillars는 이 경우에 도움이 될 수 있는 배경 비디오 성능에 대한 자세한 가이드를 작성했습니다. ( 고마워, Guy Podjarny! ).
위 시나리오의 경우 반응형 포스터 이미지 를 제공할 수 있습니다. 기본적으로
video
요소는 하나의 이미지만 포스터로 허용하며 이것이 반드시 최적일 필요는 없습니다. 반응형 비디오 포스터(Responsive Video Poster)를 사용할 수 있습니다. JavaScript 라이브러리를 사용하면 다른 화면에 다른 포스터 이미지를 사용할 수 있으며 전환 오버레이와 비디오 자리 표시자의 전체 스타일 제어를 추가할 수 있습니다.연구에 따르면 비디오 스트림 품질은 시청자 행동에 영향을 미칩니다. 실제로 시청자는 시작 지연이 약 2초를 초과하면 비디오를 포기하기 시작합니다. 그 지점을 넘어서면 지연이 1초 증가하면 포기율이 약 5.8% 증가합니다. 따라서 중간 비디오 시작 시간이 12.8초인 것은 놀라운 일이 아닙니다. 비디오의 40%는 최소 1번의 지연이 있고 20%는 최소 2초의 지연된 비디오 재생이 있습니다. 사실 3G에서는 네트워크가 콘텐츠를 제공할 수 있는 것보다 더 빠르게 비디오가 재생되기 때문에 비디오 스톨은 피할 수 없습니다.
그래서, 해결책은 무엇입니까? 일반적으로 작은 화면 장치는 데스크탑을 제공하는 720p 및 1080p를 처리할 수 없습니다. Doug Sillars에 따르면 비디오의 더 작은 버전을 만들고 Javascript를 사용하여 더 작은 화면의 소스를 감지하여 이러한 장치에서 빠르고 부드러운 재생 을 보장할 수 있습니다. 또는 스트리밍 비디오를 사용할 수 있습니다. HLS 비디오 스트림은 적절한 크기의 비디오를 장치에 전달하여 다양한 화면에 대해 다른 비디오를 생성할 필요성을 추상화합니다. 또한 네트워크 속도를 협상하고 사용 중인 네트워크 속도에 맞게 비디오 비트 전송률을 조정합니다.
대역폭 낭비를 피하기 위해 실제로 비디오를 잘 재생할 수 있는 장치에 대해서만 비디오 소스를 추가할 수 있었습니다. 또는
video
태그에서autoplay
속성을 완전히 제거하고 JavaScript를 사용하여 더 큰 화면에 대한autoplay
을 삽입할 수 있습니다. 또한video
에preload="none"
을 추가하여 실제로 파일이 필요할 때까지 비디오 파일을 다운로드 하지 않도록 브라우저에 지시해야 합니다.<!-- Based on Doug Sillars's post. https://dougsillars.com/2020/01/06/hiding-videos-on-the-mbile-web/ --> <video preload="none" playsinline muted loop width="1920" height="1080" poster="poster.jpg"> <source src="video.webm" type="video/webm"> <source src="video.mp4" type="video/mp4"> </video>
그런 다음 실제로 AV1을 지원하는 브라우저를 구체적으로 타겟팅할 수 있습니다.
<!-- Based on Doug Sillars's post. https://dougsillars.com/2020/01/06/hiding-videos-on-the-mbile-web/ --> <video preload="none" playsinline muted loop width="1920" height="1080" poster="poster.jpg"> <source src="video.av1.mp4" type="video/mp4; codecs=av01.0.05M.08"> <source src="video.hevc.mp4" type="video/mp4; codecs=hevc"> <source src="video.webm" type="video/webm"> <source src="video.mp4" type="video/mp4"> </video>
그런 다음 특정 임계값(예: 1000px)에
autoplay
을 다시 추가할 수 있습니다./* By Doug Sillars. https://dougsillars.com/2020/01/06/hiding-videos-on-the-mbile-web/ */ <script> window.onload = addAutoplay(); var videoLocation = document.getElementById("hero-video"); function addAutoplay() { if(window.innerWidth > 1000){ videoLocation.setAttribute("autoplay",""); }; } </script>
비디오 재생 성능은 그 자체로 하나의 이야기이며, 이에 대해 자세히 알아보려면 비디오 전송 메트릭에 대한 세부 정보가 포함된 현재 상태의 비디오 및 비디오 전송 모범 사례에 대한 다른 Doug Sillars 시리즈를 살펴보십시오. , 비디오 사전 로드, 압축 및 스트리밍. 마지막으로 스트리밍 여부를 사용하여 비디오 스트리밍이 얼마나 느리거나 빠른지 확인할 수 있습니다.
- 웹 글꼴 전달이 최적화되어 있습니까?
물어볼 가치가 있는 첫 번째 질문은 처음부터 UI 시스템 글꼴을 사용할 수 있는지 여부입니다. 다양한 플랫폼에서 올바르게 표시되는지 다시 확인하기만 하면 됩니다. 그렇지 않은 경우, 우리가 제공하는 웹 글꼴에 사용되지 않는 글리프와 추가 기능 및 가중치가 포함될 가능성이 높습니다. 웹 글꼴을 하위 집합 으로 지정하도록 유형 주조소에 요청할 수 있습니다. 또는 오픈 소스 글꼴을 사용하는 경우 Glyphhanger 또는 Fontsquirrel을 사용하여 자체적으로 하위 집합을 만들 수 있습니다. 가장 최적의 웹 글꼴 하위 집합을 생성한 다음 페이지에 삽입하기 위해 페이지를 정적으로 분석하는 명령줄 도구인 Peter Muller의 하위 글꼴을 사용하여 전체 워크플로를 자동화할 수도 있습니다.WOFF2 지원은 훌륭하며 WOFF를 지원하지 않는 브라우저에 대한 폴백으로 사용할 수 있습니다. 또는 레거시 브라우저에 시스템 글꼴이 제공될 수 있습니다. 웹 글꼴 로딩을 위한 많은 옵션이 있으며 Zach Leatherman의 "글꼴 로딩 전략에 대한 종합 가이드"에서 전략 중 하나를 선택할 수 있습니다(코드 조각은 웹 글꼴 로딩 레시피로도 사용 가능).
아마도 오늘날 고려해야 할 더 나은 옵션은
preload
이 있는 Critical FOFT와 "The Compromise" 방법일 것입니다. 둘 다 단계적으로 웹 글꼴을 제공하기 위해 2단계 렌더링 을 사용합니다. 먼저 웹 글꼴로 페이지를 빠르고 정확하게 렌더링하는 데 필요한 작은 상위 하위 집합이 필요한 다음 나머지 패밀리를 비동기식으로 로드합니다. 차이점은 "The Compromise" 기술은 글꼴 로드 이벤트가 지원되지 않는 경우에만 폴리필을 비동기적으로 로드하므로 기본적으로 폴리필을 로드할 필요가 없다는 것입니다. 빠른 승리가 필요하십니까? Zach Leatherman은 글꼴을 정리하기 위한 23분 분량의 빠른 튜토리얼과 사례 연구를 제공합니다.일반적으로
preload
리소스 힌트를 사용하여 글꼴을 사전 로드하는 것이 좋지만 마크업에서 중요한 CSS 및 JavaScript에 대한 링크 뒤에 힌트를 포함합니다.preload
에는 우선순위의 퍼즐이 있으므로 외부 차단 스크립트 직전에 DOM에rel="preload"
요소를 삽입하는 것을 고려하십시오. Andy Davies에 따르면 "스크립트를 사용하여 주입된 리소스는 스크립트가 실행될 때까지 브라우저에서 숨겨지며 우리는 이 동작을 사용하여 브라우저가preload
힌트를 발견할 때를 지연할 수 있습니다." 그렇지 않으면 첫 번째 렌더링 시 글꼴 로드 비용이 발생합니다.가장 중요한 파일을 선택하고 선택하는 것이 좋습니다. 예를 들어 렌더링에 중요하거나 눈에 띄고 방해가 되는 텍스트 리플로우를 방지하는 데 도움이 되는 파일을 선택하는 것이 좋습니다. 일반적으로 Zach 는 각 패밀리의 하나 또는 두 개의 글꼴을 미리 로드 할 것을 권장합니다. 덜 중요하다면 일부 글꼴 로드를 지연시키는 것도 의미가 있습니다.
@font-face
규칙에서font-family
를 정의할 때local()
값(이름으로 로컬 글꼴 참조)을 사용하는 것이 매우 일반적입니다./* Warning! Not a good idea! */ @font-face { font-family: Open Sans; src: local('Open Sans Regular'), local('OpenSans-Regular'), url('opensans.woff2') format ('woff2'), url('opensans.woff') format('woff'); }
아이디어는 합리적입니다. Open Sans와 같은 일부 인기 있는 오픈 소스 글꼴에는 일부 드라이버 또는 앱이 사전 설치되어 있으므로 해당 글꼴을 로컬에서 사용할 수 있는 경우 브라우저는 웹 글꼴을 다운로드할 필요가 없으며 로컬을 표시할 수 있습니다. 글꼴을 즉시. Bram Stein이 언급했듯이 "로컬 글꼴이 웹 글꼴의 이름과 일치하지만 동일한 글꼴이 아닐 가능성이 높습니다. 많은 웹 글꼴이 "데스크톱" 버전과 다릅니다. 텍스트가 다르게 렌더링될 수 있고 일부 문자가 떨어질 수 있습니다. 다른 글꼴로 돌아가면 OpenType 기능이 완전히 누락되거나 줄 높이가 다를 수 있습니다."
또한 서체가 시간이 지남에 따라 발전함에 따라 로컬에 설치된 버전은 웹 글꼴과 매우 다를 수 있으며 문자가 매우 다르게 보일 수 있습니다. 따라서 Bram에 따르면
@font-face
규칙에서는 로컬에 설치된 글꼴과 웹 글꼴을 혼합하지 않는 것이 좋습니다. Google Fonts는 Roboto에 대한 Android 요청을 제외한 모든 사용자에 대해 CSS 결과에서local()
을 비활성화하여 그 뒤를 따랐습니다.콘텐츠가 표시되기를 기다리는 것을 좋아하는 사람은 없습니다.
font-display
CSS 설명자를 사용하여 글꼴 로드 동작을 제어하고 콘텐츠를 즉시 (font-display: optional
) 또는 거의 즉시 (글꼴이 성공적으로 다운로드되는 한 3초의 시간 제한 포함) 읽을 수 있습니다.font-display: swap
). (글쎄요, 그것보다 조금 더 복잡합니다.)그러나 텍스트 리플로우의 영향을 최소화하려면 글꼴 로드 API (모든 최신 브라우저에서 지원됨)를 사용할 수 있습니다. 특히 이는 모든 글꼴에 대해
FontFace
개체를 만든 다음 모두 가져오려고 시도한 다음에만 페이지에 적용한다는 것을 의미합니다. 이런 식으로 모든 글꼴을 비동기식으로 로드하여 모든 다시 그리기를 그룹화 한 다음 폴백 글꼴에서 웹 글꼴로 정확히 한 번 전환합니다. 32:15부터 Zach의 설명과 코드 스니펫을 살펴보세요./* Load two web fonts using JavaScript */ /* Zach Leatherman: https://noti.st/zachleat/KNaZEg/the-five-whys-of-web-font-loading-performance#sWkN4u4 */ // Remove existing @font-face blocks // Create two let font = new FontFace("Noto Serif", /* ... */); let fontBold = new FontFace("Noto Serif, /* ... */); // Load two fonts let fonts = await Promise.all([ font.load(), fontBold.load() ]) // Group repaints and render both fonts at the same time! fonts.forEach(font => documents.fonts.add(font));
/* Load two web fonts using JavaScript */ /* Zach Leatherman: https://noti.st/zachleat/KNaZEg/the-five-whys-of-web-font-loading-performance#sWkN4u4 */ // Remove existing @font-face blocks // Create two let font = new FontFace("Noto Serif", /* ... */); let fontBold = new FontFace("Noto Serif, /* ... */); // Load two fonts let fonts = await Promise.all([ font.load(), fontBold.load() ]) // Group repaints and render both fonts at the same time! fonts.forEach(font => documents.fonts.add(font));
Font Loading API를 사용하여 글꼴을 매우 일찍 가져오기 위해 Adrian Bece는 줄 바꿈하지 않는 공백
nbsp;
body
상단에aria-visibility: hidden
및.hidden
클래스를 사용하여 시각적으로 숨깁니다.<body class="no-js"> <!-- ... Website content ... --> <div aria-visibility="hidden" class="hidden"> <!-- There is a non-breaking space here --> </div> <script> document.getElementsByTagName("body")[0].classList.remove("no-js"); </script> </body>
<body class="no-js"> <!-- ... Website content ... --> <div aria-visibility="hidden" class="hidden"> <!-- There is a non-breaking space here --> </div> <script> document.getElementsByTagName("body")[0].classList.remove("no-js"); </script> </body>
이것은 글꼴이 성공적으로 로드되면 Font Loading API에 의해 트리거된 변경과 함께 다양한 로드 상태에 대해 선언된 다른 글꼴 패밀리가 있는 CSS와 함께 진행됩니다.
body:not(.wf-merriweather--loaded):not(.no-js) { font-family: [fallback-system-font]; /* Fallback font styles */ } .wf-merriweather--loaded, .no-js { font-family: "[web-font-name]"; /* Webfont styles */ } /* Accessible hiding */ .hidden { position: absolute; overflow: hidden; clip: rect(0 0 0 0); height: 1px; width: 1px; margin: -1px; padding: 0; border: 0; }
body:not(.wf-merriweather--loaded):not(.no-js) { font-family: [fallback-system-font]; /* Fallback font styles */ } .wf-merriweather--loaded, .no-js { font-family: "[web-font-name]"; /* Webfont styles */ } /* Accessible hiding */ .hidden { position: absolute; overflow: hidden; clip: rect(0 0 0 0); height: 1px; width: 1px; margin: -1px; padding: 0; border: 0; }
모든 최적화에도 불구하고 Lighthouse가 여전히 렌더링 차단 리소스(글꼴)를 제거할 것을 제안하는 이유가 궁금하다면 같은 기사에서 Adrian Bece는 성능이 뛰어난 비동기 글꼴인 Gatsby Omni 글꼴 로더와 함께 Lighthouse를 행복하게 만드는 몇 가지 기술을 제공합니다. Gatsby용 플러그인 로드 및 Flash Of Unstyled Text(FOUT) 처리.
이제 우리 중 많은 사람들이 CDN 또는 타사 호스트를 사용하여 웹 글꼴을 로드할 수 있습니다. 일반적으로 가능하면 모든 정적 자산을 자체 호스팅하는 것이 항상 더 좋으므로 Google 글꼴을 자체 호스팅하는 번거로움 없는 방법인 google-webfonts-helper를 사용하는 것이 좋습니다. 그리고 가능하지 않다면 페이지 원본을 통해 Google 글꼴 파일을 프록시할 수 있습니다.
Google은 기본적으로 상당한 작업을 수행하고 있으므로 지연을 피하기 위해 서버를 약간 조정해야 할 수도 있습니다( 감사합니다, Barry! ).
이것은 특히 Chrome v86(2020년 10월 출시) 이후로 파티션된 브라우저 캐시로 인해 글꼴과 같은 사이트 간 리소스를 동일한 CDN에서 더 이상 공유할 수 없기 때문에 매우 중요합니다. 이 동작은 수년 동안 Safari의 기본값이었습니다.
그러나 전혀 가능하지 않은 경우 Harry Roberts의 스니펫을 사용하여 가능한 가장 빠른 Google 글꼴에 액세스할 수 있는 방법이 있습니다.
<!-- By Harry Roberts. https://csswizardry.com/2020/05/the-fastest-google-fonts/ - 1. Preemptively warm up the fonts' origin. - 2. Initiate a high-priority, asynchronous fetch for the CSS file. Works in - most modern browsers. - 3. Initiate a low-priority, asynchronous fetch that gets applied to the page - only after it's arrived. Works in all browsers with JavaScript enabled. - 4. In the unlikely event that a visitor has intentionally disabled - JavaScript, fall back to the original method. The good news is that, - although this is a render-blocking request, it can still make use of the - preconnect which makes it marginally faster than the default. --> <!-- [1] --> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /> <!-- [2] --> <link rel="preload" as="style" href="$CSS&display=swap" /> <!-- [3] --> <link rel="stylesheet" href="$CSS&display=swap" media="print" onload="this.media='all'" /> <!-- [4] --> <noscript> <link rel="stylesheet" href="$CSS&display=swap" /> </noscript>
해리의 전략은 먼저 글꼴의 기원을 선제적으로 워밍업하는 것입니다. 그런 다음 CSS 파일에 대해 우선 순위가 높은 비동기 가져오기를 시작합니다. 그 후에 페이지가 도착한 후에만 페이지에 적용되는 낮은 우선 순위의 비동기 가져오기를 시작합니다(인쇄 스타일시트 트릭 사용). 마지막으로 JavaScript가 지원되지 않으면 원래 방법으로 대체합니다.
아, Google Fonts에 대해 이야기하면
&text
를 사용하여 필요한 문자만 선언하여 Google Fonts 요청 크기의 최대 90%를 줄일 수 있습니다. 또한 최근에 Google Fonts에도 글꼴 표시 지원이 추가되었으므로 즉시 사용할 수 있습니다.그래도 조심스러운 한마디.
font-display: optional
을 사용하는 경우 웹 글꼴 요청을 일찍 트리거하므로preload
도 사용하는 것이 차선책일 수 있습니다(가져와야 하는 다른 중요한 경로 리소스가 있는 경우 네트워크 정체 가 발생함). 더 빠른 교차 출처 글꼴 요청을 위해preconnect
을 사용하지만 다른 출처에서 글꼴을 사전 로드하면 네트워크 경합이 발생할 수 있으므로 사전preload
에 주의하십시오. 이러한 모든 기술은 Zach의 웹 글꼴 로딩 레시피에서 다룹니다.반면에 사용자가 접근성 기본 설정에서 동작 줄이기를 활성화했거나 데이터 절약 모드 를 선택한 경우 웹 글꼴(또는 최소한 두 번째 단계 렌더링)을 선택 해제하는 것이 좋습니다(
Save-Data
헤더 참조). , 또는 사용자의 연결 속도가 느린 경우(네트워크 정보 API를 통해).사용자가 데이터 저장 모드를 선택한 경우(다른 사용 사례도 있음) 글꼴 선언을 정의 하지 않기 위해
prefers-reduced-data
CSS 미디어 쿼리를 사용할 수도 있습니다. 미디어 쿼리는 기본적으로 클라이언트 힌트 HTTP 확장의Save-Data
요청 헤더가 CSS와 함께 사용할 수 있도록 설정/해제되어 있는지 노출합니다. 현재 플래그 뒤의 Chrome 및 Edge에서만 지원됩니다.측정항목? 웹 글꼴 로드 성능을 측정하려면 모든 텍스트 표시 메트릭(모든 글꼴이 로드되고 모든 콘텐츠가 웹 글꼴로 표시되는 순간), 실제 기울임꼴까지의 시간 및 첫 번째 렌더링 후 웹 글꼴 리플로우 수 를 고려하십시오. 분명히 두 메트릭이 모두 낮을수록 성능이 더 좋습니다.
가변 글꼴 은 어떻습니까? 가변 글꼴에는 상당한 성능 고려 사항이 필요할 수 있습니다. 그것들은 우리에게 인쇄상의 선택을 위한 훨씬 더 넓은 디자인 공간을 제공하지만, 많은 개별 파일 요청에 반대되는 단일 직렬 요청의 비용이 듭니다.
가변 글꼴은 글꼴 파일의 전체 결합 파일 크기를 크게 줄이지 만 단일 요청이 느려 페이지의 모든 콘텐츠 렌더링을 차단할 수 있습니다. 따라서 글꼴을 문자 집합으로 하위 설정하고 분할하는 것은 여전히 중요합니다. 그러나 좋은 측면에서는 가변 글꼴을 사용하면 기본적으로 정확히 하나의 리플로우가 발생하므로 다시 그리기를 그룹화하는 데 JavaScript가 필요하지 않습니다.
그렇다면 방탄 웹폰트 로딩 전략 은 무엇일까요? 글꼴을 하위 집합으로 만들고 2단계 렌더링을 위해 준비하고
font-display
설명자로 선언하고 글꼴 로드 API를 사용하여 다시 그리기를 그룹화하고 글꼴을 영구 서비스 작업자의 캐시에 저장합니다. 첫 번째 방문 시 차단 외부 스크립트 직전에 스크립트 사전 로드를 삽입합니다. 필요한 경우 Bram Stein의 Font Face Observer로 대체할 수 있습니다. 글꼴 로드 성능을 측정하는 데 관심이 있는 경우 Andreas Marschke는 Font API 및 UserTiming API를 사용한 성능 추적을 살펴봅니다.마지막으로
unicode-range
를 포함하여 큰 글꼴을 더 작은 언어별 글꼴로 나누고 Monica Dinculescu의 글꼴 스타일 일치자를 사용하여 폴백과 글꼴 간의 크기 불일치로 인한 레이아웃 변화를 최소화합니다. 웹 글꼴.또는 대체 글꼴에 대한 웹 글꼴을 에뮬레이트하기 위해 @font-face 설명자를 사용하여 글꼴 메트릭을 재정의할 수 있습니다(데모, Chrome 87에서 활성화됨). (그러나 복잡한 글꼴 스택으로 인해 조정이 복잡합니다.)
미래가 밝습니까? 점진적 글꼴 강화를 통해 궁극적으로 "특정 페이지에서 글꼴의 필수 부분만 다운로드하고 해당 글꼴에 대한 후속 요청에 대해 후속 페이지에서 요구되는 추가 글리프 세트로 원본 다운로드를 동적으로 '패치'할 수 있습니다. 보기"로 Jason Pamental이 설명합니다. 증분 전송 데모는 이미 사용 가능하며 작업이 진행 중입니다.
목차
- 준비하기: 계획 및 측정항목
- 현실적인 목표 설정
- 환경 정의
- 자산 최적화
- 빌드 최적화
- 배달 최적화
- 네트워킹, HTTP/2, HTTP/3
- 테스트 및 모니터링
- 빠른 승리
- 한 페이지에 모든 것
- 체크리스트 다운로드(PDF, Apple Pages, MS Word)
- 다음 가이드를 놓치지 않으려면 이메일 뉴스레터를 구독하세요.