Srcset을 수동으로 작성하지 마세요: Symfony를 위한 궁극적인 이미지 솔루션
Source: Dev.to

Symfony에서 이미지 문제 해결: PGI 만나보기
이미지는 현대 웹에서 가장 무거운 요소입니다. 페이지 로드 속도를 늦추고, 누적 레이아웃 이동(CLS) 을 유발하며, 진정으로 반응형 디자인을 구현하려 할 때 개발자에게 악몽과 같은 경험을 안겨줍니다. 복잡한 “ 태그를 다루거나 다양한 브레이크포인트에 맞춰 srcset 값을 직접 계산해 본 적이 있다면 그 고통을 잘 아실 겁니다.
여기에 PGI(Progressive Image Bundle) — Symfony 6.4 및 그 이후 버전에서 이미지 처리를 위한 새로운 표준이 등장합니다.
훅: 코어 웹 바이탈이 모든 것을 바꾼 이유
Google의 코어 웹 바이탈—특히 **Largest Contentful Paint (LCP)**와 Cumulative Layout Shift (CLS)—은 웹사이트를 구축하는 방식을 완전히 바꾸어 놓았습니다. 이제 단순히 “이미지를 보여주는 것”만으로는 충분하지 않습니다. 다음을 만족시켜야 합니다:
- 이미지를 빠르게 표시하기.
- 이미지가 실제로 나타날 때 레이아웃이 튀지 않도록 보장하기.
많은 Symfony 개발자에게는 깔끔한 코드베이스를 유지하면서 100점 만점의 PageSpeed 점수를 달성하는 것이 타협처럼 느껴졌습니다. 맞춤형 반응형 로직을 작성하느라 시간을 많이 투자하거나, “충분히 좋은” 성능에 안주해야 했죠. PGI는 이러한 타협을 없애기 위해 탄생했습니다.
코드 쇼케이스: 혼란스러움에서 완벽함까지
전통적인 Twig
[Image: Hero image] }})
그리고 그것은 하나의 종횡비에 해당합니다.
PGI 사용 (Tailwind‑영감 문법)
실제 사례: 6slov.sk
PGI가 실제로 어떻게 동작하는지 확인하려면 6slov.sk 예시를 통해 다양한 디바이스에서 단일 이미지를 어떻게 처리하는지 살펴보세요.
다양한 디바이스에서의 동작
| 디바이스 | 동작 |
|---|---|
| 모바일 (sm) | 컨테이너 전체 너비를 차지하는 정사각형 (1:1) 크롭을 로드합니다. ![]() |
| 태블릿/데스크톱 (md+) | 자동으로 가로형 (16:9) 크롭으로 전환되어 그리드의 절반(6/12 열)을 차지합니다. ![]() |
렌더링된 HTML (깨끗하고 의미론적)
PGI는 blur placeholder를 포함하여 모든 무거운 작업을 처리하는 단일 최적화된 HTML 블록을 생성합니다:

What’s Happening Here?
| 구문 | 의미 |
|---|---|
sm:12@square | 작은 화면에서 전체 너비이며, 자동으로 1:1 비율로 잘립니다. |
md:6@landscape | 중간 브레이크포인트부터 절반 너비(6/12 열)이며, 자동으로 16:9 비율로 잘립니다. |
xl:[430x370] | 맞춤 레이아웃을 위한 임의 크기 – PGI는 sizes 속성에 직접 명시된 치수를 허용합니다. |
preload | PGI는 를 에 삽입하여 LCP 점수를 즉시 향상시킵니다. |
PGI의 “프로그레시브”: Blur‑up Experience
One of the most satisfying features for users is the built‑in Blurhash support. Instead of showing a blank space or a generic spinner, PGI renders a beautiful, ultra‑lightweight blurred version of the image immediately.
This blur‑up technique significantly improves perceived performance: users see the layout and the context of the image instantly, even on slow connections, while the high‑resolution version loads in the background. Once ready, the high‑res image smoothly fades in, delivering a polished experience.
기술 심층 분석: 제로 CLS와 CSS 마법
PGI는 레이아웃 이동을 어떻게 방지할까요? 단순히 width와 height 속성을 추가하는 것만으로는 충분하지 않습니다. PGI는 최신 CSS aspect-ratio와 CSS 변수를 활용합니다.
컴포넌트가 렌더링될 때, sizes 정의를 기반으로 종횡비를 계산합니다. 그런 다음 이미지를 정확히 필요한 공간을 예약하는 컨테이너에 감싸서 배치합니다. 이미지가 로드되는 동안 콘텐츠가 튀는 현상이 사라집니다—이미지가 지연 로드되거나 로드가 느리더라도 말이죠.
엔진 구동: LiipImagine 통합
PGI는 이미지 처리를 위해 휠을 새로 만들지 않습니다. 대신 거대한 LiipImagineBundle의 어깨 위에 서 있습니다. 기본적으로 PGI는 리사이징 및 필터링의 무거운 작업을 LiipImagine에 위임할 수 있어 전체 생태계를 활용할 수 있습니다.
이 시너지의 가장 강력한 기능 중 하나는 WebP와 같은 최신 포맷으로의 자동 변환입니다. 몇 줄의 설정만으로 PGI가 제공하는 모든 이미지가 완벽한 크기와 압축을 갖추도록 할 수 있습니다.
예시 설정
# config/packages/liip_imagine.yaml
liip_imagine:
default_filter_set_settings:
format: webp
webp:
generate: true
# config/packages/progressive_image.yaml
progressive_image:
image_configs:
quality: 75
post_processors:
cwebp: { q: 30 }
liip_imagine 데코레이터를 사용하면 PGI는 이미지 요청을 자동으로 LiipImagine의 필터 시스템을 통해 라우팅합니다. 이는 기존 Liip 필터를 모두 사용하면서 PGI의 뛰어난 Twig 구문 및 Zero CLS 기능을 활용할 수 있음을 의미합니다.
내부 동작: 가능하게 하는 설정
PGI의 가장 칭찬받는 측면 중 하나는 유연성입니다. 기본적으로 바로 작동하지만, 진정한 힘은 설정에 있습니다. progressive_image.yaml의 가장 중요한 부분을 살펴보겠습니다:
# config/packages/progressive_image.yaml
progressive_image:
# 1. Responsive Strategy
responsive_strategy:
grid:
framework: tailwind # or bootstrap, or custom
ratios:
landscape: "16/9"
square: "1/1"
hero: "21/9"
# 2. Resolvers (Where are your images?)
resolvers:
public_files:
type: "filesystem"
roots: [ '%kernel.project_dir%/public' ]
assets:
type: "asset_mapper"
# 3. Transparent HTML Caching
image_cache_enabled: true
image_cache_service: "cache.app"
1. 반응형 전략
이것이 PGI의 두뇌입니다. 번들에 Tailwind 혹은 Bootstrap을 사용한다고 알려주면, 각 브레이크포인트에 대한 컨테이너 너비를 자동으로 파악합니다. md:6이라고 선언하면, PGI는 md 컨테이너 너비를 찾아 2로 나눕니다(6/12 컬럼) 그리고 필요한 정확한 이미지 크기를 생성합니다.
2. 리졸버: 파일 자유
이미지를 public/ 폴더에 두든, 최신 Symfony AssetMapper를 사용하든, PGI는 이를 찾아낼 수 있습니다. 여러 위치를 탐색하도록 chain 리졸버를 정의할 수도 있습니다. 이는 Symfony의 새로운 기능으로 전환 중인 프로젝트에 큰 도움이 됩니다.
3. 성능 우선: HTML 캐싱
Blurhash를 생성하고 메타데이터를 읽는 데는 CPU 파워가 필요합니다. PGI는 투명한 HTML 캐싱으로 이를 해결합니다. 컴포넌트가 한 번 렌더링되면 최종 HTML이 캐시에 저장됩니다. 다음에 누군가 페이지를 방문하면 PGI는 캐시된 HTML을 즉시 제공하여 모든 PHP 로직을 건너뛰게 됩니다.
포인트 오브 인터레스트(PoI) 크롭
가장 멋진 기능 중 하나는 “스마트 크롭”입니다. 중앙을 무작위로 자르는 대신, 관심 지점을 정의할 수 있습니다:
이렇게 하면 이미지에서 가장 중요한 부분(예: 사람 얼굴)이 사각형, 세로, 가로 비율로 크롭되더라도 프레임 안에 유지됩니다.
다음 프로젝트에 PGI가 적합한 이유
PGI는 단순한 래퍼가 아니라 Symfony를 위한 완전한 생태계입니다:
- Zero Configuration: 설치하면 Bootstrap이나 Tailwind와 바로 작동합니다.
- Automatic Generation: 필요한 모든 크기를 실시간으로 생성하고 캐시합니다.
- LiipImagine Integration: 맞춤 필터가 필요할 경우 기존 도구와 원활하게 연동됩니다.
- Transparent Caching: 결과 HTML을 캐시하여 매 요청마다 메타데이터를 다시 계산하는 것을 방지합니다.
현대적인 Symfony 애플리케이션을 구축하면서 SEO, UX, 그리고 개발자로서의 정신적 안정을 중요하게 생각한다면, PGI는 퍼즐의 빠진 조각입니다. 이미 6slov.sk와 같은 고성능 사이트를 구동하고 있어 거의 완벽에 가까운 PageSpeed 점수를 달성하도록 돕고 있습니다.
PageSpeed를 높일 준비가 되셨나요?
Check out PGI on GitHub와 함께 더 빠르고 안정적인 웹을 향한 움직임에 동참하세요.



