The Problem
You're using a loading progress bar like the one shown below, but your website is fast enough for it to flash for a few milliseconds and disappear near instantly. This can make users feel that your website is slower than it actually is.
The Solution
Display a progress bar only if the request takes "too long." A good duration to use 200ms.
The Code
const progressFns = () => {
let progressTimeout, count = 0
const start = () => {
count++
progressTimeout = setTimeout(() => {
NProgress.start()
}, 200)
}
const stop = () => {
count = Math.max(0, count - 1)
if (count > 0) return
NProgress.done()
clearTimeout(progressTimeout)
}
return { start, stop }
}
progressFns
returns an object with two functions:
start
to queue the progress bar for display after 200msstop
to hide the progress bar
It also keeps track of how many requests are in progress and only hides the bar when the last one is done. Usually you would intercept your request library and/or Vue Router's requests and show/hide the progress bar as needed.
Usage
Get instances of the functions:
const {
start: progressStart,
stop: progressStop,
} = progressFns()
Vue.js
router.beforeResolve((to, from, next) => {
if (to.name) {
progressStart()
}
next()
})
router.afterEach((to, from) => {
progressStop()
})
Axios
window.axios.interceptors.request.use(config => {
if (!config.__noProgress) progressStart()
return config
}, error => {
progressStop()
return Promise.reject(error)
})
window.axios.interceptors.response.use(response => {
if (!response.config.__noProgress) progressStop()
return response
}, error => {
progressStop()
return Promise.reject(error)
})
Checking config.__noProgress
lets me selectively disable the progress bar completely for certain requests, like so:
axios
.get("/auth/me", { __noProgress: true })
...
Thanks to Next.js 7 for making me aware of this!
https://github.com/jamiebuilds/react-loadable#avoiding-flash-of-loading-component