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

Add support for Speculation Rules #3292

Open
tunetheweb opened this issue May 23, 2024 · 8 comments
Open

Add support for Speculation Rules #3292

tunetheweb opened this issue May 23, 2024 · 8 comments

Comments

@tunetheweb
Copy link

tunetheweb commented May 23, 2024

Is your feature request related to a problem? Please describe.

Chrome has recently launched the Speculation Rules API which provides a way of a page telling the browser to prefetch or prerender a future navigation with a simple JSON-based objected added to the page (or referred to from an HTTP Header), which either lists the list of URLs, or gives details of hrefs patterns or CSS selector matches to find links on the page. I recently presented on this at Google I/O 2024, which provides a good summary for those willing to sit through my jammering on about it for 30mins.

Speculation Rules is for full page, browser-controlled, navigations (some people use the "MPA" term, but I like to call them "webpages" 🙂), which means they are ideally suited for SSG sites using things like 11ty!

While SSG sites often are fast by default, faster perf is always a good thing IMHO, as long as the balance between effort versus reward makes it worthwhile—which we believe it is for this API.

Describe the solution you'd like

I'm wondering what opportunities there are to more fully integrate this into 11ty?

  • Could there be a default Speculation Ruleset that's easily enabled with a config option? Or should it be enabled by default with an option to disable it?
  • Should we expose an API to set a speculation rule (either to add/remove from a default or to set it?).
  • Should 11ty apply additional heuristics beyond those exposed by the API (which currently is basically speculate immediately, on hover, or on pointerdown)?
  • Something else?

I realise this is a fairly open ended question, but keen to hear the community's thoughts on this. I'm more than willing to answer any questions, and even help with any implementation here.

Describe alternatives you've considered

I did consider a plugin for this, and had a look and discovered that a plugin already exists. Maybe that's sufficient and we don't need to do anything further here? Or maybe implementing this in the main 11ty codebase/repo would be better if we think this would have high value for 11ty users?

Additional context

As a similar use case, we created a WordPress plugin for that platform and it has been received very positively. We're also considering proposing adding this to WordPress core if the plugin proves successful. We're willing (and in fact keen!) to work with other platforms where this API would potentially add a lot of value.

@zachleat
Copy link
Member

I think this is great!

Sounds like another good addition to this docs page too: https://www.11ty.dev/docs/single-page-applications/

I don’t think we would ever add something like this as opt-out to core, fwiw (given https://www.youtube.com/watch?v=b4frtsT4Cgo) but maybe an opt-in feature eventually!

The existing plugin looks good too. Looks like it’s a global configuration that generates a <script> and injects into .html files (via Transform) by replacing </body>. This likely works fine but we might be able to improve on it a bit.

  • Perhaps a shortcode or component to position the snippet where you want it to be in markup.
  • Per template configuration option in data via the data cascade. Spitball example: aggregating from speculationRules in a template or directory data file.
  • Something with https://github.com/11ty/eleventy-plugin-bundle (which is now available in 3.0)

@tunetheweb
Copy link
Author

Adding @reatlat to the thread who created the plugin to see if they have any opinions or have had any thoughts, or had any learnings from implementing that plugin, on had any feedback on their plugin so far.

@reatlat
Copy link

reatlat commented May 24, 2024

@tunetheweb Thank you for adding me!
I created a plugin to fix some speed issues in projects I am working on, and I want to share it with the community.
After researching on MDN Web Docs, I discovered the best approach is to place the code at the bottom of the page.
I aimed to make the plugin user-friendly, providing a simple way to get started, with options for advanced users to customize as needed.
I agree with you that integrating Speculation Rules into 11ty is a great idea, as this technology is important.

If @zachleat agrees, it could be included in 11ty-v3.0. Alternatively, we could keep things simple and include it using a plugin bundle.
In the meantime, the current plugin can be used on all versions of 11ty (I have not tested it on v3.0 yet).

When it comes to shortcodes, I believe it's a good idea. However, there could be issues if someone uses the shortcode twice – once in the template and again in the final document. I'm not sure if this would violate Chrome browser rules, but it could lead to confusion and mixed rules.

@zachleat, I haven't had the chance to explore 11ty 3.0 and plugin bundles yet, but I'm eager to do so, and I might have time to check them out this weekend!

@jeremyroman
Copy link

It would be great even to make it simple and obvious to opt in. One thought from having written a plugin aimed at this (https://github.com/jeremyroman/eleventy-plugin-speculationrules), which might be non-obvious:

Path prefixing. If Eleventy is deployed to a prefixed path (common, e.g., on GitHub Pages deployments), it's necessary to appropriately prefix the URL patterns. If the logic might be used on path prefixes containing a handful of characters, escaping might be necessary (see, e.g., these tests). This is something we ran into with WordPress.

There's definitely room to explore what sorts of options are most useful for Eleventy users in practice, to balance keeping it simple against exposing the full expressiveness of speculation rules. It seems both @reatlat and I independently thought that leaning toward the "simple" end was likely the way to go, at least to start.

Duplicate rules aren't desirable, in the same way duplicate stylesheets or scripts aren't, but I would assume that you can rely on authors to deal with that. Of course, this is ultimately a question of what Eleventy users expect!

The transform approach certainly avoids a step for enabling the plugin, which is great, but is potentially brittle in edge cases (e.g., if the author writes <xmp></body></xmp> or <script>let a = '</body>';</script>) without actually parsing the HTML fully (which there are Eleventy plugins to do, but which seemed somewhat overpowered for this to me).

@reatlat
Copy link

reatlat commented May 28, 2024

@jeremyroman I was looking for specualtion plugin about 3 months ago, and after I didnt find it, I wrote my one 😀
Meantime, It looks like <xmp> are deprecated...
Any examples of <script>let a = '</body>';</script> usage? it's first time I have seen that kind of staff 😀

@jeremyroman
Copy link

<xmp> is deprecated, but still supported in major browsers (and probably will be for the foreseeable future).

The script example I gave is quite contrived, of course, but the general point is that it's possible that inline script might contain the string </body> within it (e.g., because you have a script that itself generates or processes HTML documents).

Another example might be that you might be writing a blog about authoring HTML documents, so you have an attribute that contains it <img src="closingtags.png" alt="Elements are closed with closing tags, like </body>"> (you could escape this of course, but it's well-defined not to in an attribute context).

These are edge cases that most users won't run into, but it'll be surprising if they do, and the more users you have, the more likely one of them will. It's just a hazard of trying to parse HTML with a regular expression rather than an HTML parser. Parsing with an HTML parser is better, of course, but also means that you have to bring an HTML parser into the picture. At the time I explored this originally, a few Eleventy plugins did so via posthtml but core stuff relied on the author to use shortcodes (which is of course very efficient and gives authors direct control, at the cost of an extra step). Now that HtmlTransformer seems to exist in Eleventy core, that might be a more robust way to do the insertion without author intervention. I don't know what's preferred upstream.

@reatlat
Copy link

reatlat commented May 29, 2024

@jeremyroman well this make sense, and I see how I can improve my solution to avoid this kinda cases, meantime code like <img src="closingtags.png" alt="Elements are closed with closing tags, like </body>"> kinda madeup situation, I don't believe that coders who use 11ty will cose this way 🤪 body tag must be escaped in that example

@jeremyroman
Copy link

jeremyroman commented May 29, 2024

The body tag doesn't have to be escaped in that example (though it's not a bad idea to do so), because the HTML parser is in an attribute value state and can resolve it correctly.

Yes, I'd expect it to be rare in practice (I come from the web browser implementation side of things, where everything that can happen will happen somewhere, especially if it happening leads to a security vulnerability). The flipside, the </body> never appearing, is also possible in theory (because HTML doesn't require it), unless something in Eleventy guarantees it's emitted, and perhaps more likely?

This is a bit of a tangent from the main issue here, though.

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

No branches or pull requests

4 participants