|
| 1 | +# Fragment include |
| 2 | + |
| 3 | +## Overview |
| 4 | +The introduction of [patching](https://github.com/WICG/declarative-partial-updates/blob/main/patching-explainer.md) allows HTML to stream out of order declaratively. |
| 5 | +While this opens up a lot of new options, this has a few limitations that were said to be addressed as future enhancements: |
| 6 | + |
| 7 | +1. A patch *always* streams, and there is no declarative way to make it apply in one batch when desired. |
| 8 | +2. A patch is interleaved within the original response, requiring the server to multiplex content from different sources. |
| 9 | +3. A patch cannot be independently sanitized. It inherits the safety features of its embedder. |
| 10 | + |
| 11 | +## Proposed solution |
| 12 | + |
| 13 | +See also https://github.com/WICG/webcomponents/issues/645 and https://github.com/whatwg/html/issues/2791 |
| 14 | + |
| 15 | +Proposing that `<template for>` solves the problem of *where to put the markup*, and that the problem of *where does the markup come from* is somewhat separate. |
| 16 | +Taking from the [HTML modules](https://github.com/WICG/webcomponents/issues/645) and [client side includes](https://github.com/whatwg/html/issues/2791) proposal, suggesting to do something like this: |
| 17 | + |
| 18 | +- `<script type=fragment src="fragment.html">` includes a fragment of HTML in place, without streaming it. |
| 19 | +- `<script type=fragment>escaped-html</script>` can work with inline HTML as well, but it has to be escaped. |
| 20 | +- A fragment script is sanitized (safe mode) by default. |
| 21 | +- A fragment script can have an `unsafe` attribute. The `unsafe` attribute can be empty or have a `run-script` value that would make the patch run scripts. |
| 22 | +- A fragment script has module semantics, in terms of idempotency. The fragment is a `DocumentFragment` in the module tree, and can be mutated, but is cloned and appended when imported so mutations don't affect past imports. |
| 23 | +- The `async` and `defer` attributes work the same way as for JS scripts. |
| 24 | + |
| 25 | +## Performance |
| 26 | + |
| 27 | +The main issue with this approach is that overuse of client-side includes can be a performance anti-pattern vs. multiplexing in the server. |
| 28 | +However, this performance drawback is very context dependent. |
| 29 | +In some cases, adding markup asynchronously rather than having to multiplex it in the server or passing it through JS setters can be a performance win. |
| 30 | +Like with JS modules, bundlers are very mature and authors can make the decision of whether to bundle the markup or fetch it client-side based on their specific context, and we should look at adding this to the toolbox as an expansion of the options rather than as a footgun. |
0 commit comments