Skip to content

Commit

Permalink
fix: skip resizing image if it's animated (#39325)
Browse files Browse the repository at this point in the history
We were resizing animated images when importing them, but we don't optimize images when they come from an upstream provider. For consistency, we can skip resizing for local animated images as well.

Fixes #39317

## Bug

- [ ] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [ ] Errors have helpful link attached, see `contributing.md`

## Feature

- [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR.
- [ ] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [ ] Documentation added
- [ ] Telemetry added. In case of a feature if it's used or not.
- [ ] Errors have helpful link attached, see `contributing.md`

## Documentation / Examples

- [ ] Make sure the linting passes by running `pnpm lint`
- [ ] The examples guidelines are followed from [our contributing doc](https://github.com/vercel/next.js/blob/canary/contributing.md#adding-examples)
  • Loading branch information
balazsorban44 committed Aug 5, 2022
1 parent 442378d commit d008f65
Show file tree
Hide file tree
Showing 8 changed files with 47 additions and 18 deletions.
5 changes: 3 additions & 2 deletions packages/next/server/image-optimizer.ts
Expand Up @@ -4,7 +4,6 @@ import { promises } from 'fs'
import { getOrientation, Orientation } from 'next/dist/compiled/get-orientation'
import imageSizeOf from 'next/dist/compiled/image-size'
import { IncomingMessage, ServerResponse } from 'http'
// @ts-ignore no types for is-animated
import isAnimated from 'next/dist/compiled/is-animated'
import contentDisposition from 'next/dist/compiled/content-disposition'
import { join } from 'path'
Expand Down Expand Up @@ -726,7 +725,9 @@ export async function resizeImage(
extension: 'avif' | 'webp' | 'png' | 'jpeg',
quality: number
): Promise<Buffer> {
if (sharp) {
if (isAnimated(content)) {
return content
} else if (sharp) {
const transformer = sharp(content)

if (extension === 'avif') {
Expand Down
4 changes: 4 additions & 0 deletions packages/next/types/misc.d.ts
Expand Up @@ -367,3 +367,7 @@ declare module 'next/dist/compiled/watchpack' {

export default Watchpack
}

declare module 'next/dist/compiled/is-animated' {
export default function isAnimated(buffer: Buffer): boolean
}
37 changes: 32 additions & 5 deletions test/integration/image-optimizer/app/pages/index.js
@@ -1,13 +1,40 @@
import Image from 'next/image'
import Logo from '../public/test.jpg'

function Home() {
import img1 from '../public/animated2.png'
import img2 from '../public/äöüščří.png'
import img3 from '../public/test.avif'
import img4 from '../public/test.jpg'
import img5 from '../public/test.webp'
import img6 from '../public/animated.gif'
import img7 from '../public/grayscale.png'
import img8 from '../public/test.bmp'
import img9 from '../public/test.png'
import img11 from '../public/animated.png'
import img12 from '../public/mountains.jpg'
import img13 from '../public/test.gif'
import img14 from '../public/test.svg'
import img15 from '../public/animated.webp'
import img17 from '../public/test.ico'

export default function Home() {
return (
<>
<h1>Image Optimizer Home</h1>
<Image src={Logo} />
<Image src={img1} />
<Image src={img2} />
<Image src={img3} />
<Image src={img4} />
<Image src={img5} />
<Image src={img6} />
<Image src={img7} />
<Image src={img8} />
<Image src={img9} />
<Image src={img11} />
<Image src={img12} />
<Image src={img13} />
<Image src={img14} />
<Image src={img15} />
<Image src={img17} />
</>
)
}

export default Home
Expand Up @@ -374,7 +374,7 @@ describe('Image Optimizer', () => {
describe('Server support for minimumCacheTTL in next.config.js', () => {
const size = 96 // defaults defined in server/config.ts
const dangerouslyAllowSVG = true
const ctx = {
const ctx: any = {
w: size,
isDev: false,
domains,
Expand Down
Expand Up @@ -40,11 +40,8 @@ export async function serveSlowImage() {
res.end(await fs.readFile(join(__dirname, '../app/public/test.png')))
})

await new Promise((resolve, reject) => {
server.listen(port, (err) => {
if (err) return reject(err)
resolve()
})
await new Promise((resolve) => {
server.listen(port, () => resolve(true))
})
console.log(`Started slow image server at ::${port}`)
return {
Expand Down Expand Up @@ -129,7 +126,7 @@ async function fetchWithDuration(...args) {

export function runTests(ctx) {
const { isDev, minimumCacheTTL = 60 } = ctx
let slowImageServer
let slowImageServer: Awaited<ReturnType<typeof serveSlowImage>>
beforeAll(async () => {
slowImageServer = await serveSlowImage()
})
Expand Down Expand Up @@ -1248,7 +1245,7 @@ export const setupTests = (ctx) => {
await cleanImagesDir(ctx)
})
afterAll(async () => {
await killApp(curCtx.app)
if (curCtx.app) await killApp(curCtx.app)
})

runTests(curCtx)
Expand Down Expand Up @@ -1288,8 +1285,8 @@ export const setupTests = (ctx) => {
})
})
afterAll(async () => {
await killApp(curCtx.app)
nextConfig.restore()
if (curCtx.app) await killApp(curCtx.app)
})

runTests(curCtx)
Expand Down Expand Up @@ -1321,7 +1318,7 @@ export const setupTests = (ctx) => {
})
})
afterAll(async () => {
await killApp(curCtx.app)
if (curCtx.app) await killApp(curCtx.app)
})

runTests(curCtx)
Expand Down Expand Up @@ -1362,8 +1359,8 @@ export const setupTests = (ctx) => {
})
})
afterAll(async () => {
await killApp(curCtx.app)
nextConfig.restore()
if (curCtx.app) await killApp(curCtx.app)
})

runTests(curCtx)
Expand Down

0 comments on commit d008f65

Please sign in to comment.