Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove experimental image optimization feature #34349

Merged
merged 1 commit into from Feb 15, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 0 additions & 4 deletions packages/next/build/webpack-config.ts
Expand Up @@ -1346,9 +1346,6 @@ export default async function getBaseWebpackConfig(
'process.env.__NEXT_OPTIMIZE_FONTS': JSON.stringify(
config.optimizeFonts && !dev
),
'process.env.__NEXT_OPTIMIZE_IMAGES': JSON.stringify(
config.experimental.optimizeImages
),
'process.env.__NEXT_OPTIMIZE_CSS': JSON.stringify(
config.experimental.optimizeCss && !dev
),
Expand Down Expand Up @@ -1611,7 +1608,6 @@ export default async function getBaseWebpackConfig(
reactStrictMode: config.reactStrictMode,
reactMode: config.experimental.reactMode,
optimizeFonts: config.optimizeFonts,
optimizeImages: config.experimental.optimizeImages,
optimizeCss: config.experimental.optimizeCss,
scrollRestoration: config.experimental.scrollRestoration,
basePath: config.basePath,
Expand Down
Expand Up @@ -191,7 +191,6 @@ export function getPageHandler(ctx: ServerlessHandlerCtx) {
locale: detectedLocale,
defaultLocale,
domainLocales: i18n?.domains,
optimizeImages: process.env.__NEXT_OPTIMIZE_IMAGES,
optimizeCss: process.env.__NEXT_OPTIMIZE_CSS,
crossOrigin: process.env.__NEXT_CROSS_ORIGIN,
},
Expand Down
2 changes: 0 additions & 2 deletions packages/next/export/index.ts
Expand Up @@ -385,7 +385,6 @@ export default async function exportApp(
crossOrigin: nextConfig.crossOrigin,
optimizeCss: nextConfig.experimental.optimizeCss,
optimizeFonts: nextConfig.optimizeFonts,
optimizeImages: nextConfig.experimental.optimizeImages,
reactRoot: nextConfig.experimental.reactRoot || false,
}

Expand Down Expand Up @@ -583,7 +582,6 @@ export default async function exportApp(
buildExport: options.buildExport,
serverless: isTargetLikeServerless(nextConfig.target),
optimizeFonts: nextConfig.optimizeFonts,
optimizeImages: nextConfig.experimental.optimizeImages,
optimizeCss: nextConfig.experimental.optimizeCss,
disableOptimizedLoading:
nextConfig.experimental.disableOptimizedLoading,
Expand Down
9 changes: 0 additions & 9 deletions packages/next/export/worker.ts
Expand Up @@ -55,7 +55,6 @@ interface ExportPageInput {
subFolders?: boolean
serverless: boolean
optimizeFonts: boolean
optimizeImages?: boolean
optimizeCss: any
disableOptimizedLoading: any
parentSpanId: any
Expand All @@ -77,7 +76,6 @@ interface RenderOpts {
ampValidatorPath?: string
ampSkipValidation?: boolean
optimizeFonts?: boolean
optimizeImages?: boolean
disableOptimizedLoading?: boolean
optimizeCss?: any
fontManifest?: FontManifest
Expand Down Expand Up @@ -105,7 +103,6 @@ export default async function exportPage({
subFolders,
serverless,
optimizeFonts,
optimizeImages,
optimizeCss,
disableOptimizedLoading,
httpAgentOptions,
Expand Down Expand Up @@ -304,8 +301,6 @@ export default async function exportPage({
/// @ts-ignore
optimizeFonts,
/// @ts-ignore
optimizeImages,
/// @ts-ignore
optimizeCss,
disableOptimizedLoading,
distDir,
Expand Down Expand Up @@ -367,9 +362,6 @@ export default async function exportPage({
if (optimizeFonts) {
process.env.__NEXT_OPTIMIZE_FONTS = JSON.stringify(true)
}
if (optimizeImages) {
process.env.__NEXT_OPTIMIZE_IMAGES = JSON.stringify(true)
}
if (optimizeCss) {
process.env.__NEXT_OPTIMIZE_CSS = JSON.stringify(true)
}
Expand All @@ -379,7 +371,6 @@ export default async function exportPage({
ampPath: renderAmpPath,
params,
optimizeFonts,
optimizeImages,
optimizeCss,
disableOptimizedLoading,
fontManifest: optimizeFonts
Expand Down
2 changes: 0 additions & 2 deletions packages/next/pages/_document.tsx
Expand Up @@ -494,7 +494,6 @@ export class Head extends Component<
useMaybeDeferContent,
optimizeCss,
optimizeFonts,
optimizeImages,
runtime,
} = this.context

Expand Down Expand Up @@ -737,7 +736,6 @@ export class Head extends Component<
)}
{!optimizeCss && this.getCssLinks(files)}
{!optimizeCss && <noscript data-n-css={this.props.nonce ?? ''} />}
{optimizeImages && <meta name="next-image-preload" />}

{!isDeferred && getDynamicScriptPreloads()}

Expand Down
2 changes: 0 additions & 2 deletions packages/next/server/base-server.ts
Expand Up @@ -152,7 +152,6 @@ export default abstract class Server {
optimizeFonts: boolean
images: ImageConfigComplete
fontManifest?: FontManifest
optimizeImages: boolean
disableOptimizedLoading?: boolean
optimizeCss: any
locale?: string
Expand Down Expand Up @@ -314,7 +313,6 @@ export default abstract class Server {
this.nextConfig.optimizeFonts && !dev
? this.getFontManifest()
: undefined,
optimizeImages: !!this.nextConfig.experimental.optimizeImages,
optimizeCss: this.nextConfig.experimental.optimizeCss,
disableOptimizedLoading: this.nextConfig.experimental.runtime
? true
Expand Down
2 changes: 0 additions & 2 deletions packages/next/server/config-shared.ts
Expand Up @@ -85,7 +85,6 @@ export interface ExperimentalConfig {
reactMode?: 'legacy' | 'concurrent' | 'blocking'
workerThreads?: boolean
pageEnv?: boolean
optimizeImages?: boolean
optimizeCss?: boolean
scrollRestoration?: boolean
externalDir?: boolean
Expand Down Expand Up @@ -454,7 +453,6 @@ export const defaultConfig: NextConfig = {
isrFlushToDisk: true,
workerThreads: false,
pageEnv: false,
optimizeImages: false,
optimizeCss: false,
scrollRestoration: false,
externalDir: false,
Expand Down
6 changes: 1 addition & 5 deletions packages/next/server/next-server.ts
Expand Up @@ -100,15 +100,11 @@ export default class NextNodeServer extends BaseServer {
/**
* This sets environment variable to be used at the time of SSR by head.tsx.
* Using this from process.env allows targeting both serverless and SSR by calling
* `process.env.__NEXT_OPTIMIZE_IMAGES`.
* TODO(atcastle@): Remove this when experimental.optimizeImages are being cleaned up.
* `process.env.__NEXT_OPTIMIZE_CSS`.
*/
if (this.renderOpts.optimizeFonts) {
process.env.__NEXT_OPTIMIZE_FONTS = JSON.stringify(true)
}
if (this.renderOpts.optimizeImages) {
process.env.__NEXT_OPTIMIZE_IMAGES = JSON.stringify(true)
}
if (this.renderOpts.optimizeCss) {
process.env.__NEXT_OPTIMIZE_CSS = JSON.stringify(true)
}
Expand Down
7 changes: 1 addition & 6 deletions packages/next/server/render.tsx
Expand Up @@ -215,7 +215,6 @@ export type RenderOptsPartial = {
unstable_JsPreload?: false
optimizeFonts: boolean
fontManifest?: FontManifest
optimizeImages: boolean
optimizeCss: any
devOnlyCacheBusterQueryString?: string
resolvedUrl?: string
Expand Down Expand Up @@ -1406,7 +1405,6 @@ export async function renderToHTML(
crossOrigin: renderOpts.crossOrigin,
optimizeCss: renderOpts.optimizeCss,
optimizeFonts: renderOpts.optimizeFonts,
optimizeImages: renderOpts.optimizeImages,
runtime,
}

Expand Down Expand Up @@ -1485,16 +1483,13 @@ export async function renderToHTML(
return html
}
: null,
!process.browser &&
(process.env.__NEXT_OPTIMIZE_FONTS ||
process.env.__NEXT_OPTIMIZE_IMAGES)
!process.browser && process.env.__NEXT_OPTIMIZE_FONTS
? async (html: string) => {
return await postProcess(
html,
{ getFontDefinition },
{
optimizeFonts: renderOpts.optimizeFonts,
optimizeImages: renderOpts.optimizeImages,
}
)
}
Expand Down
108 changes: 0 additions & 108 deletions packages/next/shared/lib/post-process.ts
@@ -1,14 +1,10 @@
import { escapeStringRegexp } from './escape-regexp'
import { parse, HTMLElement } from 'next/dist/compiled/node-html-parser'
import { OPTIMIZED_FONT_PROVIDERS } from './constants'

// const MIDDLEWARE_TIME_BUDGET = parseInt(process.env.__POST_PROCESS_MIDDLEWARE_TIME_BUDGET || '', 10) || 10
const MAXIMUM_IMAGE_PRELOADS = 2
const IMAGE_PRELOAD_SIZE_THRESHOLD = 2500

type postProcessOptions = {
optimizeFonts: boolean
optimizeImages: boolean
}

type renderOptions = {
Expand Down Expand Up @@ -169,103 +165,6 @@ class FontOptimizerMiddleware implements PostProcessMiddleware {
}
}

class ImageOptimizerMiddleware implements PostProcessMiddleware {
inspect(originalDom: HTMLElement) {
const imgPreloads = []
const imgElements = originalDom.querySelectorAll('img')
let eligibleImages: Array<HTMLElement> = []
for (let i = 0; i < imgElements.length; i++) {
if (isImgEligible(imgElements[i])) {
eligibleImages.push(imgElements[i])
}
if (eligibleImages.length >= MAXIMUM_IMAGE_PRELOADS) {
break
}
}

for (const imgEl of eligibleImages) {
const src = imgEl.getAttribute('src')
if (src) {
imgPreloads.push(src)
}
}

return imgPreloads
}
mutate = async (markup: string, imgPreloads: string[]) => {
let result = markup
let imagePreloadTags = imgPreloads
.filter((imgHref) => !preloadTagAlreadyExists(markup, imgHref))
.reduce(
(acc, imgHref) =>
acc + `<link rel="preload" href="${imgHref}" as="image"/>`,
''
)
return result.replace('<meta name="next-image-preload"/>', imagePreloadTags)
}
}

function isImgEligible(imgElement: HTMLElement): boolean {
let imgSrc = imgElement.getAttribute('src')
return (
!!imgSrc &&
sourceIsSupportedType(imgSrc) &&
imageIsNotTooSmall(imgElement) &&
imageIsNotHidden(imgElement)
)
}

function preloadTagAlreadyExists(html: string, href: string) {
const escapedHref = escapeStringRegexp(href)
const regex = new RegExp(`<link[^>]*href[^>]*${escapedHref}`)
return html.match(regex)
}

function imageIsNotTooSmall(imgElement: HTMLElement): boolean {
// Skip images without both height and width--we don't know enough to say if
// they are too small
if (
!(imgElement.hasAttribute('height') && imgElement.hasAttribute('width'))
) {
return true
}
try {
const heightAttr = imgElement.getAttribute('height')
const widthAttr = imgElement.getAttribute('width')
if (!heightAttr || !widthAttr) {
return true
}

if (
parseInt(heightAttr) * parseInt(widthAttr) <=
IMAGE_PRELOAD_SIZE_THRESHOLD
) {
return false
}
} catch (err) {
return true
}
return true
}

// Traverse up the dom from each image to see if it or any of it's
// ancestors have the hidden attribute.
function imageIsNotHidden(imgElement: HTMLElement): boolean {
let activeElement = imgElement
while (activeElement.parentNode) {
if (activeElement.hasAttribute('hidden')) {
return false
}
activeElement = activeElement.parentNode as HTMLElement
}
return true
}

// Currently only filters out svg images--could be made more specific in the future.
function sourceIsSupportedType(imgSrc: string): boolean {
return !imgSrc.includes('.svg')
}

// Initialization
registerPostProcessor(
'Inline-Fonts',
Expand All @@ -275,11 +174,4 @@ registerPostProcessor(
(options) => options.optimizeFonts || process.env.__NEXT_OPTIMIZE_FONTS
)

registerPostProcessor(
'Preload Images',
new ImageOptimizerMiddleware(),
// @ts-ignore
(options) => options.optimizeImages || process.env.__NEXT_OPTIMIZE_IMAGES
)

export default processHTML
1 change: 0 additions & 1 deletion packages/next/shared/lib/utils.ts
Expand Up @@ -224,7 +224,6 @@ export type HtmlProps = {
crossOrigin?: string
optimizeCss?: boolean
optimizeFonts?: boolean
optimizeImages?: boolean
runtime?: 'edge' | 'nodejs'
}

Expand Down
4 changes: 0 additions & 4 deletions test/integration/image-optimization/next.config.js

This file was deleted.

25 changes: 0 additions & 25 deletions test/integration/image-optimization/pages/index.js

This file was deleted.

30 changes: 0 additions & 30 deletions test/integration/image-optimization/pages/stars.js

This file was deleted.