Skip to content

Commit 8540821

Browse files
daunXhmikosR
authored andcommitted
Fix duplicate links not being preloaded
- 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 c8410f7 commit 8540821

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
@@ -101,7 +101,7 @@ export function listen(options = {}) {
101101
const allowed = options.origins || [location.hostname];
102102
const ignores = options.ignores || [];
103103
const delay = options.delay || 0;
104-
const hrefsInViewport = [];
104+
const hrefsInViewport = new Map();
105105
const specRulesInViewport = new Map();
106106

107107
const timeoutFn = options.timeoutFn || requestIdleCallback;
@@ -121,16 +121,19 @@ export function listen(options = {}) {
121121

122122
const observer = new IntersectionObserver(entries => {
123123
entries.forEach(entry => {
124+
const set = hrefsInViewport.get(entry.target.href) || new Set();
125+
hrefsInViewport.set(entry.target.href, set);
126+
124127
// On enter
125128
if (entry.isIntersecting) {
126129
entry = entry.target;
127-
// Adding href to array of hrefsInViewport
128-
hrefsInViewport.push(entry.href);
130+
// Adding href to set of hrefsInViewport
131+
set.add(entry);
129132

130133
// Setting timeout
131134
setTimeoutIfDelay(() => {
132135
// Do not prefetch if not found in viewport
133-
if (!hrefsInViewport.includes(entry.href)) return;
136+
if (!set || !set.size) return;
134137

135138
if (!shouldOnlyPrerender && !shouldPrerenderAndPrefetch) {
136139
observer.unobserve(entry);
@@ -174,11 +177,7 @@ export function listen(options = {}) {
174177
// On exit
175178
} else {
176179
entry = entry.target;
177-
const index = hrefsInViewport.indexOf(entry.href);
178-
179-
if (index > -1) {
180-
hrefsInViewport.splice(index);
181-
}
180+
set.delete(entry);
182181

183182
if (specRulesInViewport.has(entry.href)) {
184183
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)