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

Consider extending <link> and Selectors #307

Open
zcorpan opened this issue Apr 5, 2024 · 4 comments
Open

Consider extending <link> and Selectors #307

zcorpan opened this issue Apr 5, 2024 · 4 comments

Comments

@zcorpan
Copy link

zcorpan commented Apr 5, 2024

From mozilla/standards-positions#620 (comment)

We (Mozilla) struggle a lot with the JSON syntax and the introduction of a new query language. We have Selectors, and it seems possible to add URL patterns to Selectors.

Furthermore, the rebuttals for <link> in the explainer can be solved without jumping to JSON syntax. The explainer even says that new rel values are possible. Since "prefetch" was changed to a subresource prefetch, now the terminology is confusing even with speculation rules vs link rel. Why not use nav-prerender and nav-prefetch as new rel values? And make them work on <a> also, to enable prerendering or prefetching a specific link, where all of the existing attributes can apply (like target, referrerpolicy, etc)? Listing multiple URLs can be a new space-separated or comma-separated attribute (like srcset).

Example:

<link rel="nav-prerender" selector=":link-href('/*'):not(:link-href('/logout?*'), .no-prefetch *)">
<link rel="nav-prefetch" hrefset="next.html, next2.html" requires="anonymous-client-ip-when-cross-origin" referrerpolicy="no-referrer">
...
<a href="other.html" target="_blank" rel="nav-prerender">other</a>

The motivation for external speculation rules is "it would be convenient", but that could apply to any HTML metadata? Is it necessary to support external rules?

@tunetheweb
Copy link

selector can get complicated though.

I stared at your relatively simple example (selector=":link-href('/*'):not(:link-href('/logout?*'), .no-prefetch *)) for a long time there trying to understand it and match up the parentheses. I still don't understand why you have the last * in there.

And I'm very familiar with speculation rules!

JSON allows easier formatting in therefore understanding and/or spotting errors.

I find the original example that was based upon much easier to grok:

{
  "prerender": [
    {"where": {"and": [
       {"href_matches": "/*"},
       {"not": {"href_matches": "/logout"}},
       {"not": {"selector_matches": ".no-prerender"}}
     ]}}
  ]
}

Now tooling could of course translate between the two but if needing to do that all the time, then maybe that's the better format.

@zcorpan
Copy link
Author

zcorpan commented Apr 5, 2024

I took the .no-prefetch * example from w3ctag/design-reviews#721 (comment)

It's possible to do linebreaks and indentation within the selector to make it easier to read:

<link rel="nav-prerender" selector="
  :link-href('/*'):not(
    :link-href('/logout'),
    .no-prerender
  )">

@tunetheweb
Copy link

tunetheweb commented Apr 5, 2024

Ah gotcha. Slightly different example but close enough to the one in the explainer you linked to cause me confusion! 😀

@domenic
Copy link
Collaborator

domenic commented Apr 19, 2024

Thanks for filing this!

I think this is the unfortunate result of having to guess at others' feedback. When we started requesting wide review for this project over two years ago, the team had similar discussions and questions. In the absence of feedback, we had to guess: which path would be most palatable to the web developer community and to other implementers?

At the time, I argued that other vendors generally did not like inventing new microsyntaxes, and would not like repurposing an element like <link> to no longer be a link, and would not like adding new attributes that only apply to a few rel=""s. (Or would you be able to do things like <link rel="stylesheet" hrefset="a.css, b.css">? <link rel="preload" selector=".carousel img">? We anticipated such general functionality would also get pushback based on its complexity.) I argued that the precedent of web app manifests and import maps for storing metadata in JSON was a good model to follow, and would be appreciated over using HTML.

It seems like, at least in Mozilla's case, my arguments were incorrect, and so we guessed wrong. Where do we go from here?

At this point we have almost 4% of page loads using this feature, from many origins. And so far over the two years of shipping this feature we haven't heard any web developer complaints about the use of JSON over HTML.

Still, your proposed syntax seems pretty reasonable. We'd be willing to consider implementing it in Chromium if you're able to find evidence that doing so would significantly move developer sentiment, or if doing so would bring us into interoperability with Mozilla's implementation. It's also possible that some subsets of it would be more exciting to developers than others, e.g. maybe the CSSWG would be a receptive to your proposal for a :link-href() selector.

And make them work on <a> also, to enable prerendering or prefetching a specific link, where all of the existing attributes can apply (like target, referrerpolicy, etc)?

We've explored this, in reaction to the TAG feedback which suggested that simple solutions would be appreciated. Somewhat surprisingly, all the developers we talked to so far were lukewarm about this, and none said they would use it on their sites. The general sentiment was that the full power of speculation rules was necessary for many of their use cases, and that introducing something new that only worked for very simple cases would confuse the landscape and be hard to teach. We still kind of like it as an idea, but without any developer interest we've currently put it on hold.

The motivation for external speculation rules is "it would be convenient", but that could apply to any HTML metadata? Is it necessary to support external rules?

We built this for some significant cases where platforms (e.g. CMSes or CDNs) wanted to inject speculation rules without modifying the HTML they were serving. I think that wanting to inject such speed optimizations is generally more common than wanting to inject other HTML metadata.

It's possible we could do this by putting the speculation rules themselves into a HTTP header, instead of using a link to an external file containing the speculation rules. (Either in JSON format, or in some sort of structured-header format, or maybe some extension of the Link: <url> header.) But the folks we talked to were not excited about how that would be maintained, and how it could potentially bloat the headers.

It's also the case that, unlike <link rel="stylesheet">, <link rel="preload">, or other various other metadata, loading speculation rules does not have to be done on the critical path, since any speculations will happen in idle time anyway. So an external file is an especially good fit for this particular metadata.

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

No branches or pull requests

3 participants