marko-js / webpack

A loader for marko files and a plugin for universal bundling
MIT License
13 stars 4 forks source link

Asset loading strategy problems #11

Closed tigt closed 4 years ago

tigt commented 5 years ago
  1. Injecting assets before the <!doctype> puts the page in Quirks Mode; that’s clearly bad and the team has acknowledged that, so I won’t waste more words on it. Some other possible problems depending on injection point:

    • Should be after <meta charset>
    • Should be after <base>
    • Should be after <meta name="referrer-policy">
    • Should be after any <meta http-equiv="Content-Security-Policy>
    • …probably other stuff, including things to come in the future. Maybe a heuristic of “before the first <link>/<script> element we see”, or an explicit marker string in the <head> to .replace()?
  2. Resource loading order is nondeterministic: <link rel=preload> is higher-priority than <link rel=stylesheet>, but since <link rel=preload> is injected via script, there are race conditions involving:

    • If the <script> executes before the lookahead preparser finds the <link>s
    • Across different browser (& version) JS schedulers, network heuristics, and HTTP/2 prioritization
    • How much of the HTML is received across IP/TCP/etc. network byte boundaries
  3. The resource-loading strategy has a lot of thought put into it, but it may not fit all. Some things I wanted to try:

tigt commented 5 years ago

Other than the granular as-it-streams loading, this might be solvable with a @marko/webpack taglib:

<marko-webpack-scripts />
<marko-webpack-styles />

(Names welcome for bikeshedding)

By placing them in the root templates, the developer can control where the injection points are, without overly complicating the inject-into-stream logic. Everything under point №1 is no longer a problem.

Additionally, the injected elements can be configured with attributes:

<marko-webpack-scripts 
  type="module"
  preload=(url => !url.includes('lazy'))
/>

This doesn’t solve everything in points №2 and 3, but it would solve many of them.

What do you think?

tigt commented 4 years ago

Problems 1 and 2 have been fixed. 3 adds enough scope it should probably be its own issue.