Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Normalize URLs before checking the toPrefetch set #28

Closed
mathiasbynens opened this issue Dec 13, 2018 · 5 comments
Closed

Normalize URLs before checking the toPrefetch set #28

mathiasbynens opened this issue Dec 13, 2018 · 5 comments
Labels
enhancement New feature or request

Comments

@mathiasbynens
Copy link
Member

mathiasbynens commented Dec 13, 2018

For example, these three URLs are all equivalent:

https://www.google.com
https://www.google.com/
https:\\www.google.com/

(That last one is an extreme example, but it’s pretty common to see the first and second variation used interchangeably.)

When reading an element’s .href like in

const url = entry.target.href;
, you’d get the following normalized URL for each of those three:

https://www.google.com/

However, the same normalization is not applied when the user manually passes in URLs:

options.urls.forEach(prefetcher);

Because of this, the toPrefetch set currently ends up with three separate entries in this case, even though all of them normalize to the same URL:

quicklink({
   urls: [
    'https://www.google.com',
    'https://www.google.com/',
    'https:\\www.google.com/',
  ],
});

It can be solved by forcing URL normalization before calling prefetcher on this line:

options.urls.forEach(prefetcher);

-      options.urls.forEach(prefetcher);
+      options.urls.forEach(url => prefetcher(new URL(url).toString()));
@mathiasbynens mathiasbynens changed the title Normalize URLs before adding them to the set Normalize URLs before checking the toPrefetch set Dec 13, 2018
@addyosmani
Copy link
Collaborator

addyosmani commented Dec 13, 2018

This is a great catch. Nice work highlighting the normalization issue, @mathiasbynens ❤️ Given URL() has pretty decent cross-browser support, I'm happy for us to use your suggested change in some form. We probably want to sanity check if normalization should happen elsewhere in index.mjs.

Do you want to PR a fix? If not, happy to patch directly :)

@addyosmani addyosmani added the enhancement New feature or request label Dec 13, 2018
@lukeed
Copy link
Contributor

lukeed commented Dec 13, 2018

Nothing gets added to toPrefetch when you pass in an options.url list. The prefetcher only looks to remove Set entries – additions are made thru the "scraped" links which are already normalized as you mentioned.

That said, we should still probably normalize so that the prefetch itself can send valid requests. Eg, fetch('https:\\www.google.com/') will fail.

IMO, normalization should happen here: https://github.com/GoogleChromeLabs/quicklink/blob/master/src/index.mjs#L37

It'll be redundant for the "scraped" links, but it avoids adding a new function 😇

@addyosmani
Copy link
Collaborator

@lukeed Hah. Avoiding the addition of a new function is fair. Were you thinking of normalization around L37 looking similar to this?

function prefetcher(url) {
  const nURL = new URL(url).toString();
  toPrefetch.delete(nURL);
  prefetch(nURL, observer.priority);
}

@lukeed
Copy link
Contributor

lukeed commented Dec 13, 2018

I blame Jason 🙃

Was thinking this:

function prefetcher(url) {
 toPrefetch.delete(url);
 prefetch(new URL(url).toString(), observer.priority);
}

Since anything that makes its way into toPrefetch is already normalized. If we introduce some way for option.urls to coexist within the Set, then yes, the whole Set has to be normalized on entry and/or removal


Edit: We can also just do prefetch(new URL(url), priority) since fetch() will accept an URL or string & I just discovered that XHR will also work with a URL instance. 🎉

@addyosmani
Copy link
Collaborator

Closed by #37. Thanks again!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants