크롬이 작은 JPEG 아이콘을 더 두껍게 그리는 이유, 부분 IDCT 스케일링 최적화 때문
- 크롬은 작게 렌더링되는 JPEG을 전체 해상도로 압축 해제한 뒤 축소하는 대신, libjpeg-turbo의 partial IDCT scaling 기법으로 저주파 성분만 디코딩함
- 8x8 블록 단위 DCT로 압축된 JPEG에서 1/8 축소 시 각 블록의 DC 계수(평균 색상)만 남기고 고주파 AC 계수를 건너뛰어 디코딩 속도와 메모리를 아낌
- 2000x2000 JPEG을 20x20으로 표시할 때 전체 디코딩은 약 12MB, 최종 결과는 약 1.2KB에 불과해 대부분의 정보가 버려짐을 저자가 계산으로 보여줌
- 이 최적화 때문에 15px 아이콘이 크롬에서는 엣지 디테일이 사라져 더 두껍게 보이고, 파이어폭스에서는 원본에 더 가깝게 보임
- 크롬은 8분수 단위로 가장 가까운 스케일을 계산해 부분 디코딩한 뒤 추가로 일반 다운샘플링을 적용하며, 저자는 결국 문제의 로고를 SVG로 교체해 해결함
Hacker News opinions
파이어폭스도 전체 디코딩 후 스케일링 안 함. downscale-during-decode라는 방식으로 스트리밍 디코드하면서 축소하는데, 8x8 블록 부분 디코딩까지는 안 하는 걸로 보임 (bugzilla 1045926)
크롬이랑 파이어폭스는 스케일링 알고리즘 자체가 다른 게 더 큰 차이를 만드는 거 아닌가 싶음. 크롬은 전체적으로 더 블러하고 파이어폭스는 샤프한데 링잉 아티팩트가 좀 더 있음. 난 파이어폭스 쪽이 더 좋음
객관적 이미지 품질 지표는 블러를 선호하는데 주관적 평가는 반대로 가는 경우가 많더라
메모리 부족할 때만 이 부분 스케일링 쓰면 좋을 듯. 근데 크롬이 램을 그렇게 많이 먹는 거 생각하면 20mb 아끼는 게 큰 의미가 있나 싶기도 함
파이어폭스 쪽 저해상도 디코딩 작업은 bugzilla 2033250에 있음. 벤치마크 숫자 보니까 이 트릭이 얼마나 효율적인지 새삼 느껴짐
PNG도 똑같은 문제 생길 것 같음. 크롬이 이 최적화 도입했을 때 일렉트론 릴리즈에 반영되면서 우리 제품 아이콘이 다 깨져서 SVG로 바꾸기 전까지 업그레이드를 미뤄야 했음
8배 이상 크게 만든 비트맵 아이콘을 왜 쓴 거임?
애초에 작은 아이콘에 JPEG 쓰는 거 자체가 이상함. JPEG은 사진용이고 아이콘은 SVG나 PNG, WebP 써야 함
libjpeg-turbo 대신 mozjpeg로 바꾸면 더 나은 결과 나옴. 모질라가 10년쯔음 메타/인스타그램용으로 JPEG에서 더 뽑아낸 라이브러리인데 이 글에서 비교할 만한 대상으로 언급할 만함