Angular NgOptimizedImage 지시어의 새로운 기능

Alex Castle
Alex Castle

약 1년 전 Chrome Aurora팀Angular NgOptimizedImage 지시어를 출시했습니다. 지시어는 Core Web Vitals 측정항목으로 측정된 성능 개선에 주로 중점을 둡니다. 표준 <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" 태그를 사용하여 이미지 도메인에 대한 연결을 빠르게 시작하는 것입니다.

처음부터 NgOptimizedImage는 LCP 이미지 도메인에 사전 연결하지 못할 경우 경고를 표시했지만 경고는 이상적인 솔루션은 아닙니다. 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 애플리케이션에 이미지를 포함하는 데 여전히 매력적인 옵션으로 유지되도록 개발자 환경을 개선하는 기능도 추가하려고 합니다.

Google에서 중요하게 생각하는 한 가지 기능은 이미지 자리표시자입니다. 일반적으로 웹 애플리케이션에서 이미지 로드를 개선하는 데 사용되지만 잘못 구현하면 성능이 저하될 수 있습니다. NgOptimizedImage에 성능 우선 이미지 자리표시자 시스템을 빌드하고자 합니다. 블로그에서 향후 발표 내용을 지속적으로 확인해 주시기 바랍니다.