From 373039b2d8ebe23c4709a9f8e713f38ed6422604 Mon Sep 17 00:00:00 2001 From: adityaverm-a Date: Wed, 3 Jun 2026 20:15:46 +0530 Subject: [PATCH] fix: prefer AVIF over WebP in format auto-selection (PPT-764) Reorder FORMAT_PRIORITY to avif > webp in both the container auto-optimizer and the CloudFront dit-header-normalization function so clients advertising image/avif receive AVIF instead of always falling back to WebP. Co-authored-by: Cursor --- .../lib/v8/functions/dit-header-normalization.js | 2 +- .../image-processing-stack.test.ts.snap | 2 +- .../lib/v8/test/unit/dit-function.test.ts | 2 +- .../auto-optimization/auto-optimizer.test.ts | 13 ++++++++++++- .../auto-optimization/auto-optimizer.ts | 2 +- 5 files changed, 16 insertions(+), 5 deletions(-) diff --git a/source/constructs/lib/v8/functions/dit-header-normalization.js b/source/constructs/lib/v8/functions/dit-header-normalization.js index d553e37c6..59533d9ed 100644 --- a/source/constructs/lib/v8/functions/dit-header-normalization.js +++ b/source/constructs/lib/v8/functions/dit-header-normalization.js @@ -1,7 +1,7 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -const FORMAT_PRIORITY = ['webp', 'avif', 'jpeg', 'png', 'heif', 'tiff', 'raw', 'gif']; +const FORMAT_PRIORITY = ['avif', 'webp', 'jpeg', 'png', 'heif', 'tiff', 'raw', 'gif']; const FORMAT_MAPPING = { 'image/webp': 'webp', diff --git a/source/constructs/lib/v8/test/snapshot/__snapshots__/image-processing-stack.test.ts.snap b/source/constructs/lib/v8/test/snapshot/__snapshots__/image-processing-stack.test.ts.snap index c41749de9..07d62adc6 100644 --- a/source/constructs/lib/v8/test/snapshot/__snapshots__/image-processing-stack.test.ts.snap +++ b/source/constructs/lib/v8/test/snapshot/__snapshots__/image-processing-stack.test.ts.snap @@ -878,7 +878,7 @@ exports[`ImageProcessingStack Snapshot Test 1`] = ` "FunctionCode": "// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -const FORMAT_PRIORITY = ['webp', 'avif', 'jpeg', 'png', 'heif', 'tiff', 'raw', 'gif']; +const FORMAT_PRIORITY = ['avif', 'webp', 'jpeg', 'png', 'heif', 'tiff', 'raw', 'gif']; const FORMAT_MAPPING = { 'image/webp': 'webp', diff --git a/source/constructs/lib/v8/test/unit/dit-function.test.ts b/source/constructs/lib/v8/test/unit/dit-function.test.ts index 12797445f..693e68707 100644 --- a/source/constructs/lib/v8/test/unit/dit-function.test.ts +++ b/source/constructs/lib/v8/test/unit/dit-function.test.ts @@ -164,7 +164,7 @@ describe("DIT CloudFront Function", () => { describe("Accept header normalization", () => { test("should select highest priority format from Accept header", async () => { const testCases = [ - { input: "image/avif,image/webp,image/png", expected: "image/webp" }, + { input: "image/avif,image/webp,image/png", expected: "image/avif" }, { input: "image/png,image/jpeg", expected: "image/jpeg" }, { input: "image/avif,image/heif", expected: "image/avif" }, { input: "image/gif", expected: "image/gif" }, diff --git a/source/container/src/services/transformation-resolver/auto-optimization/auto-optimizer.test.ts b/source/container/src/services/transformation-resolver/auto-optimization/auto-optimizer.test.ts index 513725e41..3cd6b335c 100644 --- a/source/container/src/services/transformation-resolver/auto-optimization/auto-optimizer.test.ts +++ b/source/container/src/services/transformation-resolver/auto-optimization/auto-optimizer.test.ts @@ -46,7 +46,7 @@ describe('applyAutoOptimizations', () => { }); }); - it('should prioritize formats by priority order (webp, avif, jpeg, png)', () => { + it('should prioritize formats by priority order (avif, webp, jpeg, png)', () => { mockPolicy.outputs = [{ type: 'format', value: 'auto' }]; mockRequest.headers = { 'dit-accept': 'image/jpeg,image/avif,image/avif,*/*' }; @@ -56,6 +56,17 @@ describe('applyAutoOptimizations', () => { expect(result[0].value).toBe('avif'); }); + it('should prefer avif over webp when both are accepted', () => { + mockPolicy.outputs = [{ type: 'format', value: 'auto' }]; + mockRequest.headers = { 'dit-accept': 'image/avif,image/webp' }; + const imageRequest = { sourceImageContentType: 'image/jpeg' } as ImageProcessingRequest; + + const result = applyAutoOptimizations(baseTransformations, mockRequest as Request, mockPolicy, imageRequest); + + expect(result).toHaveLength(1); + expect(result[0]).toEqual({ type: 'format', value: 'avif', source: 'auto' }); + }); + it('should apply static format when policy format is not auto', () => { mockPolicy.outputs = [{ type: 'format', value: 'jpeg' }]; mockRequest.headers = { 'dit-accept': 'image/webp,*/*' }; diff --git a/source/container/src/services/transformation-resolver/auto-optimization/auto-optimizer.ts b/source/container/src/services/transformation-resolver/auto-optimization/auto-optimizer.ts index e12f7955d..9d730a1f5 100644 --- a/source/container/src/services/transformation-resolver/auto-optimization/auto-optimizer.ts +++ b/source/container/src/services/transformation-resolver/auto-optimization/auto-optimizer.ts @@ -5,7 +5,7 @@ import { Request } from 'express'; import { Transformation, TransformationPolicy } from '../../../types/transformation'; import { ImageProcessingRequest } from '../../../types/image-processing-request'; -const FORMAT_PRIORITY = ['webp', 'avif', 'jpeg', 'png', 'heif', 'tiff', 'raw', 'gif']; +const FORMAT_PRIORITY = ['avif', 'webp', 'jpeg', 'png', 'heif', 'tiff', 'raw', 'gif']; // TODO, DISCUSS WITH TEAM FOR OPTIMAL FORMAT PRIORITIY LIST const ANIMATION_CAPABLE_FORMATS = new Set(['webp', 'avif', 'gif']); const FORMAT_MAPPING: Record = {