rsnext/test/e2e/app-dir/dynamic-css/index.test.ts
Jiachi Liu b4130cb07a
Preload all chunks for next/dynamic in SSR (#65486)
### What

Follow up for #64294 where we could preload all the JS and CSS chunks
for `next/dynamic` component.

* Rename `preload-css` component to `preload-chunks` and remove the
filter for css chunks
* Preload JS chunks with `defer`

### Why

Preloading all the async chunks of `next/dynamic` can make rendering
more efficiently when combined with the initial chunks. Since those
chunks are splitted on client but still essential for the page

#### After vs Before

We can see the waterfall starts much earlier for the dynamic chunk
(881.8a0e88...js)

<img width="500"
src="https://github.com/vercel/next.js/assets/4800338/9bab2c32-37c3-4c7a-93e2-3aa43b2ec7c8">
<img width="500"
src="https://github.com/vercel/next.js/assets/4800338/0fba7499-bb69-41c4-ab72-e9952f3d7f68">
2024-05-08 19:30:42 +02:00

79 lines
2.6 KiB
TypeScript

import { nextTestSetup } from 'e2e-utils'
import { retry } from 'next-test-utils'
describe('app dir - dynamic css', () => {
const { next, skipped } = nextTestSetup({
files: __dirname,
skipDeployment: true,
})
if (skipped) {
return
}
it('should preload all chunks of dynamic component during SSR', async () => {
const $ = await next.render$('/ssr')
const cssLinks = $('link[rel="stylesheet"][data-precedence="dynamic"]')
expect(cssLinks.attr('href')).toContain('.css')
const preloadJsChunks = $('link[rel="preload"]')
expect(preloadJsChunks.attr('as')).toBe('script')
expect(preloadJsChunks.attr('fetchpriority')).toContain(`low`)
})
it('should only apply corresponding css for page loaded that /ssr', async () => {
const browser = await next.browser('/ssr')
await retry(async () => {
expect(
await browser.eval(
`window.getComputedStyle(document.querySelector('.text')).color`
)
).toBe('rgb(255, 0, 0)')
// Default border width, which is not effected by bar.css that is not loaded in /ssr
expect(
await browser.eval(
`window.getComputedStyle(document.querySelector('.text')).borderWidth`
)
).toBe('0px')
})
})
it('should only apply corresponding css for page loaded in edge runtime', async () => {
const browser = await next.browser('/ssr/edge')
await retry(async () => {
expect(
await browser.eval(
`window.getComputedStyle(document.querySelector('.text')).color`
)
).toBe('rgb(255, 0, 0)')
// Default border width, which is not effected by bar.css that is not loaded in /ssr
expect(
await browser.eval(
`window.getComputedStyle(document.querySelector('.text')).borderWidth`
)
).toBe('0px')
})
})
it('should only apply corresponding css for page loaded that /another', async () => {
const browser = await next.browser('/another')
await retry(async () => {
expect(
await browser.eval(
`window.getComputedStyle(document.querySelector('.text')).color`
)
).not.toBe('rgb(255, 0, 0)')
// Default border width, which is not effected by bar.css that is not loaded in /ssr
expect(
await browser.eval(
`window.getComputedStyle(document.querySelector('.text')).borderWidth`
)
).toBe('1px')
})
})
it('should not throw with accessing to ALS in preload css', async () => {
const output = next.cliOutput
expect(output).not.toContain('was called outside a request scope')
})
})