고성능 이미지 소스를 원활하게 생성할 수 있도록 개발 프로세스입니다.
이미지 데이터의 인코딩부터 정보 집약적인 아키텍처까지
반응형 이미지를 지원하는 마크업은 컴퓨터가 기계와 통신하는 방법입니다. 보유하신
클라이언트 브라우저가 서버에 요구를 전달하고 서버가 친절하게 응답하는 여러 방법을 발견했습니다.
반응형 이미지 마크업 (특히 srcset
및 sizes
)을 사용하면 상대적으로 충격적인 정도를 알 수 있습니다.
몇 자(영문 기준)여야 합니다. 좋든 나쁘든 이 간결성은 의도적으로 설계된 것입니다. 이러한 문법을 덜 간결하게 만들면 개발자가
브라우저에서 파싱하기 더 어려울 수 있습니다. 문자열에 더 복잡해질수록
파서 오류가 있거나 브라우저 간에 의도치 않은 동작 차이가 있을 가능성이 있습니다.
그러나 이러한 대상이 너무 위협적으로 느껴지게 만들 수 있는 특성은 해결책, 즉 쉬운 문법을 제공할 수도 있습니다. 머신의 읽기는 머신에서 더 쉽게 작성하는 구문입니다. 자동화된 애플리케이션의 많은 예를 들어보셨겠지만 웹 사용자로서 이미지 인코딩 및 압축: 소셜 미디어 플랫폼, 콘텐츠를 통해 웹에 업로드된 모든 이미지 심지어 이메일 클라이언트까지도 거의 변함없이 크기를 조절하고 다시 인코딩하며 압축하는 것입니다
마찬가지로 플러그인, 외부 라이브러리, 독립형 빌드 프로세스 도구 또는 클라이언트 측 스크립팅의 책임 있는 사용을 통해, 반응형 이미지 마크업은 자동화에 쉽게 부합합니다.
이 두 가지는 이미지 성능 자동화와 관련된 두 가지 주요 관심사입니다. 이미지 생성 관리, 인코딩 관리,
압축, srcset
속성을 채우는 데 사용할 대체 소스를 제공하고 사용자 대상 마크업을 생성합니다.
이 모듈에서는 최신 워크플로의 일부로 이미지를 관리하는
개발 프로세스의 자동화된 단계 또는 사이트를 구동하는 프레임워크 또는 콘텐츠 관리 시스템을 통해
전용 콘텐츠 전송 네트워크에 의해 거의 완전히 추상화됩니다.
압축 및 인코딩 자동화
시간을 들여 이상적인 인코딩 및 레벨을 직접 결정할 수 있는 상황은 거의 발생하지 않습니다. 압축해야 할 수도 있고 그렇게 하는 것도 원치 않을 것입니다. 따라서 이미지 전송 크기를 가능한 한 작게 유지하여 크기를 조정하는 것이 중요하므로 제작 웹사이트를 대상으로 하는 모든 이미지 애셋의 압축 설정 및 대체 소스를 재저장하는 작업에는 일상 업무에 큰 병목 현상이 발생할 수 있습니다
다양한 이미지 형식과 압축 유형에 대해 읽을 때 배웠듯이 이미지를 위한 가장 효율적인 인코딩은 항상 반응형 이미지에서 알아본 것처럼 이미지 소스에 필요한 대체 크기는 이미지가 페이지 레이아웃에서 차지하는 위치에 따라 결정됩니다. 최신 워크플로에서는 이러한 결정에 접근하여 개별 이미지가 아니라 전체적으로 적용할 수 있습니다. 이미지를 사용할 때 상황에 가장 적합한 이미지 값을 사용하도록 설계된 모델입니다
사진 이미지 디렉토리의 인코딩을 선택할 때는 AVIF가 품질과 전송 크기 면에서 가장 적합합니다. 지원이 제한되어 있지만 WebP는 최적화된 최신 대체를 제공하며 JPEG가 가장 안정적인 기본값입니다. 대체 페이지 레이아웃에서 사이드바를 차지할 이미지를 위해 생성해야 하는 이미지의 크기는 가장 높은 중단점에서 전체 브라우저 표시 영역을 차지하도록 설계되었습니다. 압축 설정을 하려면 흐릿하게 하는 것을 고려해야 합니다. 압축 아티팩트를 사용하여 각 이미지에서 가능한 모든 바이트를 잘라낼 공간이 줄어들게 됩니다. 보다 유연하고 안정적인 워크플로를 제공한다는 사실을 알고 있을 겁니다 요약하자면, 여러분은 이전에 했던 것과 동일한 의사결정 프로세스를 따르게 됩니다. 큰 글씨로 쓰입니다
처리 자체의 경우, 이미지 자체에서 이미지를 처리하는 방법을 제공하는 수많은 오픈소스 이미지 처리 라이브러리가 이미지를 일괄적으로 변환, 수정, 편집하는 등 속도, 효율성, 신뢰성 경쟁을 벌입니다. 이러한 프로세싱은 라이브러리를 사용하면 인코딩 및 압축 설정을 이미지의 전체 디렉토리에 한 번에 적용할 수 있으며, 이미지 편집 소프트웨어를 열어야 하고, 해당 설정에서 원본 이미지 소스를 보존하는 방식으로 즉시 조정할 수 있습니다 이 API는 로컬 개발 환경부터 웹 서버 자체(예: 이미지 파일의 압축에 중점을 둔 ImageMin) Node.js는 일련의 플러그인을 통해 특정 애플리케이션에 맞게 확장될 수 있습니다. 크로스 플랫폼 ImageMagick 및 Node.js 기반 Sharp 엄청나게 많은 기능이 즉시 함께 제공됩니다.
이러한 이미지 처리 라이브러리를 통해 개발자는 이미지를 원활하게 최적화하는 전용 도구를 빌드할 수 있습니다. 표준 개발 프로세스의 일부로 사용하여 프로젝트에서 항상 프로덕션에 즉시 사용 가능한 이미지를 참조하도록 함 사용하는 것이 좋습니다
로컬 개발 도구 및 워크플로
Grunt, Gulp, Webpack 등의 작업 실행기 및 번들러를 사용하여 CSS 및 JavaScript 축소 등 기타 일반적인 성능 관련 작업과 함께 이미지 확장 소재를 최적화 받는사람 비교적 간단한 사용 사례를 살펴보겠습니다. 프로젝트의 디렉터리에는 수십 개의 사진 이미지가 있고 공개 웹사이트에 사용하는 것이 좋습니다.
먼저 이러한 이미지를 일관되고 효율적인 방식으로 인코딩해야 합니다. 이전 모듈에서 배운 것처럼
WebP는 품질과 파일 크기 측면에서 사진 이미지에 효율적인 기본값입니다. WebP는 잘 지원되지만
보편적으로 지원되지는 않으므로 프로그레시브 JPEG 형식으로 대체도 포함하는 것이 좋습니다. 그런 다음
srcset
속성을 사용하여 애셋을 효율적으로 전송하려면
각 인코딩의 대체 크기를 지정합니다.
이미지 편집 소프트웨어를 사용하면 반복적이고 시간이 많이 소요되는 작업일 수 있지만
Gulp는 정확히 이러한 종류의 반복을 자동화하도록 설계되었습니다. gulp-response
Sharp를 사용하는 플러그인은 모두 비슷한 패턴을 따르는 여러 옵션 중 하나입니다.
소스 디렉토리의 모든 파일을 수집하고, 다시 인코딩하고, 동일한 표준화된 '품질'에 따라 압축
이미지 형식 및 압축에서 배운 요약입니다. 그런 다음 결과 파일은 정의된 경로로 출력됩니다.
원본 파일은 그대로 두고 사용자 대상 img
요소의 src
속성에서 참조할 준비가 되었습니다.
const { src, dest } = require('gulp');
const respimg = require('gulp-responsive');
exports.webp = function() {
return src('./src-img/*')
.pipe(respimg({
'*': [{
quality: 70,
format: ['webp', 'jpeg'],
progressive: true
}]
}))
.pipe(dest('./img/'));
}
이와 같은 프로세스가 마련되어 있으면 프로젝트에 실수로 참여한 사람이 발생하더라도 프로덕션 환경에 아무런 해가 되지 않습니다. 사진과 상관없이 원본 이미지 소스가 포함된 디렉터리에 대용량 트루 컬러 PNG로 인코딩된 사진을 이 작업은 효율적인 WebP와 안정적인 프로그레시브 JPEG 대체를 생성하며 즉석에서 쉽게 조정할 수 있는 압축 수준입니다. 물론 이 과정을 통해 원본 이미지가 파일은 프로젝트의 개발 환경 내에 보관되므로 언제라도 이러한 설정을 조정할 수 있습니다. 자동으로 출력만 덮어쓰는 것입니다
여러 파일을 출력하려면
width
키 및 픽셀 단위 값:
const { src, dest } = require('gulp');
const respimg = require('gulp-responsive');
exports.default = function() {
return src('./src-img/*')
.pipe(respimg({
'*': [{
width: 1000,
format: ['jpeg', 'webp'],
progressive: true,
rename: { suffix: '-1000' }
},
{
width: 800,
format: ['jpeg', 'webp'],
progressive: true,
rename: { suffix: '-800' }
},
{
width: 400,
format: ['jpeg', 'webp'],
progressive: true,
rename: { suffix: '-400' },
}]
})
)
.pipe(dest('./img/'));
}
위 예에서는 원본 이미지 (monarch.png)가 3.3MB를 초과했습니다. 가장 큰 파일은 이 작업 (monarch-1000.jpeg)은 약 150KB입니다. 가장 작은 파일인 monarch-400.web은 32KB에 불과합니다.
[10:30:54] Starting 'default'...
[10:30:54] gulp-responsive: monarch.png -> monarch-400.jpeg
[10:30:54] gulp-responsive: monarch.png -> monarch-800.jpeg
[10:30:54] gulp-responsive: monarch.png -> monarch-1000.jpeg
[10:30:54] gulp-responsive: monarch.png -> monarch-400.webp
[10:30:54] gulp-responsive: monarch.png -> monarch-800.webp
[10:30:54] gulp-responsive: monarch.png -> monarch-1000.webp
[10:30:54] gulp-responsive: Created 6 images (matched 1 of 1 image)
[10:30:54] Finished 'default' after 374 ms
물론 결과를 면밀히 검토하여 눈에 띄는 압축 아티팩트가 있는지 확인하거나 압축을 늘리는 것이 좋습니다. 추가 할인 혜택을 받으세요. 이 작업은 비파괴적이므로 이러한 설정은 쉽게 변경할 수 있습니다.
모두 말하자면, 신중한 수동 마이크로 최적화를 통해 몇 킬로바이트를 줄일 수 있는 대가로 프로세스를 얻게 되는 것입니다. 효율적일 뿐만 아니라 탄력적인 고성능 이미지 애셋에 대한 지식을 원활하게 적용하는 도구입니다. 프로젝트 전체에 적용할 수 있습니다
반응형 이미지 마크업 사용 사례
srcset
속성을 채우는 것은 일반적으로 간단한 수동 프로세스입니다. 이 속성은
소스를 생성할 때 이미 수행한 구성에 대한 정보가 포함됩니다. 위의 작업에서
속성이 따르는 파일 이름 및 너비 정보입니다.
srcset="filename-1000.jpg 1000w, filename-800.jpg 800w, filename-400.jpg 400w"
srcset
속성의 콘텐츠는 규범적인 것이 아니라 설명을 위한 것입니다. 인프라에 과부하가 걸려도
srcset
속성(모든 소스의 가로세로 비율이 일관적이어야 함) srcset
속성에는 URI가 포함될 수 있습니다.
불필요한 요청을 유발하지 않고 서버에서 생성한 모든 대체 컷의 너비와 너비를 조절하며, 더 많은 후보가
제공할수록 브라우저에서 더 효율적으로 요청을 맞춤화할 수 있습니다.
반응형 이미지에서 알아본 것처럼 <picture>
요소를 활용하여 WebP를 원활하게 처리하는 것이 좋습니다.
또는 JPEG 대체 패턴을 사용합니다. 여기서는 srcset
와 함께 type
속성을 사용합니다.
<picture>
<source type="image/webp" srcset="filename-1000.webp 1000w, filename-800.webp 800w, filename-400.webp 400w">
<img srcset="filename-1000.jpg 1000w, filename-800.jpg 800w, filename-400.jpg 400w" sizes="…" alt="…">
</picture>
앞서 살펴봤듯이 WebP를 지원하는 브라우저는 type
속성의 콘텐츠를 인식하고 해당 <source>
를 선택합니다.
요소의 srcset
속성을 이미지 후보 목록으로 사용합니다. 브라우저에서 image/webp
을(를) 유효한 미디어로 인식하지 않음
유형은 이 <source>
를 무시하고 대신 내부 <img>
요소의 srcset
속성을 사용합니다.
브라우저 지원과 관련하여 고려할 사항이 하나 더 있습니다. 반응형 이미지 마크업을 지원하지 않는 브라우저에서는
아니면 매우 오래된 탐색 컨텍스트에서 이미지가 손상될 위험이 있습니다. 이유: <picture>
,
이러한 브라우저에서는 <source>
및 srcset
가 모두 무시되므로 내부 <img>
의
src
속성
이미지를 아래로 축소하는 것은 시각적으로 원활하고 JPEG 인코딩이 보편적으로 지원되므로 최대 JPEG는 현명한 선택입니다
<picture>
<source type="image/webp" srcset="filename-1000.webp 1000w, filename-800.webp 800w, filename-400.webp 400w">
<img src="filename-1000.jpg" srcset="filename-1000.jpg 1000w, filename-800.jpg 800w, filename-400.jpg 400w" sizes="…" alt="…">
</picture>
sizes
는 다루기가 조금 더 어려울 수 있습니다. 배운 내용에서 알 수 있듯이 sizes
는 필연적으로 문맥에 맞추어져 있습니다.
는 렌더링된 레이아웃에서 이미지가 차지할 공간의 양을 알지 못하면 속성을 채울 수 없습니다. 대상
요청을 처리할 때 정확한 sizes
속성이 요청 시 마크업에 있어야 합니다.
페이지 레이아웃을 관리하는 스타일이 요청되기 훨씬 전에 최종 사용자가 만듭니다. 모두 sizes
생략
는 HTML 사양을 위반할 뿐만 아니라 sizes="100vw"
과 동일한 기본 동작을 유발하여
표시 영역 자체에 의해서만 제한되므로 가능한 가장 큰 후보 소스가 됨
선택할 수 있습니다.
특히 부담스러운 웹 개발 작업의 경우와 마찬가지로, 웹 개발의 부담을 덜기 위해 많은 도구가 생겨났습니다.
sizes
속성을 필기로 쓰는 프로세스입니다. respImageLint
은(는) 절대적으로
이 필수 코드 스니펫은 sizes
속성이 정확한지 검토하고 개선을 위한 제안사항을 제공합니다.
북마크릿으로 실행됩니다. 북마크는 브라우저에서 실행하는 도구로, 이미지가 포함된 완전히 렌더링된 페이지를 가리킵니다.
요소 브라우저가 페이지 레이아웃을 완전히 이해하는 상황에서는 픽셀에 가까운 그래픽을 구현할 수도 있습니다.
가능한 모든 표시 영역 크기에서 이미지가 해당 레이아웃에서 차지할 공간을 인식합니다.
sizes
속성을 린트하는 도구는 확실히 유용하지만 이를 도매 생성하는 도구로서 더 많은 가치가 있습니다.
아시다시피 srcset
및 sizes
문법은 시각적으로 원활한 방식으로 이미지 애셋 요청을 최적화하기 위한 것입니다. 하지만
프로덕션에 사용하면 안 되는 값이라면 기본 sizes
자리표시자 값 100vw
가 완벽하게 적합합니다.
를 사용하는 것이 좋습니다. 레이아웃 스타일이 준비되면 respImageLint
을 실행합니다.
복사하여 마크업에 붙여넣을 수 있는 맞춤형 sizes
속성을 훨씬 더 세부적인 수준으로 제공합니다.
손으로 쓴 것보다 더 낫습니다.
서버 렌더링 마크업으로 시작된 이미지 요청은 JavaScript에서 클라이언트 측 sizes
속성을 생성하기에는 너무 빨리 발생하지만,
이러한 요청이 클라이언트 측에서 시작된 경우에는 동일한 추론이 적용되지 않습니다. Lazysizes 프로젝트
예를 들어 레이아웃이 설정될 때까지 이미지 요청을 완전히 연기하여 자바스크립트가
sizes
값을 통해 개발자 여러분은 큰 편리함을 보장하고 사용자에게 가능한 한 가장 효율적인 요청을 보장해 드립니다.
그러나 이 접근 방식은 서버에서 렌더링한 마크업의 신뢰성과
최적화하며 페이지가 렌더링된 후에만 이러한 요청을 시작하면
LCP 점수에 부정적인 영향을 줄 수 있습니다.
물론 이미 React나 Vue 같은 클라이언트 측 렌더링 프레임워크를 사용하고 있다면
이러한 경우 Lazysizes를 사용하면 sizes
속성을 거의 완전히 추상화할 수 있습니다.
지연 로드 이미지의 sizes="auto"
가 합의를 얻고
네이티브 구현을 통해 Lazysizes는 효과적으로 새로 표준화된 브라우저 동작에 대한 폴리필이 될 것입니다.