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

Replace page loader with new route loader #19006

Merged
merged 34 commits into from
Nov 11, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
9c6054b
Replace page loader with new route loader
Timer Nov 10, 2020
9f391ac
Join with control flow
Timer Nov 10, 2020
0fa3e7c
Rename method
Timer Nov 10, 2020
bef4d77
Correctly map stylesheets
Timer Nov 10, 2020
8d6168e
call direct
Timer Nov 10, 2020
21b34cd
Wait for idle to intersect
Timer Nov 10, 2020
8317797
Fix TS compile
Timer Nov 10, 2020
46e8a14
Fix prerendering
Timer Nov 10, 2020
b1a7ab1
Fix order of script check
Timer Nov 10, 2020
f485329
Dedupe page loads
Timer Nov 10, 2020
01a12ae
Add support for development files
Timer Nov 10, 2020
07cefcc
Remove old comment
Timer Nov 10, 2020
c54befe
Fix prefetching
Timer Nov 10, 2020
bb09789
Prevent duplicate prefetches
Timer Nov 10, 2020
7bed0ee
remove unnecessary checks
Timer Nov 10, 2020
259a344
remove some wrapping
Timer Nov 10, 2020
dc87d7c
remove dead constant
Timer Nov 10, 2020
50382e0
Remove export
Timer Nov 10, 2020
7842fbf
Remove cssc
Timer Nov 10, 2020
db0425c
deasync loadPage
Timer Nov 10, 2020
ff00087
deasync onEntrypoint
Timer Nov 10, 2020
647afe9
simplify helper
Timer Nov 10, 2020
582e12d
Remove fetch of CSS to hydrate
Timer Nov 10, 2020
07e56a1
Allow re-renders with incomplete route info
Timer Nov 10, 2020
929ed08
fix oopsie
Timer Nov 10, 2020
33e1024
Fix basic error recovery test
Timer Nov 10, 2020
2b2aadb
update size snapshot
Timer Nov 10, 2020
b4ddd43
remove unnecessary check
Timer Nov 10, 2020
5dcd5fc
add 1kb to modern build
Timer Nov 10, 2020
c6a9b35
remove shared build manifest callback
Timer Nov 11, 2020
a6b3db2
Test that transitions work
Timer Nov 11, 2020
9c34d98
Merge remote-tracking branch 'upstream/canary' into refactor/route-lo…
Timer Nov 11, 2020
49f08e6
update build output size
Timer Nov 11, 2020
ff18a4e
Merge branch 'canary' into refactor/route-loader
kodiakhq[bot] Nov 11, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 33 additions & 36 deletions packages/next/client/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,7 @@ import * as envConfig from '../next-server/lib/runtime-config'
import type { NEXT_DATA } from '../next-server/lib/utils'
import { getURL, loadGetInitialProps, ST } from '../next-server/lib/utils'
import initHeadManager from './head-manager'
import PageLoader, {
INITIAL_CSS_LOAD_ERROR,
looseToArray,
StyleSheetTuple,
} from './page-loader'
import PageLoader, { StyleSheetTuple } from './page-loader'
import measureWebVitals from './performance-relayer'
import { createRouter, makePublicRouterInstance } from './router'

Expand Down Expand Up @@ -53,6 +49,8 @@ window.__NEXT_DATA__ = data

export const version = process.env.__NEXT_VERSION

const looseToArray = <T extends {}>(input: any): T[] => [].slice.call(input)

const {
props: hydrateProps,
err: hydrateErr,
Expand Down Expand Up @@ -133,8 +131,9 @@ if (process.env.__NEXT_I18N_SUPPORT) {

type RegisterFn = (input: [string, () => void]) => void

const pageLoader = new PageLoader(buildId, prefix, page)
const register: RegisterFn = ([r, f]) => pageLoader.registerPage(r, f)
const pageLoader = new PageLoader(buildId, prefix)
const register: RegisterFn = ([r, f]) =>
pageLoader.routeLoader.onEntrypoint(r, f)
if (window.__NEXT_P) {
// Defer page registration for another tick. This will increase the overall
// latency in hydrating the page, but reduce the total blocking time.
Expand All @@ -151,7 +150,6 @@ let lastRenderReject: (() => void) | null
let webpackHMR: any
export let router: Router
let CachedComponent: React.ComponentType
let cachedStyleSheets: StyleSheetTuple[]
let CachedApp: AppComponent, onPerfEntry: (metric: any) => void

class Container extends React.Component<{
Expand Down Expand Up @@ -236,7 +234,13 @@ export default async (opts: { webpackHMR?: any } = {}) => {
if (process.env.NODE_ENV === 'development') {
webpackHMR = opts.webpackHMR
}
const { page: app, mod } = await pageLoader.loadPage('/_app')

const appEntrypoint = await pageLoader.routeLoader.whenEntrypoint('/_app')
if ('error' in appEntrypoint) {
throw appEntrypoint.error
}

const { component: app, exports: mod } = appEntrypoint
CachedApp = app as AppComponent

if (mod && mod.reportWebVitals) {
Expand Down Expand Up @@ -275,10 +279,16 @@ export default async (opts: { webpackHMR?: any } = {}) => {
let initialErr = hydrateErr

try {
;({
page: CachedComponent,
styleSheets: cachedStyleSheets,
} = await pageLoader.loadPage(page))
const pageEntrypoint =
// The dev server fails to serve script assets when there's a hydration
// error, so we need to skip waiting for the entrypoint.
process.env.NODE_ENV === 'development' && hydrateErr
? { error: hydrateErr }
: await pageLoader.routeLoader.whenEntrypoint(page)
if ('error' in pageEntrypoint) {
throw pageEntrypoint.error
}
CachedComponent = pageEntrypoint.component

if (process.env.NODE_ENV !== 'production') {
const { isValidElementType } = require('react-is')
Expand All @@ -289,9 +299,6 @@ export default async (opts: { webpackHMR?: any } = {}) => {
}
}
} catch (error) {
if (INITIAL_CSS_LOAD_ERROR in error) {
throw error
}
// This catches errors like throwing in the top level of a module
initialErr = error
}
Expand Down Expand Up @@ -339,12 +346,10 @@ export default async (opts: { webpackHMR?: any } = {}) => {
pageLoader,
App: CachedApp,
Component: CachedComponent,
initialStyleSheets: cachedStyleSheets,
wrapApp,
err: initialErr,
isFallback: Boolean(isFallback),
subscription: ({ Component, styleSheets, props, err }, App) =>
render({ App, Component, styleSheets, props, err }),
subscription: (info, App) => render(Object.assign({}, info, { App })),
locale,
locales,
defaultLocale,
Expand All @@ -363,10 +368,10 @@ export default async (opts: { webpackHMR?: any } = {}) => {
})
}

const renderCtx = {
const renderCtx: RenderRouteInfo = {
App: CachedApp,
initial: true,
Component: CachedComponent,
styleSheets: cachedStyleSheets,
props: hydrateProps,
err: initialErr,
}
Expand Down Expand Up @@ -471,8 +476,6 @@ export function renderError(renderErrorProps: RenderErrorProps) {
})
}

// If hydrate does not exist, eg in preact.
let isInitialRender = typeof ReactDOM.hydrate === 'function'
let reactRoot: any = null
function renderReactElement(reactEl: JSX.Element, domEl: HTMLElement) {
if (process.env.__NEXT_REACT_MODE !== 'legacy') {
Expand All @@ -491,9 +494,8 @@ function renderReactElement(reactEl: JSX.Element, domEl: HTMLElement) {
}

// The check for `.hydrate` is there to support React alternatives like preact
if (isInitialRender) {
if (typeof ReactDOM.hydrate === 'function') {
ReactDOM.hydrate(reactEl, domEl, markHydrateComplete)
isInitialRender = false
} else {
ReactDOM.render(reactEl, domEl, markRenderComplete)
}
Expand Down Expand Up @@ -591,13 +593,10 @@ const wrapApp = (App: AppComponent) => (
)
}

function doRender({
App,
Component,
props,
err,
styleSheets,
}: RenderRouteInfo): Promise<any> {
function doRender(input: RenderRouteInfo): Promise<any> {
let { App, Component, props, err } = input
let styleSheets: StyleSheetTuple[] | undefined =
'initial' in input ? undefined : input.styleSheets
Component = Component || lastAppProps.Component
props = props || lastAppProps.props

Expand Down Expand Up @@ -634,9 +633,7 @@ function doRender({
// Promise. It should remain synchronous.
function onStart(): boolean {
if (
// We can skip this during hydration. Running it wont cause any harm, but
// we may as well save the CPU cycles.
isInitialRender ||
!styleSheets ||
// We use `style-loader` in development, so we don't need to do anything
// unless we're in production:
process.env.NODE_ENV !== 'production'
Expand Down Expand Up @@ -671,7 +668,7 @@ function doRender({
process.env.NODE_ENV === 'production' &&
// We can skip this during hydration. Running it wont cause any harm, but
// we may as well save the CPU cycles:
!isInitialRender &&
styleSheets &&
// Ensure this render was not canceled
!canceled
) {
Expand Down
Loading