블로그 | NGINX

NGINX 및 NGINX Plus는 골치 아픈 일 없이 반응성 있는 이미지를 제공합니다.

NGINX-F5-수평-검정-유형-RGB의 일부
리엄 크릴리 썸네일
리암 크릴리
2016년 9월 29일 게시
더욱 반응형 웹 디자인을 위한 반응형 이미지를 생성하기 위해 NGINX Plus 이미지 필터 모듈을 사용하는 방법에 대한 기사를 위한 잡지 선반 이미지입니다.
사진: 필 로더

Image‑Filter 모듈과 srcset 태그를 사용하여 즉석에서 이미지 크기 조정

반응형 웹 디자인은 현대 웹사이트와 웹 애플리케이션의 표준이 되었으며, 다양한 기기에서 일관된 경험을 제공하고 각 기기의 디스플레이를 최적화합니다. 그러나 최신 기기는 화면 크기뿐만 아니라 픽셀 밀도도 다양합니다. HTML5 img 태그는 서버에서 여러 변형을 제공하는 경우 브라우저가 가장 적합한 자산을 선택할 수 있도록 하는 여러 기능을 제공합니다. 웹사이트에 동일한 이미지의 크기가 서로 다른 여러 개가 배포되어 있는 경우, 웹 브라우저는 현재 환경에 가장 적합한 크기를 선택할 수 있습니다.

따라서 반응형 이미지를 사용하면 웹 브라우저가 디자이너의 의도에 가장 잘 맞는 렌더링을 생성할 수 있습니다. 이를 통해 사용자 경험은 향상되지만, 기본 이미지뿐만 아니라 다양한 이미지 자산 변형을 만들고 배포해야 하는 개발 및 운영 팀의 부담도 커집니다.

이 블로그 게시물에서는 NGINX 및 NGINX Plus용 Image‑Filter 모듈을 사용하여 다양한 이미지 자산 변형을 만들고 관리하는 번거로움 없이 반응형 이미지를 제공하는 방법을 보여줍니다. 대신, NGINX 또는 NGINX Plus가 즉시 크기를 조정하는 각 이미지의 단일 "소스" 버전을 배포할 수 있습니다. 이 게시물의 정보는 NGINX 오픈 소스와 NGINX Plus 모두에 적용됩니다( 이미지 필터 모듈 설치 에 대한 별도 지침 제외). 간결하게 설명하기 위해 이 게시물에서는 NGINX Plus를 지칭합니다.

srcset 속성

반응형 이미지를 제공하는 주요 도구는 HTML5 img 태그의 srcset 속성입니다. 이를 사용하면 다양한 픽셀 밀도와 뷰포트 크기에 맞게 다양한 이미지 자산 변형을 지정할 수 있습니다. 뷰포트는 데스크톱의 창이든 모바일 기기의 전체 화면 앱이든 웹 브라우저에서 사용할 수 있는 디스플레이 공간을 일컫는 일반적인 용어입니다.

다음 예에서 src 속성은 srcset 속성을 지원하지 않는 브라우저에 대한 기본 이미지를 정의하고 srcset 속성은 두 가지 변형을 명명합니다. 하나는 표준 픽셀 밀도( 1x )의 디스플레이용이고, 다른 하나는 Apple Retina™ 디스플레이 및 일부 4K 모니터( 2x )와 같이 두 배 픽셀 밀도의 디스플레이용입니다.

< img src= "/images/mylogo-default.png" srcset= "/images/mylogo-density1.png 1x, /images/mylogo-density2.png 2x" >

다음의 보다 정교한 예제에서는 뷰포트 너비에 따라 표시할 여러 이미지 자산 변형을 정의합니다. sizes 속성은 뷰포트가 10em 보다 넓으면 브라우저가 뷰포트의 절반에 이미지를 렌더링하고, 그렇지 않으면 전체 뷰포트를 사용한다는 것을 지정합니다. 브라우저는 이미지에 사용할 수 있는 공간을 파악하고 사용 가능한 공간에 가장 잘 맞는 이미지 자산 변형을 선택합니다. 일반적으로 다음 너비( w 접미사)로 "반올림"하고 내부적으로 이미지 크기를 조정하여 공간을 정확히 채웁니다.

< img src= "/images/racecar-default.jpg" 크기= "(최소 너비: 10em) 50vw, 100vw" srcset= "/images/racecar-100px.jpg 100w, /images/racecar-225px.jpg 225w, /images/racecar-450px.jpg 450w, /images/racecar-675px.jpg 675w" >

다양한 이미지 자산 변형을 지정하여 반응형 이미지를 제공하는 이러한 접근 방식은 코딩하기 쉽고 매우 효과적입니다. 그러나 이는 이미지 변형 자체를 만들고 관리하는 측면에서 과제를 제시합니다. 사전 제작 이미지 크기를 조정하는 작업이 많이 필요하고, 서버에 훨씬 더 많은 파일을 배포해야 합니다. 각 변형의 최적 개수와 크기를 미세 조정하는 데는 시간이 많이 걸릴 수 있으며, 이로 인해 각 이미지 자산 변형에 액세스할 수 있는지 테스트하는 데 어려움이 발생합니다.

srcset 속성과 반응형 이미지를 위한 다른 기술에 대한 자세한 내용은 이 훌륭한 블로그 게시물을 참조하세요.

이미지 필터 모듈 설치

NGINX Plus와 NGINX에서 해당 Image‑Filter 모듈을 얻는 절차는 다릅니다.

NGINX Plus용 이미지 필터 모듈 설치

Image‑Filter 모듈은 NGINX Plus 구독자에게 무료 동적 모듈 로 제공됩니다.

  1. NGINX Plus 저장소에서 모듈을 설치하여 모듈 자체를 얻으세요.

    Ubuntu 및 Debian 시스템의 경우:

    $ sudo apt-get nginx-plus-module-image-filter를 설치합니다.

    RedHat, CentOS 및 Oracle Linux 시스템의 경우:

    $ sudo yum install nginx-plus-module-image-filter
  2. nginx.conf 구성 파일의 최상위("main") 컨텍스트에 load_module 지시문을 포함하여 모듈을 활성화합니다(즉, http 또는 stream 컨텍스트가 아님).

    로드_모듈 모듈/ngx_http_image_filter_module.so;
  3. NGINX Plus를 다시 로드하여 실행 중인 인스턴스에 Image‑Filter 모듈을 로드합니다.

    $ sudo nginx -s 다시 로드 >

NGINX 오픈 소스용 이미지 필터 모듈 설치

Image‑Filter 모듈을 설치하는 가장 쉬운 방법은 공식 NGINX 저장소에서 가져오는 것입니다. 다음 지침 에 따라 공식 NGINX 저장소에 액세스하도록 시스템을 구성한 다음 운영 체제 패키지 관리자를 사용하여 설치하세요.

Ubuntu 및 Debian 시스템의 경우:

$ sudo apt-get nginx-모듈-이미지-필터를 설치합니다.

Red Hat, CentOS 및 Oracle Linux 시스템의 경우:

$ sudo yum install nginx-모듈-이미지-필터

설치가 완료되면 NGINX Plus용 이미지 필터 모듈 설치 의 2단계와 3단계에 따라 NGINX를 구성하고 다시 로드합니다.

소스에서 Image‑Filter 모듈을 컴파일하여 정적으로 컴파일된 모듈이나 동적 모듈로 로드하는 것도 가능합니다. 자세한 내용은 NGINX Plus 관리자 가이드를 참조하세요.

픽셀 밀도에 맞는 이미지 크기

Image‑Filter 모듈을 사용하면 각 이미지의 단일 "소스" 버전을 만들고 배포할 수 있으며 NGINX Plus에서 브라우저에서 요청한 모든 크기 변형에 맞게 크기를 조정하여 제공할 수 있습니다. 수동으로 이미지 크기를 조정하고 웹 서버에 배포하지 않고도 HTML 소스 내에서 반응형 웹 페이지와 이미지를 세부적으로 조정할 수 있습니다.

이 샘플 HTML 파일에서는 픽셀 밀도가 다른 장치에 대한 4가지 이미지 변형을 정의합니다.

< html > < head > < title > 반응형 로고  title >  head > < body > < h2 > 픽셀 밀도에 따른 로고 선택  h2 > < img src= "/img400/mylogo.png" srcset= "/img400/mylogo.png 1x, /img800/mylogo.png 2x, /img1200/mylogo.png 3x, /img1600/mylogo.png 4x" >  body >  html >

/img400 , /img800 , /img1200 , /img1600 디렉토리는 실제로 존재하지 않습니다. 대신 다음 NGINX Plus 구성은 /img 접두사가 붙은 자산에 대한 요청을 일치시키고 이를 원래 파일 이름(예: 이전 HTML의 mylogo.png )으로 이미지 크기를 조정하는 요청으로 변환합니다.

서버 { listen 80;
root /var/www/public_html;

location ~ ^/img([0-9]+)(?:/(.*))?$ {
alias /var/www/source_images/$2;
image_filter_buffer 10M;
image_filter resize $1 -;
}
}

서버 블록은 NGINX Plus가 들어오는 HTTP 요청을 처리하는 방법을 정의합니다. listen 지시어는 NGINX Plus에게 HTTP 트래픽의 기본값인 포트 80에서 수신하도록 지시합니다. 루트 지시문은 디스크에서 이 웹사이트의 위치를 지정합니다. 이 간단한 예에서 우리는 NGINX Plus에서 호스팅하는 정적 웹사이트를 사용하고 있지만, NGINX Plus가 동적 콘텐츠나 FastCGI와 같은 애플리케이션 커넥터에 대한 역방향 프록시 역할을 하는 것도 일반적입니다. 이러한 모든 사용 사례는 소스 이미지를 NGINX Plus 서버에 배포하여 여기에 설명된 대로 Image‑Filter 모듈을 활용할 수 있습니다.

위치 블록은 정규 표현식을 사용하여 /img 로 시작하고 뒤에 하나 이상의 숫자가 오는 모든 디렉토리에 저장된 자산에 대한 요청을 일치시킵니다. 숫자는 변수 $1 로 캡처되고, 그 뒤에 오는 파일 이름은 변수 $2 로 캡처됩니다. 그런 다음 별칭 지시어를 사용하여 소스 이미지가 들어 있는 디스크의 디렉토리에서 이 요청을 처리합니다. 이 디렉토리는 루트 경로 아래에 없으므로 클라이언트는 소스 이미지를 직접 요청할 수 없습니다.

소스 이미지가 매우 클 가능성이 높고 너비가 수천 픽셀에 달할 수 있으므로 Image‑Filter 모듈이 이미지를 로드하고 크기를 조정하는 데 충분한 메모리를 할당해야 합니다. 이 예제에서는 최대 10MB 크기의 이미지 파일을 지원하기 위해 image_filter_buffer 지시어를 사용합니다.

마지막으로, image_filter 지시어는 Image‑Filter 모듈에 /img 디렉토리 이름의 접미사에서 캡처한 너비로 소스 이미지의 크기를 조정하라고 지시합니다. 대시(‑)는 NGINX Plus에게 소스 이미지의 종횡비를 유지하라고 알려줍니다.

생산 사용을 위한 고려 사항

픽셀 밀도에 맞는 이미지 크기 구성에서 설명한 구성은 이미지를 요청하는 데 사용된 디렉토리 이름에 따라 모든 크기의 이미지 변형을 제공할 수 있습니다. 그러나 운영 환경에서는 웹 서버가 요청마다 이미지 크기를 조정할 때까지 기다리고 싶지 않습니다. 이는 전반적인 지연 시간에 좋지 않으며 상당한 CPU 오버헤드를 추가할 수도 있습니다.

가장 효과적인 해결책은 크기가 조절된 이미지 변형을 캐시하여 이후의 각 변형에 대한 요청이 이미지 필터 모듈을 거치지 않고 캐시에서 처리되도록 하는 것입니다. NGINX Plus 구성을 사용하면 이미지 크기 조정을 수행하는 별도의 가상 서버를 정의하고, 요청된 이미지 크기가 캐시에 없는 경우에만 해당 서버에 요청을 프록시하여 이를 구현할 수 있습니다. 이것을 반응형 이미지 서버 라고 부릅니다.

프런트엔드 웹 서버와 반응형 이미지 서버를 위한 '위치' 블록이 있는 NGINX Plus의 프로덕션 구성입니다. 더욱 반응성이 뛰어난 웹 디자인을 위해 웹 서버는 Image-Filter 모듈을 사용하여 이미지 서버에서 생성된 크기 변형을 캐시합니다.
그림 1. 프런트엔드 웹 서버에서 캐싱이 활성화된 반응형 이미지 서버의 프로덕션 구성

임의의 요청이 이미지 크기 조정 작업을 수행하도록 허용할 경우 보안에 미치는 영향도 고려해야 합니다. 공격자가 /img1001/mylogo.png , /img1002/mylogo.png , /img1003/mylogo.png 등과 같은 고유한 이미지 자산 변형에 대한 빠른 요청을 하는 경우 캐싱을 구성해도 도움이 되지 않습니다. 상대적으로 적은 양의 요청이라도 이러한 공격은 과도한 CPU 사용률로 인해 서비스 거부(DoS)를 초래할 수 있습니다. 이 문제를 해결하기 위해 반응형 이미지 서버에는 속도 제한을 적용하지만, 캐시된 변형이 포함된 프런트엔드 서버에는 속도 제한을 적용하지 않습니다. 다음 구성은 이미지 필터 모듈에 캐싱과 속도 제한을 적용하여 픽셀 밀도에 맞게 이미지 크기를 조정하는 구성을 확장합니다.

proxy_cache_path /var/www/imgcache 레벨=1 키_존=크기 조정:1m 최대_크기=256m;
서버 {
수신 대기 80;
루트 /var/www/public_html;

위치 ~ ^/img([0-9]+)(?:/(.*))?$ {
proxy_pass http://127.0.0.1:9001;
proxy_cache 크기 조정;
proxy_cache_valid 180m;
}
}

limit_req_zone "1" 존=2초당:32k 속도=2r/s;

서버 {
수신 대기 9001;
허용 127.0.0.1;
모두 거부;
limit_req 존=2초당 버스트=10;

위치 ~ ^/img([0-9]+)(?:/(.*))?$ {
별칭 /var/www/source_images/$2;
이미지 필터 버퍼 10M;
이미지 필터 크기 조정 $1 -;
}
}

먼저 proxy_cache_path 지시문을 사용하여 캐시된 이미지의 위치를 정의합니다. keys_zone 매개변수는 캐시 인덱스( 크기 조정 됨)에 대한 공유 메모리 영역을 정의하고 약 8,000개의 크기가 조정된 이미지에 충분한 1MB를 할당합니다. max_size 매개변수는 NGINX Plus가 새로 캐시된 항목을 위한 공간을 마련하기 위해 캐시에서 가장 최근에 요청되지 않은 이미지를 제거하기 시작하는 지점을 정의합니다.

프런트엔드 웹 서버(포트 80에서 수신)에 대한 위치 지시문은 proxy_pass 지시문을 사용하여 /img 로 시작하는 요청을 내부적으로 호스팅되는 반응형 이미지 서버(127.0.0.1:9001)로 전송합니다. proxy_cache 지시어는 반응형 이미지 서버의 응답을 저장하는 데 사용할 캐시 이름( 크기 조정됨 )을 지정하여 이 위치에 대한 캐싱을 활성화합니다. proxy_cache_valid 지시어는 크기가 조절된 이미지가 최소 180분 동안 캐시에 보관되도록 합니다(캐시가 max_size를 초과하고 가장 최근에 요청되지 않은 이미지인 경우 제외). 또한 응답형 이미지 서버에서 잘못된 응답이 캐시되지 않도록 합니다.

캐싱에 대한 자세한 설명은 NGINX 및 NGINX Plus를 사용한 캐싱 가이드를 참조하세요.

반응형 이미지 서버 자체를 정의하기 전에 limit_req_zone 지시어로 속도 제한을 지정합니다. 지침 자체는 속도 제한을 적용하지 않습니다. 초당 두 개의 요청으로 속도 제한을 정의한 후, limit_req 지침을 서버 블록에 포함하여 반응형 이미지 서버에 적용합니다(다음 문단 참조). 일반적으로 속도 제한은 요청의 속성에 따라 지정되지만 이 경우에는 정적 키 값 "1" 을 지정하여 제한이 모든 요청자에게 적용되도록 합니다. 우리는 키의 고정된 카디널리티가 1이므로 공유 메모리 영역의 크기를 가능한 가장 작은 값인 3KB로 설정했습니다.

반응형 이미지 서버의 서버 블록은 포트 9001에서 수신합니다. 응답형 이미지 서버에 로컬호스트(프런트엔드 웹 서버)만 연결할 수 있도록 허용거부 지침을 포함했습니다. 그런 다음 limit_req 지시문을 포함하여 이전에 정의된 속도 제한을 적용합니다. burst 매개변수는 속도 제한을 시행하기 전에 10개의 동시 요청을 허용합니다. 속도 제한이 적용되면, 초과 요청은 제한 내에서 처리될 때까지 지연됩니다.

위치 블록은 픽셀 밀도에 맞게 이미지 크기를 조정하는 것과 동일하지만, 이제 요청된 이미지가 캐시에 없고 속도 제한을 초과하지 않은 경우에만 실행됩니다.

이 기본 구성에서는 단일 NGINX Plus 인스턴스가 프런트엔드 웹 서버와 반응형 이미지 서버 역할을 모두 수행합니다. 이미지 처리에는 많은 계산이 필요하므로 엄청난 작업 부하가 발생할 가능성이 있고 NGINX Plus가 DoS 공격을 받기 쉬워질 수 있습니다. 모든 작업자 프로세스가 이미지 크기 조정 요청으로 바빠서 프런트엔드 웹 서버가 즉시 새 요청을 수락할 수 없는 상황을 피하려면 이미지 처리에 전담된 별도의 NGINX Plus 인스턴스를 실행하는 것이 좋습니다. 이렇게 하면 프런트엔드 웹 서버의 작업자 프로세스와 이미지 처리를 수행하는 프로세스가 분리됩니다. 동일한 호스트에서 NGINX Plus의 별도 인스턴스를 실행하려면 명령줄에서 다른 구성 파일을 지정하세요.

$ sudo nginx -c /etc/nginx/resize-server.conf

반응형 이미지의 액션

반응형 이미지가 실제로 어떻게 적용되는지 확인하는 가장 효과적인 방법은 뷰포트 크기가 변경됨에 따라 브라우저가 어떤 srcset 이미지 변형을 사용할지 결정하는 모습을 관찰하는 것입니다. 간단한 이미지 갤러리의 HTML 소스는 다음과 같습니다. 데모 목적으로 각 이미지의 크기 변형이 약간씩 다르므로 브라우저가 다른 변형을 선택할 수 있는 많은 "중단점"이 생성될 수 있습니다.

<!DOCTYPE HTML>
<HTML로>
<머리>
<제목>반응형 이미지 갤러리</제목>
</머리>
<>
 
<h2>반응형 이미지 갤러리</h2>

<이미지 출처="/img100/1-도미노.jpg" 크기="(최소 너비: 20em) 40vw, 100vw" srcset= "/img110/1-dominos.jpg 110w, /img210/1-dominos.jpg 210w, /img310/1-dominos.jpg 310w, /img410/1-dominos.jpg 410w, /img510/1-dominos.jpg 510w, /img610/1-dominos.jpg 610w" > < img src= "/img100/2-sign.jpg" 크기= "(최소 너비: 20em) 40vw, 100vw" srcset= "/img120/2-sign.jpg 120w, /img220/2-sign.jpg 220w, /img330/2-sign.jpg 330w, /img420/2-sign.jpg 420w, /img520/2-sign.jpg 520w, /img620/2-sign.jpg 620w" > < img src= "/img100/3-thruppence.jpg" 크기= "(최소 너비: 20em) 40vw, 100vw" srcset= "/img130/3-thruppence.jpg 130w, /img230/3-thruppence.jpg 230w, /img330/3-thruppence.jpg 330w, /img440/3-thruppence.jpg 440w, /img550/3-thruppence.jpg 550w, /img660/3-thruppence.jpg 660w" > < img src= "/img100/4-aces.jpg" 크기= "(최소 너비: 20em) 40vw, 100vw" srcset= "/img140/4-aces.jpg 140w, /img240/4-aces.jpg 240w, /img340/4-aces.jpg 340w, /img440/4-aces.jpg 440w, /img540/4-aces.jpg 540w, /img640/4-aces.jpg 640w" >  body >  html >

아래 스크린샷은 네트워크 탭에 검사기를 연 상태에서 Chrome 브라우저에서 이 웹 페이지의 내용을 보여줍니다. 이름 열에는 서버에 요청된 각 이미지 변형의 경로가 표시되므로 웹 서버의 로그를 확인하지 않고도 선택한 크기를 확인할 수 있습니다.

그림 2의 좁은 뷰포트를 사용하면 브라우저는 220~310픽셀 너비의 이미지를 선택했습니다( 이름 열의 /img 디렉토리 이름에 있는 숫자 접미사는 해당 값 사이에 있습니다).

그림 2. 뷰포트가 좁은 경우 반응형 이미지 갤러리

그림 3에서 브라우저 창을 넓히면 브라우저는 440~540픽셀 너비의 이미지(마지막 4개 이미지)를 선택합니다. 이러한 이미지에 대한 시작 자 열의 값은 기타 입니다.

그림 3. 뷰포트가 더 넓을 때 반응형 이미지 갤러리

결론

NGINX Plus와 Image‑Filter 모듈을 사용하면 현재 브라우저 조건에 맞는 최적의 이미지 크기를 제공할 수 있습니다. 사전 제작 이미지 크기 조정, 일괄 처리 없이, 디스크에 있는 수백 개의 이미지 자산 변형을 관리할 필요 없이 이 작업을 수행할 수 있습니다. NGINX Plus가 완벽한 애플리케이션 전송을 달성하는 데 도움이 되는 또 다른 방법입니다.

NGINX Plus로 반응형 이미지를 직접 사용해보세요. 오늘 무료 30일 체험판을 시작하거나, 사용 사례에 대해 논의하기 위해 저희에게 연락하세요 .


"이 블로그 게시물에는 더 이상 사용할 수 없거나 더 이상 지원되지 않는 제품이 참조될 수 있습니다. 사용 가능한 F5 NGINX 제품과 솔루션에 대한 최신 정보를 보려면 NGINX 제품군을 살펴보세요. NGINX는 이제 F5의 일부가 되었습니다. 이전의 모든 NGINX.com 링크는 F5.com의 유사한 NGINX 콘텐츠로 리디렉션됩니다."