-
Notifications
You must be signed in to change notification settings - Fork 440
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow Rails to provide timing data in browser dev-tools via Server-Timing header #1771
Allow Rails to provide timing data in browser dev-tools via Server-Timing header #1771
Conversation
Let's do that! Let's default the config to false. |
…ils Server-Timings headers
dc423a8
to
875f6bd
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👏🏻
docs/guide/instrumentation.md
Outdated
event.payload # => { name: "MyComponent", identifier: "/Users/mona/project/app/components/my_component.rb" } | ||
end | ||
``` | ||
|
||
When using `render.view_component` with `config.server_timing = true` (default in development) in Rails 7, the Chrome developer tools display the sum total timing information in Network > Timing under the key `render.view_component`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not important but: specifying Chrome here is perhaps a little "chrome-centric". The feature works nearly the same in FF, Safari, Edge and Opera. The screenshot in the PR is from FF 113 IIRC.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there anyway you can add Firefox and safari instructions
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They are nearly identical aside from coloration, so I don't think it's necessary.
- Network tab (refresh if its empty)
- Click the request you're interested in.
- on the right-side OR the bottom-side (depends on size of the dev-tools area) you'll see several tabs for that request; choose "Timing" or "Timings" (in FF)
- Look for server timings at the bottom beneath the client-side data.
Biggest caveats with Server-Timings in general:
- It's not provided for every request. Normal MVC rails controllers in development mode will provide it (it's a middleware) - but assets won't. In production you won't see it without enabling it in production.rb.
- It does not give you the level of detail (or cross-request metrics) you can get from a product like Skylight or New Relic. I'd suggest using it for quick-checks mainly, e.g.: "huh active record is crazy on this one, maybe I should take a look at my queries."
- Does not exist prior to Rails 7.
From top-left going clockwise: Chrome, Firefox, Safari. You can see its pretty much the same.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about we just say "browser" here? Perhaps we should add this screenshot to the docs?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just added a smaller variant of the screenshot. When running the docs locally that path seems to work and display properly, but there may be some risk of a dead img src when deployed.
@tgaff it looks like we might have some missing test coverage here. Care to investigate? |
I've been trying to get coverage on that deprecation warning and have run into a bit of a wall. Maybe someone has advice. In def test_deprecation_notice_when_use_deprecated_instrumentation_name
with_config_option(:instrumentation_enabled, true) do
with_config_option(:use_deprecated_instrumentation_name, true) do
assert_deprecated(/!render\.view_component/, ViewComponent::Deprecation) do
ActiveSupport.run_load_hooks(:view_component, self)
end
end
end
end
def test_no_deprecation_notice_when_not_using_deprecated_name
with_config_option(:instrumentation_enabled, true) do
with_config_option(:use_deprecated_instrumentation_name, false) do
assert_not_deprecated(ViewComponent::Deprecation) do
ActiveSupport.run_load_hooks(:view_component, self)
end
end
end
end However it's got a pretty big down-side of causing the other instrumentation tests to fail in an order-dependent way and I suspect having all the initializer hooks (in engine.rb) run twice could also cause unexpected issues elsewhere in the test suite too (someday). More specifically: in the other instrumentation tests it finds more than one event - because with the initializer loaded twice it sends multiple events. I've been trying to find a way to bind those initializers to another context to test but I haven't been able to come up with anything that actually works. I've even tried running just the two config and instrumentation hooks, bound to a fresh Rails app but it still poisons the suite. Any ideas? |
* this has no test coverage :-(
😅 sounds like we should |
…nt failures Example: instrumentation notices are doubled
I couldn't find a better alternative. 🙁 |
To use a specific host, pass the host param: | ||
|
||
```ruby | ||
with_request_url("/users/42", host: "app.example.com") do | ||
render_inline(MyComponent.new) | ||
end | ||
``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like this may have been inadvertently deleted by regenerating the API docs, which happened because it seems this part was manually added directly in api.md
in #1773, rather than in the corresponding YARD comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've opened a PR here to restore this example here: #1794
I can confirm that this happens. The logged render statements for an exemplary stacked ViewComponent (lots of nested component calls) is
The total browser reported time is somehwere in ~400ms. The reported timing is ~6s, which is the sum of all component instrumentation calls combined. But as they are nested, inner calls should be excluded. |
…ming header (ViewComponent#1771) * change ActiveSupport::Notification event name so it is included in Rails Server-Timings headers * Changelog update for instrumentation * update docs for instrumentation change * add trailing whitespace per PR linter * Instrumentation key with '!' deprecated and usage can be configured * update CHANGELOG to mention new config for instrumentation and deprecation * update documentation for instrumentation * send deprecation notice once, rather than on each render * remove double-spaces * Apply suggestions from code review * Update docs/guide/instrumentation.md * rename instrumentation config key to match other renames * this has no test coverage :-( * nocov initializer code: re-executing it in tests causes order-dependent failures Example: instrumentation notices are doubled * lint * docs: Add browser dev tools image to aid explanation * docs: code back-ticks to make Vale happier * md linting --------- Co-authored-by: Joel Hawksley <joel@hawksley.org> Co-authored-by: Joel Hawksley <joelhawksley@github.com>
…ming header (ViewComponent#1771) * change ActiveSupport::Notification event name so it is included in Rails Server-Timings headers * Changelog update for instrumentation * update docs for instrumentation change * add trailing whitespace per PR linter * Instrumentation key with '!' deprecated and usage can be configured * update CHANGELOG to mention new config for instrumentation and deprecation * update documentation for instrumentation * send deprecation notice once, rather than on each render * remove double-spaces * Apply suggestions from code review * Update docs/guide/instrumentation.md * rename instrumentation config key to match other renames * this has no test coverage :-( * nocov initializer code: re-executing it in tests causes order-dependent failures Example: instrumentation notices are doubled * lint * docs: Add browser dev tools image to aid explanation * docs: code back-ticks to make Vale happier * md linting --------- Co-authored-by: Joel Hawksley <joel@hawksley.org> Co-authored-by: Joel Hawksley <joelhawksley@github.com>
What are you trying to accomplish?
Per this discussion:
#1490 (comment)
This may resolve in part #1490
This alters the key used for ActiveSupport Instrumentation so that Rails automatically picks it up and includes a sum total in the browser headers sent to the client (feature added to Rails here). By default the
Server-Timing
header is only enabled in development but can be turned on viaconfig.server_timing = true
. Rails excludes any notification key that starts with!
when setting the Server-Timing header.All desktop browsers I've checked (FF, Chrome, Safari, Edge, Opera) will automatically add this data to the client-side timing data on the dev-tools Network tab. This makes for a quick "low-detail" look at what happened in a particular request.
Above is what you see in Firefox.
What approach did you choose and why?
I've gone with the simplest approach of just renaming the key for now as that's what was initially discussed in the issue. Please see discussion below.Based on feedback, this now introduces a new config to avoid the breaking change.
Anything you want to highlight for special attention from reviewers?
the below "breaking change" issue has been resolved with an additional config option per @joelhawksley instruction
As I mentioned on the issue, this could be considered a breaking change for anyone currently subscribed to the current notification name. I proposed 3 ways of handling that, but could use guidance on what maintainers think is best.
!render.view_component
andrender.view_component
. The overhead is low assuming no one subscribes to both events (in which case its double the current).!
name.I have a slight preference towards 2 since it gets this in quickly, but not opposed to any of these.
Also I haven't proven it out yet, but I think there's a chance that nested components could also suffer from this bug that I reported over on the Rails repo: rails/rails#48375