Skip to content

Commit

Permalink
Speculate Navigations for Client-Side JS
Browse files Browse the repository at this point in the history
  • Loading branch information
Timer committed Feb 17, 2020
1 parent 9cfc09e commit ac46941
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 17 deletions.
26 changes: 15 additions & 11 deletions packages/next/client/link.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
declare const __NEXT_DATA__: any

import { resolve, parse, UrlObject } from 'url'
import React, { Component, Children } from 'react'
import Router from './router'
import React, { Children, Component } from 'react'
import { parse, resolve, UrlObject } from 'url'
import {
execOnce,
formatWithValidation,
getLocationOrigin,
} from '../next-server/lib/utils'
import Router from './router'

function isLocal(href: string) {
const url = parse(href, false, true)
Expand Down Expand Up @@ -127,14 +127,18 @@ class Link extends Component<LinkProps> {
this.cleanUpListeners()
}

getHref() {
getPaths() {
const { pathname } = window.location
const { href: parsedHref } = this.formatUrls(this.props.href, this.props.as)
return resolve(pathname, parsedHref)
const { href: parsedHref, as: parsedAs } = this.formatUrls(
this.props.href,
this.props.as
)
const resolvedHref = resolve(pathname, parsedHref)
return [resolvedHref, parsedAs ? resolve(pathname, parsedAs) : resolvedHref]
}

handleRef(ref: Element) {
const isPrefetched = prefetched[this.getHref()]
const isPrefetched = prefetched[this.getPaths()[0]]
if (this.p && IntersectionObserver && ref && ref.tagName) {
this.cleanUpListeners()

Expand Down Expand Up @@ -201,11 +205,11 @@ class Link extends Component<LinkProps> {
})
}

prefetch() {
prefetch(options: { priority?: boolean } = {}) {
if (!this.p || typeof window === 'undefined') return
// Prefetch the JSON page if asked (only in the client)
const href = this.getHref()
Router.prefetch(href)
const [href, asPath] = this.getPaths()
Router.prefetch(href, asPath, { priority: options.priority })
prefetched[href] = true
}

Expand Down Expand Up @@ -239,7 +243,7 @@ class Link extends Component<LinkProps> {
if (child.props && typeof child.props.onMouseEnter === 'function') {
child.props.onMouseEnter(e)
}
this.prefetch()
this.prefetch({ priority: true })
},
onClick: (e: React.MouseEvent) => {
if (child.props && typeof child.props.onClick === 'function') {
Expand Down
17 changes: 11 additions & 6 deletions packages/next/next-server/lib/router/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import { ParsedUrlQuery } from 'querystring'
import { ComponentType } from 'react'
import { parse, UrlObject } from 'url'

import mitt, { MittEmitter } from '../mitt'
import {
AppContextType,
Expand Down Expand Up @@ -652,11 +651,16 @@ export default class Router implements BaseRouter {
}

/**
* Prefetch `page` code, you may wait for the data during `page` rendering.
* Prefetch page code, you may wait for the data during page rendering.
* This feature only works in production!
* @param url of prefetched `page`
* @param url the href of prefetched page
* @param asPath the as path of the prefetched page
*/
prefetch(url: string): Promise<void> {
prefetch(
url: string,
asPath: string = url,
options: { priority?: boolean } = {}
): Promise<void> {
return new Promise((resolve, reject) => {
const { pathname, protocol } = parse(url)

Expand All @@ -674,8 +678,9 @@ export default class Router implements BaseRouter {
return
}

const route = toRoute(pathname)
this.pageLoader.prefetch(route).then(resolve, reject)
this.pageLoader[options.priority ? 'loadPage' : 'prefetch'](
toRoute(pathname)
).then(() => resolve(), reject)
})
}

Expand Down

0 comments on commit ac46941

Please sign in to comment.