Skip to content

Commit 8682705

Browse files
Refactor experimental-script component (#24940)
1 parent 59d50ff commit 8682705

File tree

8 files changed

+52
-100
lines changed

8 files changed

+52
-100
lines changed

packages/next/client/experimental-script.tsx

Lines changed: 9 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ const ScriptCache = new Map()
88
const LoadCache = new Set()
99

1010
export interface Props extends ScriptHTMLAttributes<HTMLScriptElement> {
11-
strategy?: 'defer' | 'lazy' | 'dangerouslyBlockRendering' | 'eager'
11+
strategy?: 'afterInteraction' | 'lazy' | 'beforeInteraction'
1212
id?: string
1313
onLoad?: () => void
1414
onError?: () => void
@@ -93,8 +93,8 @@ const loadScript = (props: Props): void => {
9393
}
9494

9595
function handleClientScriptLoad(props: Props) {
96-
const { strategy = 'defer' } = props
97-
if (strategy === 'defer') {
96+
const { strategy = 'afterInteraction' } = props
97+
if (strategy === 'afterInteraction') {
9898
loadScript(props)
9999
} else if (strategy === 'lazy') {
100100
window.addEventListener('load', () => {
@@ -122,8 +122,7 @@ function Script(props: Props): JSX.Element | null {
122122
src = '',
123123
onLoad = () => {},
124124
dangerouslySetInnerHTML,
125-
children = '',
126-
strategy = 'defer',
125+
strategy = 'afterInteraction',
127126
onError,
128127
preload = false,
129128
...restProps
@@ -133,7 +132,7 @@ function Script(props: Props): JSX.Element | null {
133132
const { updateScripts, scripts } = useContext(HeadManagerContext)
134133

135134
useEffect(() => {
136-
if (strategy === 'defer') {
135+
if (strategy === 'afterInteraction') {
137136
loadScript(props)
138137
} else if (strategy === 'lazy') {
139138
loadLazyScript(props)
@@ -144,42 +143,14 @@ function Script(props: Props): JSX.Element | null {
144143
return null
145144
}
146145

147-
if (strategy === 'dangerouslyBlockRendering') {
148-
const syncProps: Props = { ...restProps }
149-
150-
for (const [k, value] of Object.entries({
151-
src,
152-
onLoad,
153-
onError,
154-
dangerouslySetInnerHTML,
155-
children,
156-
})) {
157-
if (!value) {
158-
continue
159-
}
160-
if (k === 'children') {
161-
syncProps.dangerouslySetInnerHTML = {
162-
__html:
163-
typeof value === 'string'
164-
? value
165-
: Array.isArray(value)
166-
? value.join('')
167-
: '',
168-
}
169-
} else {
170-
;(syncProps as any)[k] = value
171-
}
172-
}
173-
174-
return <script {...syncProps} />
175-
} else if (strategy === 'defer') {
146+
if (strategy === 'afterInteraction') {
176147
if (updateScripts && preload) {
177-
scripts.defer = (scripts.defer || []).concat([src])
148+
scripts.afterInteraction = (scripts.afterInteraction || []).concat([src])
178149
updateScripts(scripts)
179150
}
180-
} else if (strategy === 'eager') {
151+
} else if (strategy === 'beforeInteraction') {
181152
if (updateScripts) {
182-
scripts.eager = (scripts.eager || []).concat([
153+
scripts.beforeInteraction = (scripts.beforeInteraction || []).concat([
183154
{
184155
src,
185156
onLoad,

packages/next/next-server/lib/utils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ export type DocumentProps = DocumentInitialProps & {
191191
unstable_runtimeJS?: false
192192
unstable_JsPreload?: false
193193
devOnlyCacheBusterQueryString: string
194-
scriptLoader: { defer?: string[]; eager?: any[] }
194+
scriptLoader: { afterInteraction?: string[]; beforeInteraction?: any[] }
195195
locale?: string
196196
}
197197

packages/next/pages/_document.tsx

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@ export class Head extends Component<
256256
})
257257

258258
return [
259-
...(scriptLoader.eager || []).map((file) => (
259+
...(scriptLoader.beforeInteraction || []).map((file) => (
260260
<link
261261
key={file.src}
262262
nonce={this.props.nonce}
@@ -282,7 +282,7 @@ export class Head extends Component<
282282
}
283283
/>
284284
)),
285-
...(scriptLoader.defer || []).map((file: string) => (
285+
...(scriptLoader.afterInteraction || []).map((file: string) => (
286286
<link
287287
key={file}
288288
nonce={this.props.nonce}
@@ -304,14 +304,18 @@ export class Head extends Component<
304304

305305
React.Children.forEach(children, (child: any) => {
306306
if (child.type === Script) {
307-
if (child.props.strategy === 'eager') {
308-
scriptLoader.eager = (scriptLoader.eager || []).concat([
307+
if (child.props.strategy === 'beforeInteraction') {
308+
scriptLoader.beforeInteraction = (
309+
scriptLoader.beforeInteraction || []
310+
).concat([
309311
{
310312
...child.props,
311313
},
312314
])
313315
return
314-
} else if (['lazy', 'defer'].includes(child.props.strategy)) {
316+
} else if (
317+
['lazy', 'afterInteraction'].includes(child.props.strategy)
318+
) {
315319
scriptLoaderItems.push(child.props)
316320
return
317321
}
@@ -664,18 +668,20 @@ export class NextScript extends Component<OriginProps> {
664668
getPreNextScripts() {
665669
const { scriptLoader } = this.context
666670

667-
return (scriptLoader.eager || []).map((file: ScriptLoaderProps) => {
668-
const { strategy, ...props } = file
669-
return (
670-
<script
671-
{...props}
672-
nonce={this.props.nonce}
673-
crossOrigin={
674-
this.props.crossOrigin || process.env.__NEXT_CROSS_ORIGIN
675-
}
676-
/>
677-
)
678-
})
671+
return (scriptLoader.beforeInteraction || []).map(
672+
(file: ScriptLoaderProps) => {
673+
const { strategy, ...props } = file
674+
return (
675+
<script
676+
{...props}
677+
nonce={this.props.nonce}
678+
crossOrigin={
679+
this.props.crossOrigin || process.env.__NEXT_CROSS_ORIGIN
680+
}
681+
/>
682+
)
683+
}
684+
)
679685
}
680686

681687
getScripts(files: DocumentFiles) {

test/integration/script-loader/pages/_document.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@ export default class MyDocument extends Document {
2121
href="https://fonts.googleapis.com/css?family=Voces"
2222
/>
2323
<Script
24-
id="documentDefer"
25-
src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js?a=documentDefer"
26-
strategy="defer"
24+
id="documentAfterInteraction"
25+
src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js?a=documentAfterInteraction"
26+
strategy="afterInteraction"
2727
></Script>
2828
<Script
2929
id="documentLazy"
@@ -36,9 +36,9 @@ export default class MyDocument extends Document {
3636
strategy="dangerouslyBlockRendering"
3737
></Script>
3838
<Script
39-
id="documentEager"
40-
src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js?a=documentEager"
41-
strategy="eager"
39+
id="documentBeforeInteraction"
40+
src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js?a=documentBeforeInteraction"
41+
strategy="beforeInteraction"
4242
></Script>
4343
</Head>
4444
<body>

test/integration/script-loader/pages/index.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ const Page = () => {
44
return (
55
<div class="container">
66
<Script
7-
id="scriptDefer"
8-
src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js?a=scriptDefer"
7+
id="scriptAfterInteraction"
8+
src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js?a=scriptAfterInteraction"
99
preload
1010
></Script>
1111
<div>index</div>

test/integration/script-loader/pages/page1.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ const Page = () => {
44
return (
55
<div class="container">
66
<Script
7-
id="scriptEager"
8-
src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js?a=scriptEager"
9-
strategy="eager"
7+
id="scriptBeforeInteraction"
8+
src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js?a=scriptBeforeInteraction"
9+
strategy="beforeInteraction"
1010
></Script>
1111
<div>page1</div>
1212
</div>

test/integration/script-loader/pages/page2.js

Lines changed: 0 additions & 16 deletions
This file was deleted.

test/integration/script-loader/test/index.test.js

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ describe('Script Loader', () => {
3434
stopApp(server)
3535
})
3636

37-
it('priority defer', async () => {
37+
it('priority afterInteraction', async () => {
3838
let browser
3939
try {
4040
browser = await webdriver(appPort, '/')
@@ -58,10 +58,10 @@ describe('Script Loader', () => {
5858
expect(endPreloads.length).toBe(0)
5959
}
6060

61-
// Defer script in page
62-
await test('scriptDefer')
63-
// Defer script in _document
64-
await test('documentDefer')
61+
// afterInteraction script in page
62+
await test('scriptAfterInteraction')
63+
// afterInteraction script in _document
64+
await test('documentAfterInteraction')
6565
} finally {
6666
if (browser) await browser.close()
6767
}
@@ -96,7 +96,7 @@ describe('Script Loader', () => {
9696
}
9797
})
9898

99-
it('priority eager', async () => {
99+
it('priority beforeInteraction', async () => {
100100
const html = await renderViaHTTP(appPort, '/page1')
101101
const $ = cheerio.load(html)
102102

@@ -130,17 +130,8 @@ describe('Script Loader', () => {
130130
).toBeGreaterThan(0)
131131
}
132132

133-
test('scriptEager')
134-
test('documentEager')
135-
})
136-
137-
it('priority dangerouslyBlockRendering', async () => {
138-
const html = await renderViaHTTP(appPort, '/page2')
139-
const $ = cheerio.load(html)
140-
141-
// Script is inserted in place
142-
expect($('.container #scriptBlock').length).toBeGreaterThan(0)
143-
expect($('head #documentBlock').length).toBeGreaterThan(0)
133+
test('scriptBeforeInteraction')
134+
test('documentBeforeInteraction')
144135
})
145136

146137
it('onload fires correctly', async () => {

0 commit comments

Comments
 (0)