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

delay page transition until we have all resources #6158

Merged
merged 1 commit into from
Jun 26, 2018
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 10 additions & 8 deletions packages/gatsby-plugin-nprogress/src/gatsby-browser.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,6 @@ exports.onClientEntry = (a, pluginOptions = {}) => {
// Merge default options with user defined options in `gatsby-config.js`
const options = { ...defaultOptions, ...pluginOptions }

window.___emitter.on(`onDelayedLoadPageResources`, () => {
NProgress.configure(options)
NProgress.start()
})
window.___emitter.on(`onPostLoadPageResources`, () => {
NProgress.done()
})

// Inject styles.
const styles = `
#nprogress {
Expand Down Expand Up @@ -88,4 +80,14 @@ exports.onClientEntry = (a, pluginOptions = {}) => {
node.id = `nprogress-styles`
node.innerHTML = styles
document.head.appendChild(node)

NProgress.configure(options)
}

exports.onRouteUpdateDelayed = () => {
NProgress.start()
}

exports.onRouteUpdate = () => {
NProgress.done()
}
51 changes: 32 additions & 19 deletions packages/gatsby/src/cache-dir/production-app.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ apiRunnerAsync(`onClientEntry`).then(() => {
require(`./register-service-worker`)
}

let lastNavigateToLocationString = null

const navigate = (to, replace) => {
const location = createLocation(to, null, null, history.location)
let { pathname } = location
Expand All @@ -77,33 +79,36 @@ apiRunnerAsync(`onClientEntry`).then(() => {
? window.___history.replace
: window.___history.push

// Listen to loading events. If page resources load before
// a second, navigate immediately.
function eventHandler(e) {
if (e.page.path === loader.getPage(pathname).path) {
emitter.off(`onPostLoadPageResources`, eventHandler)
clearTimeout(timeoutId)
historyNavigateFunc(location)
}
}
const historyNavigateAction = replace
? `REPLACE`
: `PUSH`

// Start a timer to wait for a second before transitioning and showing a
// loader in case resources aren't around yet.
const timeoutId = setTimeout(() => {
emitter.off(`onPostLoadPageResources`, eventHandler)
emitter.emit(`onDelayedLoadPageResources`, { pathname })
historyNavigateFunc(location)
apiRunner(`onRouteUpdateDelayed`, { location, action: historyNavigateAction })
}, 1000)

if (loader.getResourcesForPathname(pathname)) {
// The resources are already loaded so off we go.
clearTimeout(timeoutId)
historyNavigateFunc(location)
} else {
// They're not loaded yet so let's add a listener for when
// they finish loading.
emitter.on(`onPostLoadPageResources`, eventHandler)
lastNavigateToLocationString = `${location.pathname}${location.search}${
location.hash
}`

apiRunner(`onPreRouteUpdate`, { location, action: historyNavigateAction })

const loaderCallback = pageResources => {
if (!pageResources) {
// We fetch resources for 404 page in page-renderer.js. Calling it
// here is to ensure that we have needed resouces to render page
// before navigating to it
loader.getResourcesForPathname(`/404.html`, loaderCallback)
} else {
clearTimeout(timeoutId)
historyNavigateFunc(location)
}
}

loader.getResourcesForPathname(pathname, loaderCallback)
}

// window.___loadScriptsForPath = loadScriptsForPath
Expand All @@ -124,6 +129,14 @@ apiRunnerAsync(`onClientEntry`).then(() => {

history.listen((location, action) => {
if (!maybeRedirect(location.pathname)) {
// Check if we already ran onPreRouteUpdate API
// in navigateTo function
if (
lastNavigateToLocationString !==
`${location.pathname}${location.search}${location.hash}`
) {
apiRunner(`onPreRouteUpdate`, { location, action })
}
// Make sure React has had a chance to flush to DOM first.
setTimeout(() => {
apiRunner(`onRouteUpdate`, { location, action })
Expand Down
1 change: 1 addition & 0 deletions packages/gatsby/src/cache-dir/root.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ function attachToHistory(history) {

history.listen((location, action) => {
if (!maybeRedirect(location.pathname)) {
apiRunner(`onPreRouteUpdate`, { location, action })
apiRunner(`onRouteUpdate`, { location, action })
}
})
Expand Down
24 changes: 24 additions & 0 deletions packages/gatsby/src/utils/api-browser-docs.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,30 @@ exports.onClientEntry = true
*/
exports.onInitialClientRender = true

/**
* Called when changing location is started.
* @param {object} $0
* @param {object} $0.location A location object
* @param {object} $0.action The "action" that caused the route change
* @example
* exports.onPreRouteUpdate = ({ location }) => {
* console.log("Gatsby started to change location", location.pathname)
* }
*/
exports.onPreRouteUpdate = true

/**
* Called when changing location is longer than 1 second.
* @param {object} $0
* @param {object} $0.location A location object
* @param {object} $0.action The "action" that caused the route change
* @example
* exports.onRouteUpdateDelayed = () => {
* console.log("We can show loading indicator now")
* }
*/
exports.onRouteUpdateDelayed = true

/**
* Called when the user changes routes
* @param {object} $0
Expand Down