From 274f8d09c4af3a91114f429cf9ade0251614319d Mon Sep 17 00:00:00 2001 From: Joon Park Date: Tue, 13 Apr 2021 15:29:40 -0500 Subject: [PATCH 1/7] Add blurry placeholder feature to next/image As the server side functionality is not yet implemented, the only way to currently test the feature is to provide your own blurry image data URL manually (this is how the integration test is written). The feature is currently behind the experimental.imagePlaceholder config value. --- packages/next/build/webpack-config.ts | 1 + packages/next/client/image.tsx | 52 ++++++++++++++++++- .../next/next-server/server/config-shared.ts | 4 +- .../next/next-server/server/image-config.ts | 7 +++ .../default/pages/blurry-placeholder.js | 19 +++++++ .../default/test/index.test.js | 28 +++++++++- 6 files changed, 108 insertions(+), 3 deletions(-) create mode 100644 test/integration/image-component/default/pages/blurry-placeholder.js diff --git a/packages/next/build/webpack-config.ts b/packages/next/build/webpack-config.ts index c4906392837c3..a274efbf4ca65 100644 --- a/packages/next/build/webpack-config.ts +++ b/packages/next/build/webpack-config.ts @@ -1084,6 +1084,7 @@ export default async function getBaseWebpackConfig( domains: config.images.domains, } : {}), + placeholder: config.experimental.imagePlaceholder, }), 'process.env.__NEXT_ROUTER_BASEPATH': JSON.stringify(config.basePath), 'process.env.__NEXT_HAS_REWRITES': JSON.stringify(hasRewrites), diff --git a/packages/next/client/image.tsx b/packages/next/client/image.tsx index 8f8957740e655..c8cfe255ac88d 100644 --- a/packages/next/client/image.tsx +++ b/packages/next/client/image.tsx @@ -6,6 +6,7 @@ import { imageConfigDefault, LoaderValue, VALID_LOADERS, + PlaceholderValue, } from '../next-server/server/image-config' import { useIntersection } from './use-intersection' @@ -72,6 +73,13 @@ export type ImageProps = Omit< height: number | string layout?: Exclude } + ) & + ( + | { + placeholder?: Exclude + blurDataURL: never + } + | { placeholder: PlaceholderValue; blurDataURL: string } ) const { @@ -80,6 +88,7 @@ const { loader: configLoader, path: configPath, domains: configDomains, + placeholder: configPlaceholder, } = ((process.env.__NEXT_IMAGE_OPTS as any) as ImageConfig) || imageConfigDefault // sort smallest to largest @@ -209,6 +218,24 @@ function defaultImageLoader(loaderProps: ImageLoaderProps) { ) } +function removePlaceholder( + element: HTMLImageElement | null, + placeholder: PlaceholderValue +) { + const hasBlurryPlaceholder = + configPlaceholder === PlaceholderValue.BLURRY && + placeholder === PlaceholderValue.BLURRY + if (hasBlurryPlaceholder && element) { + if (element.complete) { + element.style.backgroundImage = 'none' + } else { + element.onload = () => { + element.style.backgroundImage = 'none' + } + } + } +} + export default function Image({ src, sizes, @@ -222,6 +249,8 @@ export default function Image({ objectFit, objectPosition, loader = defaultImageLoader, + placeholder = configPlaceholder, + blurDataURL, ...all }: ImageProps) { let rest: Partial = all @@ -291,6 +320,17 @@ export default function Image({ const heightInt = getInt(height) const qualityInt = getInt(quality) + const MIN_IMG_SIZE_FOR_PLACEHOLDER = 100 + const tooSmallForBlurryPlaceholder = + widthInt && heightInt + ? widthInt * heightInt < MIN_IMG_SIZE_FOR_PLACEHOLDER + : false + const shouldShowBlurryPlaceholder = + configPlaceholder === PlaceholderValue.BLURRY && + placeholder === PlaceholderValue.BLURRY && + priority && + (layout === 'fill' || !tooSmallForBlurryPlaceholder) + let wrapperStyle: JSX.IntrinsicElements['div']['style'] | undefined let sizerStyle: JSX.IntrinsicElements['div']['style'] | undefined let sizerSvg: string | undefined @@ -316,6 +356,13 @@ export default function Image({ objectFit, objectPosition, + + ...(shouldShowBlurryPlaceholder + ? { + backgroundSize: 'cover', + backgroundImage: `url("${blurDataURL}")`, + } + : undefined), } if ( typeof widthInt !== 'undefined' && @@ -462,7 +509,10 @@ export default function Image({ {...imgAttributes} decoding="async" className={className} - ref={setRef} + ref={(element) => { + setRef(element) + removePlaceholder(element, placeholder) + }} style={imgStyle} /> {priority ? ( diff --git a/packages/next/next-server/server/config-shared.ts b/packages/next/next-server/server/config-shared.ts index f508110d42948..a13aebf1da8a0 100644 --- a/packages/next/next-server/server/config-shared.ts +++ b/packages/next/next-server/server/config-shared.ts @@ -1,6 +1,6 @@ import os from 'os' import { Header, Redirect, Rewrite } from '../../lib/load-custom-routes' -import { imageConfigDefault } from './image-config' +import { imageConfigDefault, PlaceholderValue } from './image-config' export type DomainLocales = Array<{ http?: true @@ -60,6 +60,7 @@ export type NextConfig = { [key: string]: any } & { skipValidation?: boolean } turboMode: boolean + imagePlaceholder: PlaceholderValue } } @@ -115,6 +116,7 @@ export const defaultConfig: NextConfig = { externalDir: false, serialWebpackBuild: false, turboMode: false, + imagePlaceholder: PlaceholderValue.EMPTY, }, future: { strictPostcssConfiguration: false, diff --git a/packages/next/next-server/server/image-config.ts b/packages/next/next-server/server/image-config.ts index 5e60093067dd5..9ce1f767cbf88 100644 --- a/packages/next/next-server/server/image-config.ts +++ b/packages/next/next-server/server/image-config.ts @@ -7,12 +7,18 @@ export const VALID_LOADERS = [ export type LoaderValue = typeof VALID_LOADERS[number] +export enum PlaceholderValue { + EMPTY = 'empty', + BLURRY = 'blurry', +} + export type ImageConfig = { deviceSizes: number[] imageSizes: number[] loader: LoaderValue path: string domains?: string[] + placeholder: PlaceholderValue } export const imageConfigDefault: ImageConfig = { @@ -21,4 +27,5 @@ export const imageConfigDefault: ImageConfig = { path: '/_next/image', loader: 'default', domains: [], + placeholder: PlaceholderValue.EMPTY, } diff --git a/test/integration/image-component/default/pages/blurry-placeholder.js b/test/integration/image-component/default/pages/blurry-placeholder.js new file mode 100644 index 0000000000000..8b154214062f0 --- /dev/null +++ b/test/integration/image-component/default/pages/blurry-placeholder.js @@ -0,0 +1,19 @@ +import React from 'react' +import Image from 'next/image' + +export default function Page() { + return ( +
+

Blurry Placeholder

+ +
+ ) +} diff --git a/test/integration/image-component/default/test/index.test.js b/test/integration/image-component/default/test/index.test.js index cff2cc2508e67..7b887dc7e41c9 100644 --- a/test/integration/image-component/default/test/index.test.js +++ b/test/integration/image-component/default/test/index.test.js @@ -587,7 +587,10 @@ describe('Image Component Tests', () => { nextConfig, ` module.exports = { - target: 'serverless' + target: 'serverless', + experimental: { + imagePlaceholder: 'blurry', + }, } ` ) @@ -600,6 +603,29 @@ describe('Image Component Tests', () => { await killApp(app) }) + it('should have blurry placeholder when enabled', async () => { + const html = await renderViaHTTP(appPort, '/blurry-placeholder') + expect(html).toContain( + 'background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='400' height='400' viewBox='0 0 400 400'%3E%3Cfilter id='blur' filterUnits='userSpaceOnUse' color-interpolation-filters='sRGB'%3E%3CfeGaussianBlur stdDeviation='20' edgeMode='duplicate' /%3E%3CfeComponentTransfer%3E%3CfeFuncA type='discrete' tableValues='1 1' /%3E%3C/feComponentTransfer%3E%3C/filter%3E%3Cimage filter='url(%23blur)' href='data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAMDAwMDAwQEBAQFBQUFBQcHBgYHBwsICQgJCAsRCwwLCwwLEQ8SDw4PEg8bFRMTFRsfGhkaHyYiIiYwLTA+PlT/wAALCAAKAAoBAREA/8QAMwABAQEAAAAAAAAAAAAAAAAAAAcJEAABAwUAAwAAAAAAAAAAAAAFAAYRAQMEEyEVMlH/2gAIAQEAAD8Az1bLPaxhiuk0QdeCOLDtHixN2dmd2bsc5FPX7VTREX//2Q==' x='0' y='0' height='100%25' width='100%25'/%3E%3C/svg%3E")' + ) + }) + + it('should remove blurry placeholder after image loads', async () => { + let browser + try { + browser = await webdriver(appPort, '/blurry-placeholder') + const id = 'blurry-placeholder' + const backgroundImage = await browser.eval( + `window.getComputedStyle(document.getElementById('${id}')).getPropertyValue('background-image')` + ) + expect(backgroundImage).toBe('none') + } finally { + if (browser) { + await browser.close() + } + } + }) + runTests('serverless') }) }) From ffa2db7c4e218893fa11cad62d9a644a244b00cf Mon Sep 17 00:00:00 2001 From: Joon Park Date: Fri, 16 Apr 2021 15:46:51 -0500 Subject: [PATCH 2/7] Refactor experimental config name to better reflect intent --- packages/next/build/webpack-config.ts | 2 +- packages/next/client/image.tsx | 26 ++++++++++++------- .../next/next-server/server/config-shared.ts | 6 ++--- .../next/next-server/server/image-config.ts | 9 ++----- .../default/test/index.test.js | 2 +- 5 files changed, 24 insertions(+), 21 deletions(-) diff --git a/packages/next/build/webpack-config.ts b/packages/next/build/webpack-config.ts index a274efbf4ca65..27d2aa7bc3427 100644 --- a/packages/next/build/webpack-config.ts +++ b/packages/next/build/webpack-config.ts @@ -1084,7 +1084,7 @@ export default async function getBaseWebpackConfig( domains: config.images.domains, } : {}), - placeholder: config.experimental.imagePlaceholder, + enableBlurryPlaceholder: config.experimental.enableBlurryPlaceholder, }), 'process.env.__NEXT_ROUTER_BASEPATH': JSON.stringify(config.basePath), 'process.env.__NEXT_HAS_REWRITES': JSON.stringify(hasRewrites), diff --git a/packages/next/client/image.tsx b/packages/next/client/image.tsx index c8cfe255ac88d..319c98cdbce63 100644 --- a/packages/next/client/image.tsx +++ b/packages/next/client/image.tsx @@ -6,7 +6,6 @@ import { imageConfigDefault, LoaderValue, VALID_LOADERS, - PlaceholderValue, } from '../next-server/server/image-config' import { useIntersection } from './use-intersection' @@ -46,6 +45,11 @@ const VALID_LAYOUT_VALUES = [ ] as const type LayoutValue = typeof VALID_LAYOUT_VALUES[number] +enum PlaceholderValue { + BLURRY = 'blurry', + EMPTY = 'empty', +} + type ImgElementStyle = NonNullable export type ImageProps = Omit< @@ -79,7 +83,7 @@ export type ImageProps = Omit< placeholder?: Exclude blurDataURL: never } - | { placeholder: PlaceholderValue; blurDataURL: string } + | { placeholder: PlaceholderValue.BLURRY; blurDataURL: string } ) const { @@ -88,7 +92,7 @@ const { loader: configLoader, path: configPath, domains: configDomains, - placeholder: configPlaceholder, + enableBlurryPlaceholder: configEnableBlurryPlaceholder, } = ((process.env.__NEXT_IMAGE_OPTS as any) as ImageConfig) || imageConfigDefault // sort smallest to largest @@ -223,10 +227,10 @@ function removePlaceholder( placeholder: PlaceholderValue ) { const hasBlurryPlaceholder = - configPlaceholder === PlaceholderValue.BLURRY && - placeholder === PlaceholderValue.BLURRY + configEnableBlurryPlaceholder && placeholder === PlaceholderValue.BLURRY if (hasBlurryPlaceholder && element) { if (element.complete) { + // If the real image fails to load, this will still remove the placeholder. This is the desired behavior for now, and will be revisited when error handling is worked on for the image component itself. element.style.backgroundImage = 'none' } else { element.onload = () => { @@ -236,6 +240,10 @@ function removePlaceholder( } } +const defaultPlaceholder = configEnableBlurryPlaceholder + ? PlaceholderValue.BLURRY + : PlaceholderValue.EMPTY + export default function Image({ src, sizes, @@ -249,7 +257,7 @@ export default function Image({ objectFit, objectPosition, loader = defaultImageLoader, - placeholder = configPlaceholder, + placeholder = defaultPlaceholder, blurDataURL, ...all }: ImageProps) { @@ -320,16 +328,16 @@ export default function Image({ const heightInt = getInt(height) const qualityInt = getInt(quality) - const MIN_IMG_SIZE_FOR_PLACEHOLDER = 100 + const MIN_IMG_SIZE_FOR_PLACEHOLDER = 5000 const tooSmallForBlurryPlaceholder = widthInt && heightInt ? widthInt * heightInt < MIN_IMG_SIZE_FOR_PLACEHOLDER : false const shouldShowBlurryPlaceholder = - configPlaceholder === PlaceholderValue.BLURRY && + configEnableBlurryPlaceholder && placeholder === PlaceholderValue.BLURRY && priority && - (layout === 'fill' || !tooSmallForBlurryPlaceholder) + !tooSmallForBlurryPlaceholder let wrapperStyle: JSX.IntrinsicElements['div']['style'] | undefined let sizerStyle: JSX.IntrinsicElements['div']['style'] | undefined diff --git a/packages/next/next-server/server/config-shared.ts b/packages/next/next-server/server/config-shared.ts index 2eceb338e06e9..412cc98904eef 100644 --- a/packages/next/next-server/server/config-shared.ts +++ b/packages/next/next-server/server/config-shared.ts @@ -1,6 +1,6 @@ import os from 'os' import { Header, Redirect, Rewrite } from '../../lib/load-custom-routes' -import { imageConfigDefault, PlaceholderValue } from './image-config' +import { imageConfigDefault } from './image-config' export type DomainLocales = Array<{ http?: true @@ -60,7 +60,7 @@ export type NextConfig = { [key: string]: any } & { skipValidation?: boolean } turboMode: boolean - imagePlaceholder: PlaceholderValue + enableBlurryPlaceholder: boolean } } @@ -116,7 +116,7 @@ export const defaultConfig: NextConfig = { externalDir: false, serialWebpackBuild: false, turboMode: false, - imagePlaceholder: PlaceholderValue.EMPTY, + enableBlurryPlaceholder: false, }, future: { strictPostcssConfiguration: false, diff --git a/packages/next/next-server/server/image-config.ts b/packages/next/next-server/server/image-config.ts index 9ce1f767cbf88..db88d2c516b6d 100644 --- a/packages/next/next-server/server/image-config.ts +++ b/packages/next/next-server/server/image-config.ts @@ -7,18 +7,13 @@ export const VALID_LOADERS = [ export type LoaderValue = typeof VALID_LOADERS[number] -export enum PlaceholderValue { - EMPTY = 'empty', - BLURRY = 'blurry', -} - export type ImageConfig = { deviceSizes: number[] imageSizes: number[] loader: LoaderValue path: string domains?: string[] - placeholder: PlaceholderValue + enableBlurryPlaceholder: boolean } export const imageConfigDefault: ImageConfig = { @@ -27,5 +22,5 @@ export const imageConfigDefault: ImageConfig = { path: '/_next/image', loader: 'default', domains: [], - placeholder: PlaceholderValue.EMPTY, + enableBlurryPlaceholder: false, } diff --git a/test/integration/image-component/default/test/index.test.js b/test/integration/image-component/default/test/index.test.js index 7b887dc7e41c9..6460efa45ac25 100644 --- a/test/integration/image-component/default/test/index.test.js +++ b/test/integration/image-component/default/test/index.test.js @@ -589,7 +589,7 @@ describe('Image Component Tests', () => { module.exports = { target: 'serverless', experimental: { - imagePlaceholder: 'blurry', + enableBlurryPlaceholder: true, }, } ` From 40b83db135a63d54091fe750701f23cda62a772d Mon Sep 17 00:00:00 2001 From: Joon Park Date: Wed, 21 Apr 2021 18:42:21 -0500 Subject: [PATCH 3/7] Fix type error and rename enum value --- packages/next/client/image.tsx | 14 +++++++------- .../default/pages/blurry-placeholder.js | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/next/client/image.tsx b/packages/next/client/image.tsx index 319c98cdbce63..782aa8d5c7e94 100644 --- a/packages/next/client/image.tsx +++ b/packages/next/client/image.tsx @@ -46,7 +46,7 @@ const VALID_LAYOUT_VALUES = [ type LayoutValue = typeof VALID_LAYOUT_VALUES[number] enum PlaceholderValue { - BLURRY = 'blurry', + BLUR = 'blur', EMPTY = 'empty', } @@ -80,10 +80,10 @@ export type ImageProps = Omit< ) & ( | { - placeholder?: Exclude - blurDataURL: never + placeholder?: Exclude + blurDataURL?: never } - | { placeholder: PlaceholderValue.BLURRY; blurDataURL: string } + | { placeholder: PlaceholderValue.BLUR; blurDataURL: string } ) const { @@ -227,7 +227,7 @@ function removePlaceholder( placeholder: PlaceholderValue ) { const hasBlurryPlaceholder = - configEnableBlurryPlaceholder && placeholder === PlaceholderValue.BLURRY + configEnableBlurryPlaceholder && placeholder === PlaceholderValue.BLUR if (hasBlurryPlaceholder && element) { if (element.complete) { // If the real image fails to load, this will still remove the placeholder. This is the desired behavior for now, and will be revisited when error handling is worked on for the image component itself. @@ -241,7 +241,7 @@ function removePlaceholder( } const defaultPlaceholder = configEnableBlurryPlaceholder - ? PlaceholderValue.BLURRY + ? PlaceholderValue.BLUR : PlaceholderValue.EMPTY export default function Image({ @@ -335,7 +335,7 @@ export default function Image({ : false const shouldShowBlurryPlaceholder = configEnableBlurryPlaceholder && - placeholder === PlaceholderValue.BLURRY && + placeholder === PlaceholderValue.BLUR && priority && !tooSmallForBlurryPlaceholder diff --git a/test/integration/image-component/default/pages/blurry-placeholder.js b/test/integration/image-component/default/pages/blurry-placeholder.js index 8b154214062f0..d23c21799cd4c 100644 --- a/test/integration/image-component/default/pages/blurry-placeholder.js +++ b/test/integration/image-component/default/pages/blurry-placeholder.js @@ -11,7 +11,7 @@ export default function Page() { src="/test.jpg" width="400" height="400" - placeholder="blurry" + placeholder="blur" blurDataURL="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='400' height='400' viewBox='0 0 400 400'%3E%3Cfilter id='blur' filterUnits='userSpaceOnUse' color-interpolation-filters='sRGB'%3E%3CfeGaussianBlur stdDeviation='20' edgeMode='duplicate' /%3E%3CfeComponentTransfer%3E%3CfeFuncA type='discrete' tableValues='1 1' /%3E%3C/feComponentTransfer%3E%3C/filter%3E%3Cimage filter='url(%23blur)' href='data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAMDAwMDAwQEBAQFBQUFBQcHBgYHBwsICQgJCAsRCwwLCwwLEQ8SDw4PEg8bFRMTFRsfGhkaHyYiIiYwLTA+PlT/wAALCAAKAAoBAREA/8QAMwABAQEAAAAAAAAAAAAAAAAAAAcJEAABAwUAAwAAAAAAAAAAAAAFAAYRAQMEEyEVMlH/2gAIAQEAAD8Az1bLPaxhiuk0QdeCOLDtHixN2dmd2bsc5FPX7VTREX//2Q==' x='0' y='0' height='100%25' width='100%25'/%3E%3C/svg%3E" /> From 70499429c43206e7a1f8bd0759b74d865513a950 Mon Sep 17 00:00:00 2001 From: Joon Park Date: Thu, 22 Apr 2021 16:48:38 -0500 Subject: [PATCH 4/7] Enable placeholder for not just priority images --- packages/next/client/image.tsx | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/packages/next/client/image.tsx b/packages/next/client/image.tsx index 782aa8d5c7e94..cab2d8a31e73b 100644 --- a/packages/next/client/image.tsx +++ b/packages/next/client/image.tsx @@ -45,10 +45,7 @@ const VALID_LAYOUT_VALUES = [ ] as const type LayoutValue = typeof VALID_LAYOUT_VALUES[number] -enum PlaceholderValue { - BLUR = 'blur', - EMPTY = 'empty', -} +type PlaceholderValue = 'blur' | 'empty' type ImgElementStyle = NonNullable @@ -80,10 +77,10 @@ export type ImageProps = Omit< ) & ( | { - placeholder?: Exclude + placeholder?: Exclude blurDataURL?: never } - | { placeholder: PlaceholderValue.BLUR; blurDataURL: string } + | { placeholder: 'blur'; blurDataURL: string } ) const { @@ -227,7 +224,7 @@ function removePlaceholder( placeholder: PlaceholderValue ) { const hasBlurryPlaceholder = - configEnableBlurryPlaceholder && placeholder === PlaceholderValue.BLUR + configEnableBlurryPlaceholder && placeholder === 'blur' if (hasBlurryPlaceholder && element) { if (element.complete) { // If the real image fails to load, this will still remove the placeholder. This is the desired behavior for now, and will be revisited when error handling is worked on for the image component itself. @@ -240,9 +237,7 @@ function removePlaceholder( } } -const defaultPlaceholder = configEnableBlurryPlaceholder - ? PlaceholderValue.BLUR - : PlaceholderValue.EMPTY +const defaultPlaceholder = configEnableBlurryPlaceholder ? 'blur' : 'empty' export default function Image({ src, @@ -335,8 +330,7 @@ export default function Image({ : false const shouldShowBlurryPlaceholder = configEnableBlurryPlaceholder && - placeholder === PlaceholderValue.BLUR && - priority && + placeholder === 'blur' && !tooSmallForBlurryPlaceholder let wrapperStyle: JSX.IntrinsicElements['div']['style'] | undefined From 44a5e864c3f4c70e3de340d7baef89c6d3fda230 Mon Sep 17 00:00:00 2001 From: Joon Park Date: Fri, 23 Apr 2021 13:49:55 -0500 Subject: [PATCH 5/7] Simplify prop interaction with config value --- packages/next/client/image.tsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/next/client/image.tsx b/packages/next/client/image.tsx index cab2d8a31e73b..a097d87d60e4e 100644 --- a/packages/next/client/image.tsx +++ b/packages/next/client/image.tsx @@ -237,8 +237,6 @@ function removePlaceholder( } } -const defaultPlaceholder = configEnableBlurryPlaceholder ? 'blur' : 'empty' - export default function Image({ src, sizes, @@ -252,7 +250,7 @@ export default function Image({ objectFit, objectPosition, loader = defaultImageLoader, - placeholder = defaultPlaceholder, + placeholder = 'empty', blurDataURL, ...all }: ImageProps) { @@ -271,6 +269,10 @@ export default function Image({ delete rest['layout'] } + if (!configEnableBlurryPlaceholder) { + placeholder = 'empty' + } + if (process.env.NODE_ENV !== 'production') { if (!src) { throw new Error( @@ -325,9 +327,7 @@ export default function Image({ const MIN_IMG_SIZE_FOR_PLACEHOLDER = 5000 const tooSmallForBlurryPlaceholder = - widthInt && heightInt - ? widthInt * heightInt < MIN_IMG_SIZE_FOR_PLACEHOLDER - : false + widthInt && heightInt && widthInt * heightInt < MIN_IMG_SIZE_FOR_PLACEHOLDER const shouldShowBlurryPlaceholder = configEnableBlurryPlaceholder && placeholder === 'blur' && From 0356aa1e8a65b2208bd71bf88fadbbf129175d69 Mon Sep 17 00:00:00 2001 From: Joon Park Date: Mon, 26 Apr 2021 10:22:24 -0500 Subject: [PATCH 6/7] Remoe vestigial config checks --- packages/next/client/image.tsx | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/packages/next/client/image.tsx b/packages/next/client/image.tsx index a097d87d60e4e..f18137d9e36f9 100644 --- a/packages/next/client/image.tsx +++ b/packages/next/client/image.tsx @@ -223,11 +223,11 @@ function removePlaceholder( element: HTMLImageElement | null, placeholder: PlaceholderValue ) { - const hasBlurryPlaceholder = - configEnableBlurryPlaceholder && placeholder === 'blur' - if (hasBlurryPlaceholder && element) { + if (placeholder === 'blur' && element) { if (element.complete) { - // If the real image fails to load, this will still remove the placeholder. This is the desired behavior for now, and will be revisited when error handling is worked on for the image component itself. + // If the real image fails to load, this will still remove the placeholder. + // This is the desired behavior for now, and will be revisited when error + // handling is worked on for the image component itself. element.style.backgroundImage = 'none' } else { element.onload = () => { @@ -329,9 +329,7 @@ export default function Image({ const tooSmallForBlurryPlaceholder = widthInt && heightInt && widthInt * heightInt < MIN_IMG_SIZE_FOR_PLACEHOLDER const shouldShowBlurryPlaceholder = - configEnableBlurryPlaceholder && - placeholder === 'blur' && - !tooSmallForBlurryPlaceholder + placeholder === 'blur' && !tooSmallForBlurryPlaceholder let wrapperStyle: JSX.IntrinsicElements['div']['style'] | undefined let sizerStyle: JSX.IntrinsicElements['div']['style'] | undefined From 3dc7d1592821fbd1cf5934ce7f29b25d224d9de7 Mon Sep 17 00:00:00 2001 From: Joon Park Date: Mon, 26 Apr 2021 23:37:11 -0500 Subject: [PATCH 7/7] Add comment about ref handler --- packages/next/client/image.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/next/client/image.tsx b/packages/next/client/image.tsx index f18137d9e36f9..887a6769acd03 100644 --- a/packages/next/client/image.tsx +++ b/packages/next/client/image.tsx @@ -219,6 +219,8 @@ function defaultImageLoader(loaderProps: ImageLoaderProps) { ) } +// See https://stackoverflow.com/q/39777833/266535 for why we use this ref +// handler instead of the img's onLoad attribute. function removePlaceholder( element: HTMLImageElement | null, placeholder: PlaceholderValue