Skip to content

Commit cdf89ef

Browse files
Allow customizing the delay for InstantClick behavior
1 parent f4bbb77 commit cdf89ef

7 files changed

+155
-7
lines changed

src/core/drive/prefetch_cache.js

+20-6
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,16 @@ class PrefetchCache {
1010
}
1111
}
1212

13-
setLater(url, request, ttl) {
13+
setLater(url, request, ttl, delay) {
1414
this.clear()
1515

16-
this.#prefetchTimeout = setTimeout(() => {
17-
request.perform()
18-
this.set(url, request, ttl)
19-
this.#prefetchTimeout = null
20-
}, PREFETCH_DELAY)
16+
if (delay === "0") {
17+
this.#setNow(url, request, ttl)
18+
} else {
19+
delay = Number(delay) || PREFETCH_DELAY
20+
21+
this.#enqueue(url, request, ttl, delay)
22+
}
2123
}
2224

2325
set(url, request, ttl) {
@@ -28,6 +30,18 @@ class PrefetchCache {
2830
if (this.#prefetchTimeout) clearTimeout(this.#prefetchTimeout)
2931
this.#prefetched = null
3032
}
33+
34+
#enqueue(url, request, ttl, delay) {
35+
this.#prefetchTimeout = setTimeout(() => {
36+
this.#setNow(url, request, ttl)
37+
this.#prefetchTimeout = null
38+
}, delay)
39+
}
40+
41+
#setNow(url, request, ttl) {
42+
request.perform()
43+
this.set(url, request, ttl)
44+
}
3145
}
3246

3347
export const cacheTtl = 10 * 1000

src/observers/link_prefetch_observer.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,9 @@ export class LinkPrefetchObserver {
7676
target
7777
)
7878

79-
prefetchCache.setLater(location.toString(), fetchRequest, this.#cacheTtl)
79+
const delay = link.dataset.turboPrefetchDelay || getMetaContent("turbo-prefetch-delay")
80+
81+
prefetchCache.setLater(location.toString(), fetchRequest, this.#cacheTtl, delay)
8082

8183
link.addEventListener("mouseleave", () => prefetchCache.clear(), { once: true })
8284
}

src/tests/fixtures/hover_to_prefetch.html

+3
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@
1414
<span>Hover to prefetch me</span>
1515
</a>
1616
<a href="/src/tests/fixtures/prefetched.html" id="anchor_with_turbo_stream" data-turbo-stream>Hover to prefetch me</a>
17+
<a href="/src/tests/fixtures/prefetched.html" id="anchor_with_custom_delay" data-turbo-prefetch-delay="300">Hover to prefetch me</a>
18+
<a href="/src/tests/fixtures/prefetched.html" id="anchor_with_zero_delay" data-turbo-prefetch-delay="0">Hover to prefetch me</a>
19+
<a href="/src/tests/fixtures/prefetched.html" id="anchor_with_invalid_delay" data-turbo-prefetch-delay="bad">Hover to prefetch me</a>
1720
<div data-turbo="false">
1821
<a href="/src/tests/fixtures/prefetched.html" id="anchor_with_turbo_false_parent">Won't prefetch when hovering me</a>
1922
</div>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8" />
5+
<title>Hover to Prefetch</title>
6+
<script src="/dist/turbo.es2017-umd.js" data-turbo-track="reload"></script>
7+
<meta name="turbo-prefetch" content="true" />
8+
<meta name="turbo-prefetch-delay" content="300" />
9+
</head>
10+
11+
<body>
12+
<a href="/src/tests/fixtures/prefetched.html" id="anchor_for_prefetch">Hover to prefetch me</a>
13+
</body>
14+
</html>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8" />
5+
<title>Hover to Prefetch</title>
6+
<script src="/dist/turbo.es2017-umd.js" data-turbo-track="reload"></script>
7+
<meta name="turbo-prefetch" content="true" />
8+
<meta name="turbo-prefetch-delay" content="bad" />
9+
</head>
10+
11+
<body>
12+
<a href="/src/tests/fixtures/prefetched.html" id="anchor_for_prefetch">Hover to prefetch me</a>
13+
</body>
14+
</html>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8" />
5+
<title>Hover to Prefetch</title>
6+
<script src="/dist/turbo.es2017-umd.js" data-turbo-track="reload"></script>
7+
<meta name="turbo-prefetch" content="true" />
8+
<meta name="turbo-prefetch-delay" content="0" />
9+
</head>
10+
11+
<body>
12+
<a href="/src/tests/fixtures/prefetched.html" id="anchor_for_prefetch">Hover to prefetch me</a>
13+
</body>
14+
</html>

src/tests/functional/link_prefetch_observer_tests.js

+87
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,93 @@ test("it prefetches links with a delay", async ({ page }) => {
188188
assertRequestMade(requestMade)
189189
})
190190

191+
test("it allows to customize the delay with a data-turbo-prefetch-delay attribute", async ({ page }) => {
192+
await goTo({ page, path: "/hover_to_prefetch.html" })
193+
194+
let requestMade = false
195+
page.on("request", async (request) => (requestMade = true))
196+
197+
await page.hover("#anchor_with_custom_delay")
198+
await sleep(200)
199+
200+
assertRequestNotMade(requestMade)
201+
202+
await sleep(150)
203+
204+
assertRequestMade(requestMade)
205+
})
206+
207+
test("it allows to customize the delay with a turbo-prefetch-delay a meta tag", async ({ page }) => {
208+
await goTo({ page, path: "/hover_to_prefetch_with_delay_on_meta_tag.html" })
209+
210+
let requestMade = false
211+
page.on("request", async (request) => (requestMade = true))
212+
213+
await page.hover("#anchor_for_prefetch")
214+
215+
await sleep(200)
216+
217+
assertRequestNotMade(requestMade)
218+
219+
await sleep(150)
220+
221+
assertRequestMade(requestMade)
222+
})
223+
224+
test("it prefetches immediately with a data-turbo-prefetch-delay attribute set to 0", async ({ page }) => {
225+
await goTo({ page, path: "/hover_to_prefetch.html" })
226+
227+
let requestMade = false
228+
page.on("request", async (request) => (requestMade = true))
229+
230+
await page.hover("#anchor_with_zero_delay")
231+
232+
assertRequestMade(requestMade)
233+
})
234+
235+
test("it prefetches immediately with a turbo-prefetch-delay meta tag set to 0", async ({ page }) => {
236+
await goTo({ page, path: "/hover_to_prefetch_with_zero_delay_on_meta_tag.html" })
237+
238+
let requestMade = false
239+
page.on("request", async (request) => (requestMade = true))
240+
241+
await page.hover("#anchor_for_prefetch")
242+
243+
assertRequestMade(requestMade)
244+
})
245+
246+
test("it uses the default delay with a data-turbo-prefetch-delay attribute set to an invalid value", async ({ page }) => {
247+
await goTo({ page, path: "/hover_to_prefetch.html" })
248+
249+
let requestMade = false
250+
page.on("request", async (request) => (requestMade = true))
251+
252+
await page.hover("#anchor_with_invalid_delay")
253+
await sleep(75)
254+
255+
assertRequestNotMade(requestMade)
256+
257+
await sleep(100)
258+
259+
assertRequestMade(requestMade)
260+
})
261+
262+
test("it uses the default delay with a turbo-prefetch-delay meta tag set to an invalid value", async ({ page }) => {
263+
await goTo({ page, path: "/hover_to_prefetch_with_invalid_delay_on_meta_tag.html" })
264+
265+
let requestMade = false
266+
page.on("request", async (request) => (requestMade = true))
267+
268+
await page.hover("#anchor_for_prefetch")
269+
await sleep(75)
270+
271+
assertRequestNotMade(requestMade)
272+
273+
await sleep(100)
274+
275+
assertRequestMade(requestMade)
276+
})
277+
191278
test("it cancels the prefetch request if the link is no longer hovered", async ({ page }) => {
192279
await goTo({ page, path: "/hover_to_prefetch.html" })
193280

0 commit comments

Comments
 (0)