Skip to content

Commit f51d4c6

Browse files
authored
Fix duplicate links not being preloaded (#403)
- Index visible links by href first, by element second - Fixes issue #387 where duplicate links with identical hrefs won't preload at all if one link is visible and another one isn't
1 parent 3c52827 commit f51d4c6

File tree

3 files changed

+11
-9
lines changed

3 files changed

+11
-9
lines changed

src/index.mjs

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ export function listen(options = {}) {
103103
const allowed = options.origins || [location.hostname];
104104
const ignores = options.ignores || [];
105105
const delay = options.delay || 0;
106-
const hrefsInViewport = [];
106+
const hrefsInViewport = new Map();
107107
const specRulesInViewport = new Map();
108108

109109
const timeoutFn = options.timeoutFn || requestIdleCallback;
@@ -123,16 +123,19 @@ export function listen(options = {}) {
123123

124124
const observer = new IntersectionObserver(entries => {
125125
for (let entry of entries) {
126+
const set = hrefsInViewport.get(entry.target.href) || new Set();
127+
hrefsInViewport.set(entry.target.href, set);
128+
126129
// On enter
127130
if (entry.isIntersecting) {
128131
entry = entry.target;
129-
// Adding href to array of hrefsInViewport
130-
hrefsInViewport.push(entry.href);
132+
// Adding href to set of hrefsInViewport
133+
set.add(entry);
131134

132135
// Setting timeout
133136
setTimeoutIfDelay(() => {
134137
// Do not prefetch if not found in viewport
135-
if (!hrefsInViewport.includes(entry.href)) return;
138+
if (!set || !set.size) return;
136139

137140
if (!shouldOnlyPrerender && !shouldPrerenderAndPrefetch) {
138141
observer.unobserve(entry);
@@ -185,11 +188,7 @@ export function listen(options = {}) {
185188
// On exit
186189
} else {
187190
entry = entry.target;
188-
const index = hrefsInViewport.indexOf(entry.href);
189-
190-
if (index !== -1) {
191-
hrefsInViewport.splice(index);
192-
}
191+
set.delete(entry);
193192

194193
if (specRulesInViewport.has(entry.href)) {
195194
specRulesInViewport.set(removeSpeculationRule(specRulesInViewport, entry.href));

test/fixtures/test-basic-usage.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
<a href="main.css">CSS</a>
1717
</section>
1818
<a href="4.html" style="position:absolute;margin-top:900px;">Link 4</a>
19+
<a href="1.html" style="position:absolute;margin-top:1000px;">Link 1 again</a>
1920
<script src="../../dist/quicklink.umd.js"></script>
2021
<script>
2122
quicklink.listen();

test/quicklink.spec.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ mainSuite('should prefetch in-viewport links correctly (UMD)', async context =>
4040
assert.ok(responseURLs.includes(`${server}/1.html`));
4141
assert.ok(responseURLs.includes(`${server}/2.html`));
4242
assert.ok(responseURLs.includes(`${server}/3.html`));
43+
assert.ok(!responseURLs.includes(`${server}/4.html`));
4344
});
4445

4546
mainSuite('should prefetch in-viewport links correctly (ES Modules)', async context => {
@@ -53,6 +54,7 @@ mainSuite('should prefetch in-viewport links correctly (ES Modules)', async cont
5354
assert.ok(responseURLs.includes(`${server}/1.html`));
5455
assert.ok(responseURLs.includes(`${server}/2.html`));
5556
assert.ok(responseURLs.includes(`${server}/3.html`));
57+
assert.ok(!responseURLs.includes(`${server}/4.html`));
5658
});
5759

5860
mainSuite('should prefetch in-viewport links that scroll into view correctly (UMD)', async context => {

0 commit comments

Comments
 (0)