5,399 karma · joined April 2, 2007
[ my public key: https://keybase.io/igrigorik; my proof: https://keybase.io/igrigorik/sigs/eMcFb-lAFqkBGZKfdzJcQrC5a2dTBj_8cTAQqsXUhaE ]
The key to unlocking fast first-render is combination of streaming SSR (i.e. streaming HTML instead of just JS blobs), which is enabled by adopting Suspense (i.e. async the data fetch and stream data when available in HTML response, which then hydrates relevant component). RSC layers on top: it establishes a clear boundary between client and server logic, which enables better bundling strategies (as you highlighted), but also per-component and efficient subtree updates for subsequent interactions.
RSC is early but we've been working with the React core team on our use case and, based on the past few months of work and progress, we feel pretty confident about the direction. In particular, shifting legacy React apps towards Suspense+RSC will be a big shift for many, but we don't have that constraint.. We have the "luxury" of starting anew and we're leaning into the bleeding edge because it enables all the right primitives for commerce: fast first render, efficient updates, open space for optimizing bundles and RSC transport protocol, etc.
It's not a matter of first vs rest but observation that input while the page is loading is, often, where most of the egregious delays happen: the browser is busy parsing+executing oodles of script, sites don't chunk script execution and yield to the browser to process input, etc. As a result, we have FID, which is a diagnostic metric for this particular (painful) user experience problem on the web today.
Note that Event Timing API captures all input: https://github.com/WICG/event-timing. First input is just a special case we want to draw attention to due to the reasons I outlined above. That said, we encourage everyone to track all input delays on their site, and it's definitely a focus area for future versions of Core Web Vitals -- we want to make sure users have predictable, fast, response latency on the web.
The 2.7MB is a reference to the median.
E.g, to identify sites with CSP: https://discuss.httparchive.org/t/which-sites-have-content-s....
You can access raw HAR captures, as well as pre-aggregated stats via BigQuery.
If you have any feedback, questions, or suggestions on the contents of the book, please file an issue on GitHub: https://github.com/igrigorik/hpbn.co/issues
We should be thinking about how to deliver the best of both worlds: a great experience for older (non-SW) browsers, and an even better experience for those that do. The underlying patterns are effectively the same, SW just makes many things much simpler, and there is no reason to block on SW to start on this path.
I'm simply pointing out that you can get most (if not all) of the claimed perf benefits using existing API's. Yes, it won't look as pretty, but if you want to deliver a better experience to existing + older browsers.. this is something to consider.
The benefit of above technique is that it's deployable today, doesn't require the destination server to be upgraded, and works for cross-origin resources.
The early feedback from FF, IE, (and to some extent, Webkit), folks have been positive, and I'm hoping this can be a cross-browser feature in 2015 (yes, I'm an optimist).
Let's hope that twelve months from now, we're looking at a very different landscape. Kudos to NYTimes for issuing the challenge. At the very least, this is an important conversation starter.
Also, if you need to wait for DOM/CSSOM, then you can still use an async script and just install an event listener for DomContentLoaded / DomInteractive / etc., when it loads.
As for why the browser doesn't download the script-injected scripts: they're hidden inside of the inline script blocks. In order to figure out what you intend to do inside of that block, the browser would have to execute the JavaScript. The behavior that you want (download wait for CSSOM) is exactly what you get when you use regular blocking tags - those are discovered by the preloader and requests are dispatched. That's what the first and second diagram in the blog post illustrate.