-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
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
High level profiling / tracing #8588
Comments
This all makes sense to me, and it sounds useful!
You could do this using the
We could add a new CLI option like we have for
We could make
Sounds like it would work. |
Thanks for the feedback Devon, I've removed the questions from the original post and added some proposed implementation details based on the answers and some more thinking. |
Implemented in #8695 |
💬 RFC
🔦 Context
Parcel currently provides a way to generate sampling CPU profiles using
--profile
, or using Ctrl-E during the build. These CPU sample based profiles can be used to identify bottlenecks and understand where Parcel is spending it's time at the code level, and are useful for these low-level purposes.This proposal is to introduce the concept of a high-level trace, where Parcel can report on time spent at a higher level - for example, to be able to identify which transform is the most expensive in your build, or identify if there is a particular source file that causes additional overhead.
This is particularly useful for us internally when determining where to focus our efforts on build time improvements, in order to identify where time is being spent and where we should focus our optimisation efforts.
Prior art
When I initially spiked this, @mischnic mentioned this had been previously raised by him in the Parcel project management tool (issue T-1131).
This RFC builds upon work originally created by @thebriando in our internal Parcel fork - Brian's implementation only ran on the main thread, and measured time spent in transform/bundling/packaging at a high level, however when I tried to adapt this approach to a more broad high level tracing (e.g. per transform) I ran into the following issues: a) passing a
Tracer
around through the various layers would involve a lot of changes in a lot of places, b) it would not be able to cross thread/serialisation boundaries.Spike approach
There is a very rough spike branch here: https://github.com/marcins/parcel/tree/mszczepanski/spike-system-tracing which at this stage is not comprehensive, nor particularly clean, but was created in order to help socialise the potential approach.
In this branch I have added additional "trace" functionality to the logger, mostly because I wanted to follow a similar approach - have a singleton
SystemTracer
that could be used to access the measurement functionality from anywhere. ThisSystemTracer
lets you measure any code within Parcel with a pattern like:These trace events are caught by a TraceReporter which uses
chrome-trace-event
to produce an appropriate output.This will produce a Chrome Trace event similar to:
A trivial but complete trace is available here: https://gist.github.com/marcins/a1a0ceaf3f3fd0d4771e0e611ebc360f
Analysing results
While these traces can be loaded into Chrome DevTools Performance tab, like Parcel's other profiles, they are of limited value here due to the lack of analysis tools. However, where this data can really be useful is by loading it into https://ui.perfetto.dev/. Example screenshot from the trace above:
The visual timeline itself isn't necessarily useful except at a very high level, however the SQL queries built into Perfetto let us easily ask questions like "What is the most expensive transform?"
Using Perfetto's SQL you can come up with all sorts of other queries, whether it's by source file, category, etc.
Proposed implementation details
@parcel/tracing
to encapsulate tracing/profiling. The existingTrace
andProfiler
frompackages/core/workers/src/Profiler.js
could be moved here as well as they share a dependency onchrome-trace-event
/ deal with tracing.Tracer
/tracer
should be analogous toLogger
/logger
(i.e. the class implementing the thing, a singleton instance of the thing exported for use in other code)Tracer.onTrace
events and re-emit them usingbus.emit('traceEvent')
, which get re-fired on the main thread by a listener.TraceReporter
to handle creating the trace, but we should probably just handle this in core similar to how / where existing profiling traces are created?--profile=application
vs--profile=sampling
(wheresampling
is the default current behaviour?).enable()
/.disable()
toTracer
that can be called when config/CLI options are processed?)wrapPluginVisitorMethod
that will measure time spent in individual Babel plugins (marcins@51695a0#diff-8555dae9dfcfcf7ddcaab1c7cb7ebde8b3bcdecef9b54dc032c654bb0e2c5c21R69-R86)Status / Questions / etc
Pending implementation.
The text was updated successfully, but these errors were encountered: