Skip to content

Commit 5a76c7a

Browse files
committed
fix: more resilient system for page pre-rendering
1 parent 8d89ab5 commit 5a76c7a

File tree

3 files changed

+32
-25
lines changed

3 files changed

+32
-25
lines changed

packages/smooth/src/page/Page.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import App from '__smooth_app'
44
import Content from '__smooth_content'
55
import { applyHook } from '../plugin/browser'
66
import { PageContextProvider } from './PageContext'
7+
import { usePause } from '../router/HiddenRouter'
78

89
function getFileName(filePath) {
910
return filePath.replace(/^\.\//, '').replace(/\.js$/, '')
@@ -110,9 +111,11 @@ export default function Page({
110111
location,
111112
}) {
112113
const pageRef = usePageRef(page)
114+
const unpause = usePause()
113115
return (
114116
<page.LoadableComponent>
115117
{pageModule => {
118+
unpause()
116119
enrichPageRef(pageRef, {
117120
module: pageModule,
118121
indexUrl,

packages/smooth/src/query/Query.js

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import React, { useRef, useEffect } from 'react'
1+
import React, { useEffect } from 'react'
22
import qs from 'query-string'
33
import { Query as ApolloQuery } from 'react-apollo'
44
import { usePageContext } from '../page/PageContext'
5-
import { useHiddenRouter } from '../router/HiddenRouter'
5+
import { usePause } from '../router/HiddenRouter'
66

77
function getQueryContext(location, lang) {
88
const { id, preview } = qs.parse(location.search)
@@ -21,24 +21,12 @@ function getQueryContext(location, lang) {
2121
}
2222

2323
function PrefetchHandler({ children, ...props }) {
24-
const hiddenRouter = useHiddenRouter()
25-
const resolveRef = useRef()
26-
const { loading } = props
24+
const unpause = usePause()
2725
useEffect(() => {
28-
if (!hiddenRouter) return
29-
if (loading) {
30-
hiddenRouter.waitForPromise(
31-
new Promise(resolve => {
32-
resolveRef.current = resolve
33-
}),
34-
)
35-
return
26+
if (!props.loading) {
27+
unpause()
3628
}
37-
if (resolveRef.current) {
38-
resolveRef.current()
39-
}
40-
}, [loading]) // eslint-disable-line react-hooks/exhaustive-deps
41-
29+
}, [props.loading, unpause])
4230
return children(props)
4331
}
4432

packages/smooth/src/router/HiddenRouter.js

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import React, {
2-
useEffect,
32
useRef,
43
useCallback,
54
createContext,
65
useContext,
76
useMemo,
7+
useEffect,
88
} from 'react'
99
import { createPath } from 'history'
1010
import { Router, withRouter } from 'react-router-dom'
@@ -16,6 +16,24 @@ export function useHiddenRouter() {
1616
return useContext(HiddenRouterContext)
1717
}
1818

19+
export function usePause() {
20+
const resolve = useRef()
21+
const promise = useMemo(
22+
() =>
23+
new Promise(r => {
24+
resolve.current = r
25+
}),
26+
[],
27+
)
28+
const hiddenRouter = useHiddenRouter()
29+
useEffect(() => {
30+
if (hiddenRouter) {
31+
hiddenRouter.waitForPromise(promise)
32+
}
33+
}, [hiddenRouter, promise])
34+
return resolve.current
35+
}
36+
1937
function createURL(location) {
2038
return typeof location === 'string' ? location : createPath(location)
2139
}
@@ -33,12 +51,15 @@ function HiddenRouter({ history, children }) {
3351

3452
const waitForPromise = useCallback(
3553
promise => {
54+
if (promises.current.includes(promise)) return
3655
promise.then(() => {
3756
const index = promises.current.indexOf(promise)
3857
if (index !== -1) {
3958
promises.current.splice(index, 1)
4059
}
41-
flush()
60+
// 65ms is 4 frames, pretty invisible when we change page
61+
// it ensures that React have time to start a new request for an example
62+
setTimeout(() => flush(), 65)
4263
})
4364
promises.current.push(promise)
4465
},
@@ -47,11 +68,6 @@ function HiddenRouter({ history, children }) {
4768

4869
const hiddenRouter = useMemo(() => ({ waitForPromise }), [waitForPromise])
4970

50-
useEffect(() => {
51-
const timeout = setTimeout(() => flush(), 20)
52-
return () => clearTimeout(timeout)
53-
}, [flush])
54-
5571
const staticHistory = useMemo(() => {
5672
if (!hiddenHistory.location) return null
5773
const noop = () => {}

0 commit comments

Comments
 (0)