Angular NgOptimizedImage 지시어의 새로운 기능

알렉스 캐슬
알렉스 캐슬

약 1년 전 Chrome Aurora팀에서 Angular NgOptimizedImage 지시어를 출시했습니다. 이 지침은 코어 웹 바이탈 측정항목으로 측정된 성능 개선에 주로 중점을 둡니다. 이 API는 일반적인 이미지 최적화 및 권장사항을 표준 <img> 요소보다 훨씬 더 복잡하지 않은 사용자 대상 API에 번들로 제공합니다.

2023년에는 새로운 기능으로 지침을 개선했습니다. 이 게시물에서는 이러한 새로운 기능 중 가장 중요한 내용을 설명하며, 각 기능의 우선 순위를 정하기로 결정한 이유와 Angular 애플리케이션의 성능을 개선하는 데 어떻게 도움이 될 수 있는지에 중점을 둡니다.

새로운 기능

NgOptimizedImage는 다음과 같은 새로운 기능을 포함하여 시간이 지남에 따라 크게 개선되었습니다.

채우기 모드

widthheight 속성을 제공하여 이미지 크기를 조정하는 것은 레이아웃 변경을 줄이는 데 매우 중요한 최적화입니다. 브라우저에서 공간을 절약하기 위해 이미지의 가로세로 비율을 알아야 하기 때문입니다. 그러나 이미지 크기 조정은 애플리케이션 개발자의 추가 작업이며 일부 이미지 사용 사례에서는 적합하지 않습니다.

이러한 긴장감을 해결하는 데 도움을 주는 것이 개발자가 이미지 구성요소 미리보기 후 이미지 구성요소에 추가된 첫 번째 주요 기능인 채우기 모드입니다. 이렇게 하면 개발자가 명시적으로 크기를 조정하지 않고 레이아웃 변경 없이 이미지를 포함할 수 있습니다.

채우기 모드를 사용하면 이미지 크기 요구사항이 사용 중지되며 이미지가 포함된 요소를 채우도록 자동으로 스타일이 지정됩니다. 이렇게 하면 이미지의 가로 세로 비율이 페이지에서 차지하는 공간으로부터 분리되고 이미지가 페이지 레이아웃에 맞게 조정되는 방식을 더 효과적으로 제어할 수 있습니다.

채우기 모드는 background-image css 속성 대신 NgOptimizedImage를 더 나은 성능의 대안으로 사용합니다. <div> 또는 background-image 스타일이 지정되었을 다른 요소 내에 이미지를 배치한 다음 앞의 코드 예와 같이 채우기 모드를 사용 설정합니다. <div>에서 object-fitobject-position CSS 속성을 사용하여 이미지가 배경에 배치되는 방식을 제어합니다.

// Height and width are required
<img ngSrc="example.com" height="300" width="400">

// Unless you use fill mode!
<div style="width: 100vw; height: 50em; position: relative">
  <img ngSrc="example.com" fill>
</div>

Srcset 생성

가장 효과적인 이미지 최적화 기법 중 하나는 srcset 속성을 사용하여 애플리케이션에 액세스하는 모든 기기에 적절한 크기의 이미지가 다운로드되도록 하는 것입니다. 앱 전체에서 srcset를 사용하면 대역폭 낭비를 방지하고 LCP Core Web Vitals를 크게 개선할 수 있습니다.

srcset 속성의 단점은 구현하기가 번거로울 수 있다는 것입니다. srcset 값을 수동으로 작성하려면 앱의 각 이미지 요소에 여러 개의 마크업 행을 추가하고 각 srcset에 여러 개의 커스텀 URL을 추가합니다. 또한 일반적인 기기의 화면 밀도와 표시 영역 크기를 모두 나타낼 수 있으므로 복잡한 중단점 집합을 결정해야 합니다.

이러한 이유로 NgOptimizedImage 지시어에 자동 srcset 생성을 추가하는 것이 출시 후 중요한 마일스톤이 되었습니다. 이 추가 기능으로 이미지 크기 조절을 지원하는 CDN을 사용하는 모든 애플리케이션은 NgOptimizedImage 지시어로 생성된 모든 이미지에 자동으로 맞춤설정 가능한 완벽한 srcset를 추가할 수 있습니다.

sizes 속성을 설정하기 위한 간소화된 API가 포함되어 있습니다. 이 API는 각 이미지가 올바른 유형의 srcset를 가져오도록 하는 데 사용됩니다. sizes 속성을 포함하지 않으면 이미지가 고정 크기임을 알 수 있으며 다음과 같이 밀도 종속 srcset를 가져옵니다.

<img src="www.example.com/image.png" srcset="www.example.com/image.png?w=400 1x, www.example.com/image.png?w=800 2x" >

이 유형의 srcset를 사용하면 사용자의 기기 픽셀 밀도를 고려한 크기로 이미지가 게재됩니다.

반면 sizes 속성을 포함하면 NgOptimizedImage는 다음과 같은 기본 중단점 목록을 사용하여 많은 일반 기기 및 이미지 크기의 중단점이 포함된 반응형 srcset를 생성합니다.

[16, 32, 48, 64, 96, 128, 256, 384, 640, 750, 828, 1080, 1200, 1920, 2048, 3840]

사전 연결 생성

LCP를 개선하려면 사용자가 LCP 이미지를 다운로드하는 데 소요되는 시간을 줄이는 것이 중요합니다. 이전 섹션에서는 srcset가 더 작은 이미지 파일을 전송하여 어떻게 지원할 수 있는지 확인했지만 마찬가지로 중요한 최적화는 최대한 빨리 전송을 시작하는 것입니다. 이렇게 하는 한 가지 방법은 link rel="preconnect" 태그를 사용하여 이미지 도메인에 대한 연결을 즉시 시작하는 것입니다.

처음부터 LCP 이미지의 도메인에 사전 연결하지 못하면 NgOptimizedImage가 경고를 표시했지만, 이상적인 해결 방법은 아닙니다. Google은 문제만 해결하고자 합니다. 이것이 바로 지금 NgOptimizedImage가 하는 일이며, 자동 사전 연결 생성을 사용합니다.

이 기능을 지원하기 위해 Google에서는 정적 코드 분석을 사용하여 NgOptimizedImage 로더에서 이미지 도메인을 감지하려고 시도하고, 이러한 도메인에 대한 사전 연결 링크 태그를 자동으로 생성합니다. 수동 사전 연결 링크가 필요한 경우가 여전히 있을 수 있지만, 대부분의 사용자의 경우 자동 사전 연결을 사용하면 이미지 성능을 향상하는 데 필요한 단계가 한 단계 줄어듭니다.

맞춤 로더 지원 향상

NgOptimizedImage의 핵심 요소는 로더 아키텍처로, 지시어가 애플리케이션의 이미지 CDN에 맞춤화된 URL을 자동으로 생성할 수 있게 해줍니다. 널리 사용되는 CDN을 위해 일련의 내장 로더가 포함되어 있습니다. 또한 NgOptimizedImage를 거의 모든 이미지 호스팅 솔루션과 통합할 수 있는 커스텀 로더를 사용할 수 있도록 지원합니다.

출시 시점에 이러한 맞춤 로더는 범위가 제한되었으며 이미지 요소에서 width 속성만 읽을 수 있었습니다. 사용자 의견에 따라 맞춤설정 가능한 loaderParams 데이터 구조에 관한 지원을 추가하여 이미지 요소에서 맞춤 로더로 임의의 데이터를 전달할 수 있습니다. 커스텀 로더는 확장을 통해 애플리케이션의 이미지 인프라에 필요한 만큼 간단하게 또는 복잡하게 만들 수 있습니다.

다음 예는 간단한 커스텀 로더가 loaderParams API를 사용하여 두 개의 대체 이미지 도메인 중에서 선택하는 방법을 보여줍니다.

const myCustomLoader = (config: ImageLoaderConfig) => {
  if (config.loaderParams?.alternateDomain) {
    return `https://alternate.domain.com/images/${config.src}`
  }
  return `https://primary.domain.com/images/${config.src}`;
};

더 복잡한 커스텀 로더의 예는 Angular 문서에서 확인할 수 있습니다.

이미지 실적에 대한 확장된 가이드

지금까지 Angular에 추가한 모든 이미지 성능 알림은 NgOptimizedImage 지시어의 일부였습니다. 앱에서 지시어를 사용하지 않는 경우 이미지 성능 문제에 관한 안내가 제공되지 않습니다.

Angular 17에서는 이미지 성능 지침의 범위를 확장하여 모든 Angular 앱을 포함합니다. 이제 LCP 이미지를 지연 로드하거나 페이지에 비해 너무 큰 파일을 다운로드하는 등 성능 저하를 야기하는 실수라고 판단되는 이미지 패턴이 감지되면 NgOptimizedImage를 사용하지 않더라도 Google에서 알려드립니다.

이미지 성능은 모든 앱에 중요합니다. 따라서 Angular 앱에서 흔히 발생하는 실수를 방지하는 데 도움이 되는 가드레일을 계속 빌드하게 되어 기쁩니다.

향후 계획

Google은 이미 NgOptimizedImage의 다음 기능 세트를 개발하고 있습니다. 이미지 성능은 여전히 우리의 핵심 관심사이지만, 저희는 개발자 환경을 개선하는 기능도 추가하려고 합니다. 그래야 NgOptimizedImage가 Angular 애플리케이션에 이미지를 포함할 때 매력적인 옵션으로 유지될 수 있기 때문입니다.

저희에게 중요한 기능 중 하나는 이미지 자리표시자입니다. 이는 일반적으로 웹 애플리케이션에서 이미지 로드를 개선하는 데 사용되지만, 잘못 구현하면 성능이 저하될 수 있습니다. 우리는 NgOptimizedImage에 성능 우선 이미지 자리표시자 시스템을 빌드하고자 합니다. 블로그에서 추가 공지사항을 확인하세요.