Skip to content

Commit

Permalink
Bypass image optimization for vector images (#18179)
Browse files Browse the repository at this point in the history
Previously, vector images like svg were being converted to webp and resized.

However, vector images already handle any size so we can bypass the same we do for animated images.

Related to #18122
  • Loading branch information
styfle authored Oct 24, 2020
1 parent d4397d8 commit 0dff7de
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 20 deletions.
23 changes: 12 additions & 11 deletions packages/next/next-server/server/image-optimizer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@ const WEBP = 'image/webp'
const PNG = 'image/png'
const JPEG = 'image/jpeg'
const GIF = 'image/gif'
const SVG = 'image/svg+xml'
const MIME_TYPES = [/* AVIF, */ WEBP, PNG, JPEG]
const CACHE_VERSION = 1
const ANIMATABLE_TYPES = [WEBP, PNG, GIF]
const VECTOR_TYPES = [SVG]

export async function imageOptimizer(
server: Server,
Expand Down Expand Up @@ -200,21 +202,20 @@ export async function imageOptimizer(
}
}

const expireAt = maxAge * 1000 + now
let contentType: string

if (
upstreamType &&
ANIMATABLE_TYPES.includes(upstreamType) &&
isAnimated(upstreamBuffer)
) {
if (upstreamType) {
if (upstreamType) {
const vector = VECTOR_TYPES.includes(upstreamType)
const animate =
ANIMATABLE_TYPES.includes(upstreamType) && isAnimated(upstreamBuffer)
if (vector || animate) {
res.setHeader('Content-Type', upstreamType)
res.end(upstreamBuffer)
return { finished: true }
}
res.end(upstreamBuffer)
return { finished: true }
}

const expireAt = maxAge * 1000 + now
let contentType: string

if (mimeType) {
contentType = mimeType
} else if (upstreamType?.startsWith('image/') && getExtension(upstreamType)) {
Expand Down
23 changes: 14 additions & 9 deletions test/integration/image-optimizer/test/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,20 @@ function runTests({ w, isDev, domains }) {
expect(isAnimated(await res.buffer())).toBe(true)
})

it('should maintain vector svg', async () => {
const query = { w, q: 90, url: '/test.svg' }
const opts = { headers: { accept: 'image/webp' } }
const res = await fetchViaHTTP(appPort, '/_next/image', query, opts)
expect(res.status).toBe(200)
expect(res.headers.get('Content-Type')).toContain('image/svg+xml')
const actual = await res.text()
const expected = await fs.readFile(
join(__dirname, '..', 'public', 'test.svg'),
'utf8'
)
expect(actual).toMatch(expected)
})

it('should fail when url is missing', async () => {
const query = { w, q: 100 }
const res = await fetchViaHTTP(appPort, '/_next/image', query, {})
Expand Down Expand Up @@ -203,15 +217,6 @@ function runTests({ w, isDev, domains }) {
await expectWidth(res, w)
})

it('should resize relative url with invalid accept header as svg', async () => {
const query = { url: '/test.svg', w, q: 80 }
const opts = { headers: { accept: 'image/invalid' } }
const res = await fetchViaHTTP(appPort, '/_next/image', query, opts)
expect(res.status).toBe(200)
expect(res.headers.get('Content-Type')).toBe('image/svg+xml')
await expectWidth(res, w)
})

it('should resize relative url with invalid accept header as tiff', async () => {
const query = { url: '/test.tiff', w, q: 80 }
const opts = { headers: { accept: 'image/invalid' } }
Expand Down

0 comments on commit 0dff7de

Please sign in to comment.