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:
parent
c178e98a67
commit
9d30e411b5
|
@ -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) {
|
||||
|
|
|
@ -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')
|
||||
})
|
||||
)
|
||||
|
|
Loading…
Reference in a new issue