Chrome의 소형 JPEG 렌더링 차이 이유

원제: Why tiny JPEGs look different in Chrome

왜 중요한가

브라우저 엔진 간 JPEG 디코딩 전략의 차이가 UI 충실도에 영향을 미칠 수 있음을 실증한 사례로, 프런트엔드 최적화 설계 시 중요한 참고 사항이 된다.

개발자 Guillaume Técher가 2026년 8월에 공개한 블로그에서, Chrome과 Firefox가 15px 크기의 소형 JPEG를 다르게 렌더링하는 현상의 원인을 분석했다. Chrome은 JPEG의 DCT(이산 코사인 변환) 구조를 활용해 1/8 축소 시 고주파 계수를 생략하고 저주파 성분만 디코딩하는 최적화를 적용하며, 이로 인해 2000×2000 이미지 기준 약 12MB의 전체 비트맵을 메모리에 올리지 않고 처리할 수 있다.

Guillaume Técher가 동료의 컴퓨터에서 동일한 로고 이미지가 자신의 화면과 다르게 보이는 현상을 발견한 것이 계기였다. 해당 이미지는 15px로 렌더링된 JPEG였으며, Firefox에서는 얇게, Chrome에서는 두껍게 표시됐다. SVG로 교체하자 문제가 해결됐지만, Técher는 근본 원인을 추적했다.

JPEG는 압축 과정에서 이미지를 8×8픽셀 블록으로 나눠 DCT를 적용해 주파수 영역으로 변환한다. 이때 각 블록은 저주파(평탄한 색상)부터 고주파(체커보드 패턴)까지의 계수로 표현된다. 이미지를 크게 축소하면 잎사귀나 나무껍질 같은 세밀한 고주파 정보는 대부분 소실되고, 큰 덩어리의 색상 정보인 저주파 성분만 남는다.

Chrome은 이 점을 활용해, 이미지를 1/8 이하로 표시할 때 8×8 블록 전체를 디코딩하지 않고 DCT 계수 중 저주파에 해당하는 최상위 계수만 사용해 단일 픽셀을 생성한다. 2000×2000 JPEG를 20×20으로 표시할 경우, 전체 디코딩 시 약 12MB의 메모리가 필요한 반면, 이 최적화를 적용하면 최종 결과인 약 1.2KB 분량만 처리하면 된다. 단, 고주파 정보를 배제하기 때문에 렌더링 결과가 Firefox 등 다른 브라우저와 시각적으로 차이가 발생한다.

출처

guillaumetech.github.io — 원문 읽기 →