1
0
Fork 0
mirror of https://github.com/terribleplan/next.js.git synced 2024-01-19 02:48:18 +00:00

Fallback to <script> loading behavior when preload is not supported (#5744)

Based on https://github.com/zeit/next.js/pull/5737#discussion_r236059295

This will cause a warning in chrome/safari after 3s
This commit is contained in:
Tim Neutkens 2018-11-26 23:58:40 +01:00 committed by GitHub
parent c178e98a67
commit 9d30e411b5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 27 additions and 16 deletions

View file

@ -2,18 +2,18 @@
import EventEmitter from 'next-server/dist/lib/EventEmitter'
// smaller version of https://gist.github.com/igrigorik/a02f2359f3bc50ca7a9c
function listSupports (list, token) {
function supportsPreload (list) {
if (!list || !list.supports) {
return false
}
try {
return list.supports(token)
return list.supports('preload')
} catch (e) {
return false
}
}
const supportsPrefetch = listSupports(document.createElement('link').relList, 'prefetch')
const hasPreload = supportsPreload(document.createElement('link').relList)
const webpackModule = module
export default class PageLoader {
@ -131,22 +131,33 @@ export default class PageLoader {
}
this.prefetchCache.add(scriptRoute)
const link = document.createElement('link')
// Feature detection is used to see if prefetch is supported, else fall back to preload
// Mainly this is for Safari
// https://caniuse.com/#feat=link-rel-prefetch
// Feature detection is used to see if preload is supported
// If not fall back to loading script tags before the page is loaded
// https://caniuse.com/#feat=link-rel-preload
link.rel = supportsPrefetch ? 'prefetch' : 'preload'
link.href = `${this.assetPrefix}/_next/static/${encodeURIComponent(this.buildId)}/pages${scriptRoute}`
link.as = 'script'
document.head.appendChild(link)
if (hasPreload) {
const link = document.createElement('link')
link.rel = 'preload'
link.href = `${this.assetPrefix}/_next/static/${encodeURIComponent(this.buildId)}/pages${scriptRoute}`
link.as = 'script'
document.head.appendChild(link)
return
}
if (document.readyState === 'complete') {
await this.loadPage(route)
} else {
return new Promise((resolve, reject) => {
window.addEventListener('load', () => {
this.loadPage(route).then(() => resolve(), reject)
})
})
}
}
clearCache (route) {
route = this.normalizeRoute(route)
delete this.pageCache[route]
delete this.loadingRoutes[route]
delete this.loadingRoutes[route]
const script = document.getElementById(`__NEXT_PAGE__${route}`)
if (script) {

View file

@ -210,15 +210,15 @@ describe('Production Usage', () => {
browser.close()
})
it('should add prefetch tags when Link prefetch prop is used', async () => {
it('should add preload tags when Link prefetch prop is used', async () => {
const browser = await webdriver(appPort, '/prefetch')
const elements = await browser.elementsByCss('link[rel=prefetch]')
expect(elements.length).toBe(4)
const elements = await browser.elementsByCss('link[rel=preload]')
expect(elements.length).toBe(10)
await Promise.all(
elements.map(async (element) => {
const rel = await element.getAttribute('rel')
const as = await element.getAttribute('as')
expect(rel).toBe('prefetch')
expect(rel).toBe('preload')
expect(as).toBe('script')
})
)