사이트 생성기, 프레임워크, CMS

WordPress와 같은 CMS 및 기타 사이트 생성기로 반응형 이미지를 더 쉽게 사용하는 방법을 알아보세요.

각 이미지의 대체 컷을 수동으로 저장하고 Squoosh.app과 같은 도구를 통해 직접 최적화하는 것보다 확실히 개선되었지만, 개발 프로세스에서 이미지 압축을 자동화하는 데는 몇 가지 제한사항이 있습니다. 한 가지 이유는 사이트 전반에서 사용되는 이미지를 항상 완벽하게 제어할 수 있는 것은 아닙니다. 웹에 있는 대부분의 사용자 대상 이미지는 자바스크립트나 스타일시트와 같은 개발 애셋과 함께 저장소에 상주하기보다는 사용자나 편집자가 업로드하는 개발 우려보다는 콘텐츠와 관련된 우려사항입니다.

여기에는 일반적으로 이미지 관리에 두 가지 이상의 프로세스가 필요합니다. 사이트를 구축하고 유지관리하는 데 사용되는 이미지 애셋(배경, 아이콘, 로고 등)을 위한 개발 수준 작업과 편집팀의 게시물에 삽입된 사진, 사용자가 업로드한 아바타와 같이 사이트의 사용을 통해 생성된 이미지 애셋과 관련된 또 다른 프로세스입니다. 맥락은 다를 수 있지만 최종 목표는 동일합니다. 바로 개발팀에서 정의한 설정을 기반으로 자동 인코딩과 압축입니다.

다행히 로컬 개발 워크플로에서 파악하게 된 이미지 처리 라이브러리를 다양한 컨텍스트에서 사용할 수 있습니다. 반응형 이미지 마크업에 모든 경우에 적용할 수 있는 방법은 없지만 이러한 시스템은 구현을 용이하게 하기 위해 적절한 기본값, 구성 옵션 및 API 후크를 제공합니다.

정적 사이트 생성기

작업 실행자와 비교할 때 Jekyll 또는 Eleventy 접근 방식과 같은 정적 사이트 생성기가 접근하는 방식은 몇 가지 유사점이 있습니다. 이러한 도구를 사용하여 배포가 가능한 웹사이트를 제작하려면 CSS 축소 또는 자바스크립트 트랜스파일 및 번들링을 비롯한 애셋 관리가 필요합니다. 짐작할 수 있겠지만 이러한 도구를 사용하면 이미 학습한 많은 라이브러리를 사용하여 동일한 방식으로 이미지 애셋을 처리할 수 있습니다.

공식 Eleventy용 이미지 플러그인은 여기에서 학습한 일부 작업과 마찬가지로 Sharp를 사용하여 크기 조절, 여러 소스 크기의 생성, 재인코딩, 압축을 제공합니다.

작업 실행기와 달리 정적 사이트 생성기는 이러한 라이브러리의 구성과 사용, 그리고 프로덕션 사이트를 위해 생성되는 마크업에 대한 직접적인 정보를 가지고 있습니다. 즉, 반응형 이미지 마크업을 자동화하는 데 훨씬 더 많은 작업을 할 수 있습니다. 예를 들어 이미지 표시를 위한 단축 코드의 일부로 호출된 경우 이 플러그인은 Sharp에 전달된 구성 옵션에 따라 HTML을 출력합니다.


const Image = require("@11ty/eleventy-img");
module.exports = function(eleventyConfig) {

async function imageShortcode(src, alt, sizes="100vw") {
  let metadata = await Image(src, {
  formats: ["avif", "webp", "jpeg"],
  widths: [1000, 800, 400],
  outputDir: "_dist/img/",
  filenameFormat: function( id, src, width, format, options ) {
      const ext = path.extname( src ),
        name = path.basename( src, ext );

      return `${name}-${width}.${format}`
  }
  });

  let imageAttributes = {
  alt,
  sizes,
  loading: "lazy"
  };

  return Image.generateHTML(metadata, imageAttributes);
}

eleventyConfig.addAsyncShortcode("respimg", imageShortcode);
};

그런 다음 기본 이미지 구문 대신 이 단축 코드를 사용할 수 있습니다.

{‌% respimg "img/butterfly.jpg", "Alt attribute.", "(min-width: 30em) 800px, 80vw" %}

위와 같이 여러 인코딩을 출력하도록 구성된 경우 생성된 마크업은 생성된 후보 크기 목록으로 이미 완전히 채워진 <source> 요소, type 속성, srcset 속성을 포함하는 <picture> 요소가 됩니다.

<picture><source type="image/avif" srcset="/img/butterfly-400.avif 400w, /img/butterfly-800.avif 800w, /img/butterfly-1000.avif 1000w" sizes="(min-width: 30em) 800px, 80vw"><source type="image/webp" srcset="/img/butterfly-400.webp 400w, /img/butterfly-800.webp 800w, /img/butterfly-1000.webp 1000w" sizes="(min-width: 30em) 800px, 80vw"><source type="image/jpeg" srcset="/img/butterfly-400.jpeg 400w, /img/butterfly-800.jpeg 800w, /img/butterfly-1000.jpeg 1000w" sizes="(min-width: 30em) 800px, 80vw"><img alt="Alt attribute." loading="lazy" src="/img/butterfly-400.jpeg" width="1000" height="846"></picture>

물론 이 플러그인은 렌더링된 레이아웃에서 이미지의 최종 크기와 위치를 알 수 없으므로 실행 가능한 sizes 속성을 generate할 수 없지만 마크업을 생성할 때 입력으로 수락합니다. RespImageLint의 또 다른 작업입니다.

프레임워크

클라이언트 측 렌더링 프레임워크에는 이미지 애셋 자체를 수정, 인코딩, 압축하기 위해 Webpack과 같은 작업 실행기 또는 번들러가 필요합니다. 예를 들어 반응형 로더는 Sharp 라이브러리를 사용하여 이미지 애셋을 다시 저장합니다. 그런 다음 이미지를 객체로 import할 수 있습니다.

  import imageAVIF from 'img/butterfly.jpg?sizes[]=400,sizes[]=800,sizes[]=1000&format=avif';
  import imageWebP from 'img/butterfly.jpg?sizes[]=400,sizes[]=800,sizes[]=1000&format=webp';
  import imageDefault from 'img/butterfly.jpg?sizes[]=400,sizes[]=800,sizes[]=1000';

가져온 이미지는 React의 이미지 구성요소와 같은 추상화를 통해 사용하거나 반응형 이미지 마크업을 직접 채우는 데 사용할 수 있습니다.

<picture>
  <source type='image/avif' srcSet={imageAVIF.srcSet} sizes='…' />
  <source type='image/webp' srcSet={imageWebp.srcSet} sizes='…' />
  <img
    src={imageDefault.src}
    srcSet={imageDefault.srcSet}
    width={imageDefault.width}
    height={imageDefault.height}
    sizes='…'
    loading="lazy"
  />

클라이언트 측 렌더링을 실행하는 프레임워크는 Lazysizessizes="auto"를 사용할 수 있는 강력한 후보이며, 거의 완전히 자동화된 반응형 이미지를 제공합니다.

콘텐츠 관리 시스템

WordPress는 네이티브 반응형 이미지 마크업을 가장 일찍 도입한 제품 중 하나이며 WebP를 지원하고 출력 MIME 유형을 제어하는 기능과 함께 WordPress 4.4에 도입된 이후 API가 점진적으로 개선되었습니다. WordPress 코어는 ImageMagick PHP 확장 프로그램(또는 GD 라이브러리가 없는 경우)을 사용하도록 설계되었습니다.

WordPress 관리자 인터페이스를 통해 이미지가 업로드되면 소스 이미지는 로컬 머신에서와 동일한 방식으로 서버에서 사용자 대상 파일을 생성하는 데 사용됩니다. 기본적으로 WordPress의 모든 이미지 출력에는 테마에 구성된 이미지 크기에 따라 생성된 srcset 속성이 있습니다.

생성된 이미지에 대해 구성할 수 있는 두 가지 주요 설정은 압축 품질출력 MIME 유형입니다.

예를 들어 생성된 모든 이미지의 기본 압축 품질을 70로 설정하려면 다음을 사용합니다.

add_filter( 'wp_editor_set_quality', function() { return 70; } );

더 나은 압축을 위해 다음을 사용하여 업로드된 JPEG 이미지의 출력 형식을 WebP로 전환하세요.

add_filter( 'image_editor_output_format', function( $mappings ) {
  $mappings[ 'image/jpeg' ] = 'image/webp';
    return $mappings;
} );

WordPress가 업로드된 이미지에서 생성하는 모든 대체 컷과 인코딩을 완전히 이해한다는 점을 감안할 때 이미지 첨부파일의 생성된 전체 srcset 값을 검색하는 도우미 함수(예: wp_get_attachment_image_srcset())를 제공할 수 있습니다.

이 시점에서 짐작하셨겠지만 sizes 속성을 사용하는 것은 조금 더 까다롭습니다. 레이아웃에 이미지가 사용되는 방식에 관한 정보가 없는 경우, WordPress는 현재 '이 이미지는 사용 가능한 표시 영역의 100% 를 차지해야 함'(최대 소스의 고유 크기까지)을 효과적으로 나타내는 sizes 값을 기본값으로 설정합니다. 이는 예측 가능한 기본값이지만 실제 애플리케이션에는 올바른 값이 아닙니다. wp_calculate_image_sizes()를 사용하여 템플릿에서 상황에 맞는 sizes 속성을 설정해야 합니다.

물론, 개발팀과 사용자 모두에게 최신 이미지 워크플로를 더 빠르게 제공하기 위한 전용 WordPress 플러그인이 많습니다. 가장 흥미로운 점은 Jetpack의 Site Accelerator (이전의 'Photon')와 같은 플러그인이 인코딩을 위한 서버 측 협상을 제공하여 사용자가 <picture>type 마크업 패턴 없이도 브라우저에서 지원할 수 있는 가장 작고 효율적인 인코딩을 받을 수 있다는 사실입니다. 이 작업은 CMS와 관계없이 직접 활용할 수 있는 기술인 이미지 콘텐츠 전송 네트워크를 사용하여 이루어집니다.

이 모든 것이 Shopify와 같은 호스팅된 CMS 솔루션에도 적용되지만 메커니즘 자체는 다소 다릅니다. 즉, 대체 이미지 소스 및 상응하는 srcset 속성 생성<picture> 요소를 통한 아트 디렉션을 위한 유사한 후크를 제공합니다.