Open tigt opened 3 years ago
<script defer>
instead of<script async>
on pages that don’t stream HTML
I second this in making this configurable, there should be an option for neither defer or async, where it fetches and executes immediately before the HTML begins the parse.
update: correction to my statement, I actually want neither defer or async, but would like this to be configurable.
@knyto2 i'm curious what the benefit you see to using defer
(even in the non streaming case) over async
?
@DylanPiercey Sorry, I meant that there should be an option to not have either async or defer, where the the javascript will be fetched and executed immediately (which I'm assuming marko is beginning to stream in this case). As a result, the script elements are outside of html. As a workaround, I've added
Also, shouldn't the CSS come before the JS assets? I am seeing a first paint issue where my components are being rendered, but looks the CSS is still coming over the wire, so it looks like html without the css.
Using async
actually allows the Marko runtime to load immediately, and components initialize as they are streamed out. Script async
does not effect blocking style sheets though, so what you are seeing must be from something else.
If we didn’t use async
that’d mean flushing scripts at the end of the body which would mean they couldn’t be downloaded or evaluated until the entire document is ready. Using defer
has the same issue, but the scripts don’t have to go at the end of the body. Using async
tells the browser to download and execute right away without blocking the pages rendering, which is what the Marko runtime is designed to do.
I'm thinking that the Marko webpack plugin should expose hooks similar to HTMLWebpackPlugin that allow for changing the asset writing code.
Didn’t @mlrawlings have a branch doing pretty much exactly that, or am I misremembering?
I think you are misremembering. We have talked about doing that before though for other reasons.
Description
(Old, original issue for historical purposes: #11)
Right now,
@marko/webpack
writesmarkoc
’s produced component assets to the HTML like so in/src/loader/get-asset-code.ts
:There’s nothing wrong with this, but its one-size-fits-all approach may be unsuitable for a number of reasons…
Why
<init-components/>
and<await-reorderer/>
— I personally want toperformance.mark()
around them.<script type=module>
and<script nomodule>
nonce
s aren’t always applicable — ifscript-src 'self' 'nonce-…'
, then non-inline scripts don’t need one. (That’s our CSP configuration.)integrity
attribute, for future-proofing/fallbacksprefetch
,preload
, andmodulepreload
<link>
s<link rel=stylesheet>
) midway through the<body>
<link rel=stylesheet>
right before each component for truly progressive rendering<script defer>
instead of<script async>
on pages that don’t stream HTML<script>…</script>
and<style>…</style>
<script defer src="data:application/javascript,…">
@marko/webpack
’s asset output, but before</head>
crossorigin
attribute for preventing double-downloads, fine-tuning HTTP/2 coalescing with different originsmedia
attribute on<link>
Possible Implementation & Open Questions
In the Webpack plugin configuration, an author could pass their own function. Their passed function could be
.toString()
’d to comply with the reasonsget-asset-code.ts
mostly just exports a big function that templates JavaScript source code.Maybe with a signature like this:
Is this something you're interested in working on?
Yes