Skip to content

Commit

Permalink
Fix next/image blur placeholder when JS is disabled (#28269)
Browse files Browse the repository at this point in the history
This PR does a few things:

- Moves `<noscript>` usage below the blur image since so that the `<noscript>` image renders on top of the blur image
- Remove the `isVisible` check for `<noscript>` since we can't rely on client-side JS
- Add `loading=lazy` to the `<noscript>` image to take advantage of native lazy loading (can't rely on JS lazy loading)

Fixes #28251
  • Loading branch information
styfle committed Aug 19, 2021
1 parent f2fa4f3 commit 53f0973
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 22 deletions.
40 changes: 20 additions & 20 deletions packages/next/client/image.tsx
Expand Up @@ -597,26 +597,6 @@ export default function Image({
) : null}
</div>
) : null}
{!isVisible && (
<noscript>
<img
{...rest}
{...generateImgAttrs({
src,
unoptimized,
layout,
width: widthInt,
quality: qualityInt,
sizes,
loader,
})}
decoding="async"
data-nimg
style={imgStyle}
className={className}
/>
</noscript>
)}
<img
{...rest}
{...imgAttributes}
Expand All @@ -629,6 +609,26 @@ export default function Image({
}}
style={{ ...imgStyle, ...blurStyle }}
/>
<noscript>
<img
{...rest}
{...generateImgAttrs({
src,
unoptimized,
layout,
width: widthInt,
quality: qualityInt,
sizes,
loader,
})}
decoding="async"
data-nimg
style={imgStyle}
className={className}
loading={loading || 'lazy'}
/>
</noscript>

{priority ? (
// Note how we omit the `href` attribute, as it would only be relevant
// for browsers that do not support `imagesrcset`, and in those cases
Expand Down
5 changes: 5 additions & 0 deletions packages/next/types/index.d.ts
Expand Up @@ -40,6 +40,11 @@ declare module 'react' {
interface LinkHTMLAttributes<T> extends HTMLAttributes<T> {
nonce?: string
}

// <img loading="lazy"> support
interface ImgHTMLAttributes<T> extends HTMLAttributes<T> {
loading?: 'auto' | 'eager' | 'lazy'
}
}

export type Redirect =
Expand Down
2 changes: 1 addition & 1 deletion test/integration/export-image-loader/test/index.test.js
Expand Up @@ -74,7 +74,7 @@ describe('Export with custom loader next/image component', () => {
it('should contain img element with same src in html output', async () => {
const html = await fs.readFile(join(outdir, 'index.html'))
const $ = cheerio.load(html)
expect($('img[alt="icon"]').attr('src')).toBe('/custom/i.png')
expect($('img[src="/custom/o.png"]')).toBeDefined()
})

afterAll(async () => {
Expand Down
Expand Up @@ -151,7 +151,7 @@ function runTests(mode) {
const els = [].slice.apply($html('img'))
expect(els.length).toBe(2)

const [noscriptEl, el] = els
const [el, noscriptEl] = els
expect(noscriptEl.attribs.src).toBeDefined()
expect(noscriptEl.attribs.srcset).toBeDefined()

Expand Down

0 comments on commit 53f0973

Please sign in to comment.