From b9183fd68226a86183f900b884548f560ece7d3c Mon Sep 17 00:00:00 2001 From: Steven Date: Tue, 17 May 2022 10:37:16 -0400 Subject: [PATCH 1/8] Change experimental `layout=raw` to use native img lazy loading --- docs/api-reference/next/image.md | 14 +++++++------- packages/next/client/image.tsx | 15 +++++++++++---- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/docs/api-reference/next/image.md b/docs/api-reference/next/image.md index 043f2487963f0..bbf9d3c66a86e 100644 --- a/docs/api-reference/next/image.md +++ b/docs/api-reference/next/image.md @@ -75,13 +75,13 @@ The `` component accepts a number of additional properties beyond those The layout behavior of the image as the viewport changes size. -| `layout` | Behavior | `srcSet` | `sizes` | Has wrapper and sizer | -| ---------------------------------------- | ---------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- | -------- | --------------------- | -| `intrinsic` (default) | Scale *down* to fit width of container, up to image size | `1x`, `2x` (based on [imageSizes](#image-sizes)) | N/A | yes | -| `fixed` | Sized to `width` and `height` exactly | `1x`, `2x` (based on [imageSizes](#image-sizes)) | N/A | yes | -| `responsive` | Scale to fit width of container | `640w`, `750w`, ... `2048w`, `3840w` (based on [imageSizes](#image-sizes) and [deviceSizes](#device-sizes)) | `100vw` | yes | -| `fill` | Grow in both X and Y axes to fill container | `640w`, `750w`, ... `2048w`, `3840w` (based on [imageSizes](#image-sizes) and [deviceSizes](#device-sizes)) | `100vw` | yes | -| `raw`[\*](#experimental-raw-layout-mode) | Insert the image element with no automatic layout behavior | Behaves like `responsive` if the image has the `sizes` prop, and like `fixed` if it does not | optional | no | +| `layout` | Behavior | `srcSet` | `sizes` | Has wrapper and sizer | +| ---------------------------------------- | -------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- | -------- | --------------------- | +| `intrinsic` (default) | Scale *down* to fit width of container, up to image size | `1x`, `2x` (based on [imageSizes](#image-sizes)) | N/A | yes | +| `fixed` | Sized to `width` and `height` exactly | `1x`, `2x` (based on [imageSizes](#image-sizes)) | N/A | yes | +| `responsive` | Scale to fit width of container | `640w`, `750w`, ... `2048w`, `3840w` (based on [imageSizes](#image-sizes) and [deviceSizes](#device-sizes)) | `100vw` | yes | +| `fill` | Grow in both X and Y axes to fill container | `640w`, `750w`, ... `2048w`, `3840w` (based on [imageSizes](#image-sizes) and [deviceSizes](#device-sizes)) | `100vw` | yes | +| `raw`[\*](#experimental-raw-layout-mode) | Raw `` without styles and native lazy loading | Behaves like `responsive` if the image has the `sizes` prop, and like `fixed` if it does not | optional | no | - [Demo the `intrinsic` layout (default)](https://image-component.nextjs.gallery/layout-intrinsic) - When `intrinsic`, the image will scale the dimensions down for smaller viewports, but maintain the original dimensions for larger viewports. diff --git a/packages/next/client/image.tsx b/packages/next/client/image.tsx index 052e38fe58b61..996d813701451 100644 --- a/packages/next/client/image.tsx +++ b/packages/next/client/image.tsx @@ -467,7 +467,7 @@ export default function Image({ rootMargin: lazyBoundary, disabled: !isLazy, }) - const isVisible = !isLazy || isIntersected + const isVisible = !isLazy || isIntersected || layout === 'raw' const wrapperStyle: JSX.IntrinsicElements['span']['style'] = { boxSizing: 'border-box', @@ -571,6 +571,11 @@ export default function Image({ `Image with src "${src}" has "layout='raw'" and 'objectFit' or 'objectPosition'. For raw images, these and other styles should be specified using the 'style' attribute.` ) } + if (layout === 'raw' && (lazyRoot || lazyBoundary)) { + throw new Error( + `Image with src "${src}" has "layout='raw'" and 'lazyRoot' or 'lazyBoundary'. For raw images, native lazy loading is used so lazyRoot and lazyBoundary cannot be used.` + ) + } if ( sizes && layout !== 'fill' && @@ -677,7 +682,7 @@ export default function Image({ } } - const imgStyle = Object.assign({}, style, layout === 'raw' ? {} : layoutStyle) + const imgStyle = layout === 'raw' ? {} : Object.assign({}, style, layoutStyle) const blurStyle = placeholder === 'blur' && !blurComplete ? { @@ -882,7 +887,7 @@ const ImageElement = ({ blurStyle, isLazy, placeholder, - loading, + loading = 'lazy', srcString, config, unoptimized, @@ -904,6 +909,8 @@ const ImageElement = ({ decoding="async" data-nimg={layout} className={className} + // @ts-ignore - TODO: upgrade to `@types/react@17` + loading={layout === 'raw' ? loading : undefined} style={{ ...imgStyle, ...blurStyle }} ref={useCallback( (img: ImgElementWithDataProp) => { @@ -974,7 +981,7 @@ const ImageElement = ({ style={imgStyle} className={className} // @ts-ignore - TODO: upgrade to `@types/react@17` - loading={loading || 'lazy'} + loading={loading} /> )} From 14fbd12149b8c3868da40d6c4e39c6831be8e76c Mon Sep 17 00:00:00 2001 From: Steven Date: Tue, 17 May 2022 15:12:34 -0400 Subject: [PATCH 2/8] Add errors for lazyRoot/lazyBoundary --- packages/next/client/image.tsx | 30 +++++++++++++------ .../pages/invalid-raw-lazy-boundary.js | 19 ++++++++++++ .../default/test/index.test.js | 9 ++++++ 3 files changed, 49 insertions(+), 9 deletions(-) create mode 100644 test/integration/image-component/default/pages/invalid-raw-lazy-boundary.js diff --git a/packages/next/client/image.tsx b/packages/next/client/image.tsx index 996d813701451..bf2341d38cbe6 100644 --- a/packages/next/client/image.tsx +++ b/packages/next/client/image.tsx @@ -566,15 +566,27 @@ export default function Image({ `Image with src "${src}" has both "priority" and "loading='lazy'" properties. Only one should be used.` ) } - if (layout === 'raw' && (objectFit || objectPosition)) { - throw new Error( - `Image with src "${src}" has "layout='raw'" and 'objectFit' or 'objectPosition'. For raw images, these and other styles should be specified using the 'style' attribute.` - ) - } - if (layout === 'raw' && (lazyRoot || lazyBoundary)) { - throw new Error( - `Image with src "${src}" has "layout='raw'" and 'lazyRoot' or 'lazyBoundary'. For raw images, native lazy loading is used so lazyRoot and lazyBoundary cannot be used.` - ) + if (layout === 'raw') { + if (objectFit) { + throw new Error( + `Image with src "${src}" has "layout='raw'" and "objectFit='${objectFit}'". For raw images, these and other styles should be specified using the "style" attribute.` + ) + } + if (objectPosition) { + throw new Error( + `Image with src "${src}" has "layout='raw'" and "objectPosition='${objectPosition}'". For raw images, these and other styles should be specified using the "style" attribute.` + ) + } + if (lazyRoot) { + throw new Error( + `Image with src "${src}" has "layout='raw'" and "lazyRoot='${lazyRoot}'". For raw images, native lazy loading is used so "lazyRoot" cannot be used.` + ) + } + if (lazyBoundary) { + throw new Error( + `Image with src "${src}" has "layout='raw'" and "lazyBoundary='${lazyBoundary}'". For raw images, native lazy loading is used so "lazyBoundary" cannot be used.` + ) + } } if ( sizes && diff --git a/test/integration/image-component/default/pages/invalid-raw-lazy-boundary.js b/test/integration/image-component/default/pages/invalid-raw-lazy-boundary.js new file mode 100644 index 0000000000000..d1c2fc1ebddee --- /dev/null +++ b/test/integration/image-component/default/pages/invalid-raw-lazy-boundary.js @@ -0,0 +1,19 @@ +import React from 'react' +import Image from 'next/image' + +const Page = () => { + return ( +
+ +
+ ) +} + +export default Page diff --git a/test/integration/image-component/default/test/index.test.js b/test/integration/image-component/default/test/index.test.js index 27c206722d306..7d1a4a7328a03 100644 --- a/test/integration/image-component/default/test/index.test.js +++ b/test/integration/image-component/default/test/index.test.js @@ -862,6 +862,15 @@ function runTests(mode) { ) }) + it('should show error when layout=raw and lazyBoundary assigned', async () => { + const browser = await webdriver(appPort, '/invalid-raw-lazy-boundary') + + expect(await hasRedbox(browser)).toBe(true) + expect(await getRedboxHeader(browser)).toContain( + `Image with src "/test.jpg" has "layout='raw'" and "lazyBoundary='500px'". For raw images, native lazy loading is used so "lazyBoundary" cannot be used.` + ) + }) + it('should warn when img with layout=responsive is inside flex container', async () => { const browser = await webdriver(appPort, '/layout-responsive-inside-flex') await browser.eval(`document.getElementById("img").scrollIntoView()`) From 31997db649f9a398d5180a44ff434d65fda25e8a Mon Sep 17 00:00:00 2001 From: Steven Date: Tue, 17 May 2022 16:04:01 -0400 Subject: [PATCH 3/8] Add test for layout=raw placeholder=blur --- packages/next/client/image.tsx | 11 ++-- .../pages/layout-raw-placeholder-blur.js | 27 ++++++++ .../default/test/index.test.js | 61 +++++++++++++++++++ 3 files changed, 95 insertions(+), 4 deletions(-) create mode 100644 test/integration/image-component/default/pages/layout-raw-placeholder-blur.js diff --git a/packages/next/client/image.tsx b/packages/next/client/image.tsx index bf2341d38cbe6..db9ae4ade75fe 100644 --- a/packages/next/client/image.tsx +++ b/packages/next/client/image.tsx @@ -372,7 +372,7 @@ export default function Image({ priority = false, loading, lazyRoot = null, - lazyBoundary = '200px', + lazyBoundary, className, quality, width, @@ -464,10 +464,11 @@ export default function Image({ const [setIntersection, isIntersected, resetIntersected] = useIntersection({ rootRef: lazyRoot, - rootMargin: lazyBoundary, + rootMargin: lazyBoundary || '200px', disabled: !isLazy, }) - const isVisible = !isLazy || isIntersected || layout === 'raw' + const isVisible = + !isLazy || isIntersected || (layout === 'raw' && placeholder !== 'blur') const wrapperStyle: JSX.IntrinsicElements['span']['style'] = { boxSizing: 'border-box', @@ -922,7 +923,9 @@ const ImageElement = ({ data-nimg={layout} className={className} // @ts-ignore - TODO: upgrade to `@types/react@17` - loading={layout === 'raw' ? loading : undefined} + loading={ + layout === 'raw' && placeholder !== 'blur' ? loading : undefined + } style={{ ...imgStyle, ...blurStyle }} ref={useCallback( (img: ImgElementWithDataProp) => { diff --git a/test/integration/image-component/default/pages/layout-raw-placeholder-blur.js b/test/integration/image-component/default/pages/layout-raw-placeholder-blur.js new file mode 100644 index 0000000000000..3b790fdc61e78 --- /dev/null +++ b/test/integration/image-component/default/pages/layout-raw-placeholder-blur.js @@ -0,0 +1,27 @@ +import React from 'react' +import Image from 'next/image' + +import testJPG from '../public/test.jpg' +import testPNG from '../public/test.png' + +const Page = () => { + return ( +
+

Layout Raw with Placeholder Blur

+

Scroll down...

+
+ +
+ +
Footer
+
+ ) +} + +export default Page diff --git a/test/integration/image-component/default/test/index.test.js b/test/integration/image-component/default/test/index.test.js index 7d1a4a7328a03..be614ed3f5d7c 100644 --- a/test/integration/image-component/default/test/index.test.js +++ b/test/integration/image-component/default/test/index.test.js @@ -713,6 +713,9 @@ function runTests(mode) { expect(await browser.elementById('raw1').getAttribute('srcset')).toBe( `/_next/image?url=%2Fwide.png&w=1200&q=75 1x, /_next/image?url=%2Fwide.png&w=3840&q=75 2x` ) + expect(await browser.elementById('raw1').getAttribute('loading')).toBe( + 'eager' + ) expect(await browser.elementById('raw2').getAttribute('style')).toBe( 'padding-left:4rem;width:100%;object-position:30% 30%' @@ -726,6 +729,9 @@ function runTests(mode) { expect(await browser.elementById('raw2').getAttribute('srcset')).toBe( `/_next/image?url=%2Fwide.png&w=16&q=75 16w, /_next/image?url=%2Fwide.png&w=32&q=75 32w, /_next/image?url=%2Fwide.png&w=48&q=75 48w, /_next/image?url=%2Fwide.png&w=64&q=75 64w, /_next/image?url=%2Fwide.png&w=96&q=75 96w, /_next/image?url=%2Fwide.png&w=128&q=75 128w, /_next/image?url=%2Fwide.png&w=256&q=75 256w, /_next/image?url=%2Fwide.png&w=384&q=75 384w, /_next/image?url=%2Fwide.png&w=640&q=75 640w, /_next/image?url=%2Fwide.png&w=750&q=75 750w, /_next/image?url=%2Fwide.png&w=828&q=75 828w, /_next/image?url=%2Fwide.png&w=1080&q=75 1080w, /_next/image?url=%2Fwide.png&w=1200&q=75 1200w, /_next/image?url=%2Fwide.png&w=1920&q=75 1920w, /_next/image?url=%2Fwide.png&w=2048&q=75 2048w, /_next/image?url=%2Fwide.png&w=3840&q=75 3840w` ) + expect(await browser.elementById('raw2').getAttribute('loading')).toBe( + 'lazy' + ) expect(await browser.elementById('raw3').getAttribute('style')).toBeNull() expect(await browser.elementById('raw3').getAttribute('srcset')).toBe( @@ -749,6 +755,61 @@ function runTests(mode) { } } }) + + it('should lazy load layout=raw and placeholder=blur', async () => { + const browser = await webdriver(appPort, '/layout-raw-placeholder-blur') + + // raw1 + expect(await browser.elementById('raw1').getAttribute('src')).toMatch( + 'data:image/' + ) + expect(await browser.elementById('raw1').getAttribute('srcset')).toBeNull() + expect(await browser.elementById('raw1').getAttribute('loading')).toBeNull() + expect(await browser.elementById('raw1').getAttribute('sizes')).toBeNull() + expect(await browser.elementById('raw1').getAttribute('style')).toMatch( + 'filter:blur(20px);background-size:cover;' + ) + expect(await browser.elementById('raw1').getAttribute('height')).toBe('400') + expect(await browser.elementById('raw1').getAttribute('width')).toBe('400') + await browser.eval(`document.getElementById("raw1").scrollIntoView()`) + expect(await browser.elementById('raw1').getAttribute('src')).toBe( + '/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Ftest.fab2915d.jpg&w=828&q=75' + ) + expect(await browser.elementById('raw1').getAttribute('srcset')).toBe( + '/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Ftest.fab2915d.jpg&w=640&q=75 1x, /_next/image?url=%2F_next%2Fstatic%2Fmedia%2Ftest.fab2915d.jpg&w=828&q=75 2x' + ) + expect(await browser.elementById('raw1').getAttribute('loading')).toBeNull() + expect(await browser.elementById('raw1').getAttribute('sizes')).toBeNull() + expect(await browser.elementById('raw1').getAttribute('style')).toBeNull() + expect(await browser.elementById('raw1').getAttribute('height')).toBe('400') + expect(await browser.elementById('raw1').getAttribute('width')).toBe('400') + + // raw2 + expect(await browser.elementById('raw2').getAttribute('src')).toMatch( + 'data:image/' + ) + expect(await browser.elementById('raw2').getAttribute('srcset')).toBeNull() + expect(await browser.elementById('raw2').getAttribute('loading')).toBeNull() + expect(await browser.elementById('raw2').getAttribute('sizes')).toBe('50vw') + expect(await browser.elementById('raw2').getAttribute('style')).toMatch( + 'filter:blur(20px);background-size:cover;' + ) + expect(await browser.elementById('raw2').getAttribute('height')).toBe('400') + expect(await browser.elementById('raw2').getAttribute('width')).toBe('400') + await browser.eval(`document.getElementById("raw1").scrollIntoView()`) + expect(await browser.elementById('raw2').getAttribute('src')).toBe( + '/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Ftest.fab2915d.jpg&w=828&q=75' + ) + expect(await browser.elementById('raw2').getAttribute('srcset')).toBe( + '/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Ftest.fab2915d.jpg&w=640&q=75 1x, /_next/image?url=%2F_next%2Fstatic%2Fmedia%2Ftest.fab2915d.jpg&w=828&q=75 2x' + ) + expect(await browser.elementById('raw2').getAttribute('sizes')).toBe('50vw') + expect(await browser.elementById('raw2').getAttribute('loading')).toBeNull() + expect(await browser.elementById('raw2').getAttribute('style')).toBeNull() + expect(await browser.elementById('raw2').getAttribute('height')).toBe('400') + expect(await browser.elementById('raw2').getAttribute('width')).toBe('400') + }) + it('should handle the styles prop appropriately', async () => { let browser try { From aaad40989edd799781ac6f22ec6af7d89da744be Mon Sep 17 00:00:00 2001 From: Steven Date: Tue, 17 May 2022 16:17:54 -0400 Subject: [PATCH 4/8] Fix tests --- .../default/test/index.test.js | 26 ++++++++++++++----- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/test/integration/image-component/default/test/index.test.js b/test/integration/image-component/default/test/index.test.js index be614ed3f5d7c..5b76208df9905 100644 --- a/test/integration/image-component/default/test/index.test.js +++ b/test/integration/image-component/default/test/index.test.js @@ -771,7 +771,13 @@ function runTests(mode) { ) expect(await browser.elementById('raw1').getAttribute('height')).toBe('400') expect(await browser.elementById('raw1').getAttribute('width')).toBe('400') - await browser.eval(`document.getElementById("raw1").scrollIntoView()`) + await browser.eval( + `document.getElementById("raw1").scrollIntoView({behavior: "smooth"})` + ) + await check( + () => browser.eval(`document.getElementById("raw1").currentSrc`), + /test(.*)jpg/ + ) expect(await browser.elementById('raw1').getAttribute('src')).toBe( '/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Ftest.fab2915d.jpg&w=828&q=75' ) @@ -780,7 +786,7 @@ function runTests(mode) { ) expect(await browser.elementById('raw1').getAttribute('loading')).toBeNull() expect(await browser.elementById('raw1').getAttribute('sizes')).toBeNull() - expect(await browser.elementById('raw1').getAttribute('style')).toBeNull() + expect(await browser.elementById('raw1').getAttribute('style')).toBe('') expect(await browser.elementById('raw1').getAttribute('height')).toBe('400') expect(await browser.elementById('raw1').getAttribute('width')).toBe('400') @@ -790,22 +796,28 @@ function runTests(mode) { ) expect(await browser.elementById('raw2').getAttribute('srcset')).toBeNull() expect(await browser.elementById('raw2').getAttribute('loading')).toBeNull() - expect(await browser.elementById('raw2').getAttribute('sizes')).toBe('50vw') + expect(await browser.elementById('raw2').getAttribute('sizes')).toBeNull() expect(await browser.elementById('raw2').getAttribute('style')).toMatch( 'filter:blur(20px);background-size:cover;' ) expect(await browser.elementById('raw2').getAttribute('height')).toBe('400') expect(await browser.elementById('raw2').getAttribute('width')).toBe('400') - await browser.eval(`document.getElementById("raw1").scrollIntoView()`) + await browser.eval( + `document.getElementById("raw2").scrollIntoView({behavior: "smooth"})` + ) + await check( + () => browser.eval(`document.getElementById("raw2").currentSrc`), + /test(.*)png/ + ) expect(await browser.elementById('raw2').getAttribute('src')).toBe( - '/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Ftest.fab2915d.jpg&w=828&q=75' + '/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Ftest.3f1a293b.png&w=3840&q=75' ) expect(await browser.elementById('raw2').getAttribute('srcset')).toBe( - '/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Ftest.fab2915d.jpg&w=640&q=75 1x, /_next/image?url=%2F_next%2Fstatic%2Fmedia%2Ftest.fab2915d.jpg&w=828&q=75 2x' + '/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Ftest.3f1a293b.png&w=384&q=75 384w, /_next/image?url=%2F_next%2Fstatic%2Fmedia%2Ftest.3f1a293b.png&w=640&q=75 640w, /_next/image?url=%2F_next%2Fstatic%2Fmedia%2Ftest.3f1a293b.png&w=750&q=75 750w, /_next/image?url=%2F_next%2Fstatic%2Fmedia%2Ftest.3f1a293b.png&w=828&q=75 828w, /_next/image?url=%2F_next%2Fstatic%2Fmedia%2Ftest.3f1a293b.png&w=1080&q=75 1080w, /_next/image?url=%2F_next%2Fstatic%2Fmedia%2Ftest.3f1a293b.png&w=1200&q=75 1200w, /_next/image?url=%2F_next%2Fstatic%2Fmedia%2Ftest.3f1a293b.png&w=1920&q=75 1920w, /_next/image?url=%2F_next%2Fstatic%2Fmedia%2Ftest.3f1a293b.png&w=2048&q=75 2048w, /_next/image?url=%2F_next%2Fstatic%2Fmedia%2Ftest.3f1a293b.png&w=3840&q=75 3840w' ) expect(await browser.elementById('raw2').getAttribute('sizes')).toBe('50vw') expect(await browser.elementById('raw2').getAttribute('loading')).toBeNull() - expect(await browser.elementById('raw2').getAttribute('style')).toBeNull() + expect(await browser.elementById('raw2').getAttribute('style')).toBe('') expect(await browser.elementById('raw2').getAttribute('height')).toBe('400') expect(await browser.elementById('raw2').getAttribute('width')).toBe('400') }) From 5640d272f604060c1f85fa097725aa38a63d1086 Mon Sep 17 00:00:00 2001 From: Steven Date: Tue, 17 May 2022 16:59:58 -0400 Subject: [PATCH 5/8] Revert unnecessary style object assign --- packages/next/client/image.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/next/client/image.tsx b/packages/next/client/image.tsx index db9ae4ade75fe..7e82fecc45787 100644 --- a/packages/next/client/image.tsx +++ b/packages/next/client/image.tsx @@ -695,7 +695,7 @@ export default function Image({ } } - const imgStyle = layout === 'raw' ? {} : Object.assign({}, style, layoutStyle) + const imgStyle = Object.assign({}, style, layout === 'raw' ? {} : layoutStyle) const blurStyle = placeholder === 'blur' && !blurComplete ? { From ee1d56cf2c4a6cb23ce5239688425ae72a51dc6f Mon Sep 17 00:00:00 2001 From: Steven Date: Tue, 17 May 2022 17:49:59 -0400 Subject: [PATCH 6/8] Don't special case placeholder=blur --- packages/next/client/image.tsx | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/packages/next/client/image.tsx b/packages/next/client/image.tsx index 7e82fecc45787..8de739f2b6685 100644 --- a/packages/next/client/image.tsx +++ b/packages/next/client/image.tsx @@ -467,8 +467,7 @@ export default function Image({ rootMargin: lazyBoundary || '200px', disabled: !isLazy, }) - const isVisible = - !isLazy || isIntersected || (layout === 'raw' && placeholder !== 'blur') + const isVisible = !isLazy || isIntersected || layout === 'raw' const wrapperStyle: JSX.IntrinsicElements['span']['style'] = { boxSizing: 'border-box', @@ -923,9 +922,7 @@ const ImageElement = ({ data-nimg={layout} className={className} // @ts-ignore - TODO: upgrade to `@types/react@17` - loading={ - layout === 'raw' && placeholder !== 'blur' ? loading : undefined - } + loading={layout === 'raw' ? loading : undefined} style={{ ...imgStyle, ...blurStyle }} ref={useCallback( (img: ImgElementWithDataProp) => { From 4262a133db1f0e071b8cfd0075e4205ce0835426 Mon Sep 17 00:00:00 2001 From: Steven Date: Tue, 17 May 2022 18:18:16 -0400 Subject: [PATCH 7/8] Fix tests --- .../default/test/index.test.js | 36 ++++++++++++------- 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/test/integration/image-component/default/test/index.test.js b/test/integration/image-component/default/test/index.test.js index 5b76208df9905..2a0febd83130d 100644 --- a/test/integration/image-component/default/test/index.test.js +++ b/test/integration/image-component/default/test/index.test.js @@ -760,11 +760,15 @@ function runTests(mode) { const browser = await webdriver(appPort, '/layout-raw-placeholder-blur') // raw1 - expect(await browser.elementById('raw1').getAttribute('src')).toMatch( - 'data:image/' + expect(await browser.elementById('raw1').getAttribute('src')).toBe( + '/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Ftest.fab2915d.jpg&w=828&q=75' + ) + expect(await browser.elementById('raw1').getAttribute('srcset')).toBe( + '/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Ftest.fab2915d.jpg&w=640&q=75 1x, /_next/image?url=%2F_next%2Fstatic%2Fmedia%2Ftest.fab2915d.jpg&w=828&q=75 2x' + ) + expect(await browser.elementById('raw1').getAttribute('loading')).toBe( + 'lazy' ) - expect(await browser.elementById('raw1').getAttribute('srcset')).toBeNull() - expect(await browser.elementById('raw1').getAttribute('loading')).toBeNull() expect(await browser.elementById('raw1').getAttribute('sizes')).toBeNull() expect(await browser.elementById('raw1').getAttribute('style')).toMatch( 'filter:blur(20px);background-size:cover;' @@ -784,19 +788,25 @@ function runTests(mode) { expect(await browser.elementById('raw1').getAttribute('srcset')).toBe( '/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Ftest.fab2915d.jpg&w=640&q=75 1x, /_next/image?url=%2F_next%2Fstatic%2Fmedia%2Ftest.fab2915d.jpg&w=828&q=75 2x' ) - expect(await browser.elementById('raw1').getAttribute('loading')).toBeNull() + expect(await browser.elementById('raw1').getAttribute('loading')).toBe( + 'lazy' + ) expect(await browser.elementById('raw1').getAttribute('sizes')).toBeNull() - expect(await browser.elementById('raw1').getAttribute('style')).toBe('') + expect(await browser.elementById('raw1').getAttribute('style')).toMatch('') expect(await browser.elementById('raw1').getAttribute('height')).toBe('400') expect(await browser.elementById('raw1').getAttribute('width')).toBe('400') // raw2 - expect(await browser.elementById('raw2').getAttribute('src')).toMatch( - 'data:image/' + expect(await browser.elementById('raw2').getAttribute('src')).toBe( + '/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Ftest.3f1a293b.png&w=3840&q=75' + ) + expect(await browser.elementById('raw2').getAttribute('srcset')).toBe( + '/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Ftest.3f1a293b.png&w=384&q=75 384w, /_next/image?url=%2F_next%2Fstatic%2Fmedia%2Ftest.3f1a293b.png&w=640&q=75 640w, /_next/image?url=%2F_next%2Fstatic%2Fmedia%2Ftest.3f1a293b.png&w=750&q=75 750w, /_next/image?url=%2F_next%2Fstatic%2Fmedia%2Ftest.3f1a293b.png&w=828&q=75 828w, /_next/image?url=%2F_next%2Fstatic%2Fmedia%2Ftest.3f1a293b.png&w=1080&q=75 1080w, /_next/image?url=%2F_next%2Fstatic%2Fmedia%2Ftest.3f1a293b.png&w=1200&q=75 1200w, /_next/image?url=%2F_next%2Fstatic%2Fmedia%2Ftest.3f1a293b.png&w=1920&q=75 1920w, /_next/image?url=%2F_next%2Fstatic%2Fmedia%2Ftest.3f1a293b.png&w=2048&q=75 2048w, /_next/image?url=%2F_next%2Fstatic%2Fmedia%2Ftest.3f1a293b.png&w=3840&q=75 3840w' + ) + expect(await browser.elementById('raw2').getAttribute('sizes')).toBe('50vw') + expect(await browser.elementById('raw2').getAttribute('loading')).toBe( + 'lazy' ) - expect(await browser.elementById('raw2').getAttribute('srcset')).toBeNull() - expect(await browser.elementById('raw2').getAttribute('loading')).toBeNull() - expect(await browser.elementById('raw2').getAttribute('sizes')).toBeNull() expect(await browser.elementById('raw2').getAttribute('style')).toMatch( 'filter:blur(20px);background-size:cover;' ) @@ -816,7 +826,9 @@ function runTests(mode) { '/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Ftest.3f1a293b.png&w=384&q=75 384w, /_next/image?url=%2F_next%2Fstatic%2Fmedia%2Ftest.3f1a293b.png&w=640&q=75 640w, /_next/image?url=%2F_next%2Fstatic%2Fmedia%2Ftest.3f1a293b.png&w=750&q=75 750w, /_next/image?url=%2F_next%2Fstatic%2Fmedia%2Ftest.3f1a293b.png&w=828&q=75 828w, /_next/image?url=%2F_next%2Fstatic%2Fmedia%2Ftest.3f1a293b.png&w=1080&q=75 1080w, /_next/image?url=%2F_next%2Fstatic%2Fmedia%2Ftest.3f1a293b.png&w=1200&q=75 1200w, /_next/image?url=%2F_next%2Fstatic%2Fmedia%2Ftest.3f1a293b.png&w=1920&q=75 1920w, /_next/image?url=%2F_next%2Fstatic%2Fmedia%2Ftest.3f1a293b.png&w=2048&q=75 2048w, /_next/image?url=%2F_next%2Fstatic%2Fmedia%2Ftest.3f1a293b.png&w=3840&q=75 3840w' ) expect(await browser.elementById('raw2').getAttribute('sizes')).toBe('50vw') - expect(await browser.elementById('raw2').getAttribute('loading')).toBeNull() + expect(await browser.elementById('raw2').getAttribute('loading')).toBe( + 'lazy' + ) expect(await browser.elementById('raw2').getAttribute('style')).toBe('') expect(await browser.elementById('raw2').getAttribute('height')).toBe('400') expect(await browser.elementById('raw2').getAttribute('width')).toBe('400') From 984ed956ade431b9b617bec19a513cc6b69cbf12 Mon Sep 17 00:00:00 2001 From: Steven Date: Wed, 18 May 2022 16:26:13 -0400 Subject: [PATCH 8/8] Fix test --- .../default/pages/layout-raw-placeholder-blur.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/integration/image-component/default/pages/layout-raw-placeholder-blur.js b/test/integration/image-component/default/pages/layout-raw-placeholder-blur.js index 3b790fdc61e78..e0d46ca5e32a5 100644 --- a/test/integration/image-component/default/pages/layout-raw-placeholder-blur.js +++ b/test/integration/image-component/default/pages/layout-raw-placeholder-blur.js @@ -9,9 +9,9 @@ const Page = () => {

Layout Raw with Placeholder Blur

Scroll down...

-
+
-
+