Skip to content

[15.5.x] Re-enable AVIF image optimization with a runtime libheif version guard - #97954

Merged
eps1lon merged 5 commits into
next-15-5from
sebbie/backport-97931-to-next-15-5
Aug 31, 2026
Merged

eps1lon merged 5 commits into
next-15-5from
sebbie/backport-97931-to-next-15-5

Conversation

@eps1lon

@eps1lon eps1lon commented Aug 26, 2026 •

Copy link
Copy Markdown
Member

Backports #97931
Part of https://linear.app/vercel/issue/VOC-34654/

Since 15.x supports a Node.js version not supported by a secure sharp version, we have to conditionally block AVIF optimization based on the used libheif version. I added a test that runs for each support major sharp version to validate only the fixed version optimizes AVIF.

@github-actions

github-actions Bot commented Aug 26, 2026 •

Copy link
Copy Markdown
Contributor

Failing test suites

Commit: ac65ec4 | About building and testing Next.js

pnpm test-start test/e2e/app-dir/ppr-partial-hydration/ppr-partial-hydration.test.ts (job)

  • PPR - partial hydration > Static shell, no streaming metadata > should hydrate the shell without waiting for slow suspense boundaries (DD)
  • PPR - partial hydration > Static shell, streaming metadata > should hydrate the shell without waiting for slow suspense boundaries (DD)
Expand output

● PPR - partial hydration › Static shell, no streaming metadata › should hydrate the shell without waiting for slow suspense boundaries

page.waitForSelector: Timeout 10ms exceeded.
Call log:
  - waiting for locator('#shell-hydrated') to be visible
  -   locator resolved to visible <div id="shell-hydrated" data-is-hydrated="true">🟢 Hydrated</div>

  491 |
  492 |     return this.startChain(async () => {
> 493 |       const el = await page.waitForSelector(selector, {
      |                             ^
  494 |         timeout,
  495 |         state,
  496 |       })

  at waitForSelector (lib/browsers/playwright.ts:493:29)
  at Playwright._chain (lib/browsers/playwright.ts:616:23)
  at Playwright._chain [as startChain] (lib/browsers/playwright.ts:597:17)
  at Playwright.startChain [as waitForElementByCss] (lib/browsers/playwright.ts:492:17)
  at Playwright.waitForElementByCss (lib/browsers/playwright.ts:398:17)
  at elementByCssInstant (e2e/app-dir/ppr-partial-hydration/ppr-partial-hydration.test.ts:75:14)
  at fn (lib/next-test-utils.ts:845:20)
  at Object.<anonymous> (e2e/app-dir/ppr-partial-hydration/ppr-partial-hydration.test.ts:71:7)
  at Proxy._chain (lib/browsers/playwright.ts:616:23)
  at Proxy._chain (lib/browsers/playwright.ts:592:17)
  at Proxy.continueChain (lib/browsers/playwright.ts:440:17)
  at getAttribute (e2e/app-dir/ppr-partial-hydration/ppr-partial-hydration.test.ts:76:14)
  at fn (lib/next-test-utils.ts:845:20)
  at Object.<anonymous> (e2e/app-dir/ppr-partial-hydration/ppr-partial-hydration.test.ts:71:7)

● PPR - partial hydration › Static shell, streaming metadata › should hydrate the shell without waiting for slow suspense boundaries

expect(received).toHaveLength(expected)

Expected length: 0
Received length: 1
Received array:  [{"_guid": "handle@93518a7147a7c3401e24ab07931186d8", "_type": "ElementHandle"}]

  57 |
  58 |           // The dynamic content hasn't streamed in yet, we should only see the fallback
> 59 |           expect(await browser.elementsByCss('main #dynamic')).toHaveLength(0)
     |                                                                ^
  60 |           expect(
  61 |             await browser
  62 |               .elementByCssInstant('#dynamic-fallback', { state: 'visible' })

  at toHaveLength (e2e/app-dir/ppr-partial-hydration/ppr-partial-hydration.test.ts:59:64)
  at retry (lib/next-test-utils.ts:845:14)
  at Object.<anonymous> (e2e/app-dir/ppr-partial-hydration/ppr-partial-hydration.test.ts:48:7)

@eps1lon eps1lon changed the title [backport] Re-enable AVIF image optimization with a runtime libheif version guard [15.5.x] Re-enable AVIF image optimization with a runtime libheif version guard Aug 26, 2026
Comment thread packages/next/src/server/image-optimizer.ts
@eps1lon
eps1lon force-pushed the sebbie/backport-97931-to-next-15-5 branch from 890bb4e to 587c966 Compare August 26, 2026 20:35
styfle
styfle previously approved these changes Aug 26, 2026
@eps1lon
eps1lon dismissed styfle’s stale review August 26, 2026 20:43

not meant to be reviewed

@eps1lon
eps1lon force-pushed the sebbie/backport-97931-to-next-15-5 branch 8 times, most recently from 77ae312 to f0415c2 Compare August 27, 2026 17:39
@eps1lon
eps1lon force-pushed the sebbie/backport-97931-to-next-15-5 branch 3 times, most recently from ac7eb17 to 8448b01 Compare August 29, 2026 20:39
Comment thread packages/next/src/server/image-optimizer.ts Outdated
@eps1lon
eps1lon force-pushed the sebbie/backport-97931-to-next-15-5 branch 8 times, most recently from 76da755 to 28f8c95 Compare August 31, 2026 14:54
@eps1lon
eps1lon marked this pull request as ready for review August 31, 2026 15:47
@eps1lon
eps1lon requested a review from styfle August 31, 2026 15:47
it('should bypass optimization for avif input', async () => {
const query = { url: '/test.avif', w: ctx.w, q: ctx.q }
it('should resize avif', async () => {
const query = { url: '/test.avif', w: ctx.w, q: 75 }

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to hardcode q here?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed the hardcoding which got reintroduced by reverting. It was hardcoded before we disabled AVIF.

it('should bypass avif input when avif output is enabled', async () => {
const query = { url: '/test.avif', w: ctx.w, q: ctx.q }
it('should resize avif and maintain format', async () => {
const query = { url: '/test.avif', w: ctx.w, q: 75 }

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same question - Do we need to hardcode q here?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed the hardcoding which got reintroduced by reverting. It was hardcoded before we disabled AVIF.

@eps1lon
eps1lon force-pushed the sebbie/backport-97931-to-next-15-5 branch from 28f8c95 to ac65ec4 Compare August 31, 2026 16:56
Comment thread packages/next/src/server/image-optimizer.ts
@eps1lon
eps1lon enabled auto-merge (squash) August 31, 2026 18:24
@eps1lon
eps1lon disabled auto-merge August 31, 2026 18:55
@eps1lon

eps1lon commented Aug 31, 2026

Copy link
Copy Markdown
Member Author

Flaky test. Force-merging.

@eps1lon
eps1lon merged commit d64c0d1 into next-15-5 Aug 31, 2026
637 of 654 checks passed
@eps1lon
eps1lon deleted the sebbie/backport-97931-to-next-15-5 branch August 31, 2026 18:56
@github-actions github-actions Bot locked as resolved and limited conversation to collaborators Sep 15, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants