Add uncapped preload headers for style, script assets#11504
Conversation
app/helpers/script_helper.rb
Outdated
There was a problem hiding this comment.
we should be able to directly assign this right? I'd go a step further an inline the entire thing, but that would make us have to wrap line 23 below
| crossorigin = true if local_crossorigin_sources? | |
| crossorigin = local_crossorigin_sources? |
There was a problem hiding this comment.
This branch was actually a few months old, and that change was one of the first things I tried editing when I resurrected it. But there's a significant difference between nil and false in how it's used with javascript_include_tag, which is the reason for the true if. I can't recall off the top of my head, but I'll make sure to add some test coverage for it when I write those.
There was a problem hiding this comment.
ah looks like the source code checks for "not nil" and "true"
maybe it would be easier if we updated local_crossorigin_sources? to match that expected format?
# Fake boolean to match expected values for `:crossorigin` option in `javascript_include_tag`
# @see ActionView::Helpers::AssetTagHelper#javascript_include_tag
# @return [true, nil]
def crossorigin
true if Rails.env.development? && ENV['WEBPACK_PORT'].present?
endThere was a problem hiding this comment.
I tinkered with this a bit, and landed toward a small revision to use presence in 4e23c1e.
Partly for micro-optimization, since the value is referenced twice and would prefer to avoid evaluating that logic twice. But moreso because the true / nil vs. true / false is less to do with some internal logic specific to javascript_include_tag, and moreso about the crossorigin attribute itself, where false would apply an empty string attribute value, which is significant since it's an HTML boolean attribute.
app/helpers/script_helper.rb
Outdated
There was a problem hiding this comment.
this means that preload_links_header: nil will add the preload header, that seems counterintuitive to me?
There was a problem hiding this comment.
There was a problem hiding this comment.
shoudl we use the same presence trick?
| if attributes[:preload_links_header] != false | |
| if attributes[:preload_links_header].present? |
There was a problem hiding this comment.
I think that'd be the opposite behavior from what we expect, since we want :preload_links_header to be opt-out, not opt-in.
changelog: Internal, Performance, Add preload headers for all style, script assets
ea5090e to
8183cb1
Compare
| '</application.js>; rel=preload; as=script,' \ | ||
| '</document-capture.js>; rel=preload; as=script', | ||
| '</application.js>;rel=preload;as=script,' \ | ||
| '</document-capture.js>;rel=preload;as=script', |
There was a problem hiding this comment.
Whitespace is optional per the spec, which allows us to salvage back some of the bytesize increase these changes could incur.
link-value = "<" URI-Reference ">" *( OWS ";" OWS link-param )
See: https://github.com/18F/identity-idp/pull/11504/files#r1841273216 Co-authored-by: Zach Margolis <zachmargolis@users.noreply.github.com>
We don't need any of this anymore: - Asset pipeline lookup - Preload headers handling - Server push - Multiple source concatenation - Nonce handling crossorigin as a boolean attribute is same as crossorigin=anonymous
Previously evaluated per script, even though the result would always be the same
|
I did some local benchmarking and pushed a few more iterations for some small optimizations. The end result is pretty nice, about 75% improvement. (Benchmark script as HTML comment of this message) |
app/helpers/script_helper.rb
Outdated
There was a problem hiding this comment.
shoudl we use the same presence trick?
| if attributes[:preload_links_header] != false | |
| if attributes[:preload_links_header].present? |
🛠 Summary of changes
Updates asset helpers to bypass internal
stylesheet_link_tagandjavascript_include_taglogic for handling preload response headers, appending preload headers without caps. As of rails/rails#48405 (Rails 7.1), preload headers added by tag helpers are capped at 1kb, which is very limiting, especially given our approach of loading many, smaller assets targeted as sidecar assets for UI components.While the caps have created some incentives to be more intentional with preloading (e.g. #10612), we've already addressed the lowest hanging fruit, and a number of critical scripts are currently not being preloaded (e.g. reCAPTCHA behaviors on the sign-in screen).
References:
📜 Testing Plan
Verify that preload headers are included for all scripts and assets, including
integrityorcrossorigindirectives as appropriate. Compare against https://secure.login.govVerify that there are no style or script regressions in browsing the application, either in local development or in a review application.