The callback graph is an indispensable tool for troubleshooting, but the bigger the graphs get, the harder it becomes to get around and to use it effectively.
I wanted to share some of the improvements I am currently working on regarding the callback graph .
My main idea for this post is to:
discuss how people currently use it and which parts/improvements they would like to see
get feedback on the improvements made / proposed improvements (see further)
Currently basic search functionality and filtering of non-zero callback counts with dynamic updates are mostly working
Additional ideas for implementation/improvement:
toggle for threshold marking with a configurable thresholds (e.g. highlight > 300ms)
introduce absolute min / max values for call-backs stats, besides the currently average-only numbers
research if there is a way to implement/define a “friendly name” for pattern matching callbacks
(currently there is only an auto-generated UUID, which doesn’t tell us much)
research if there is a way to have a marking/naming of callback as per the page of a multi-page app they are in/running
(less important and not even sure if its possible at all)
Export to PNG / JPG (not very important, since a screen grab tool can be used to achieve the same)
Discarded / postponed ideas:
filter for client vs server side callbacks (some subtrees have mixed client/server callbacks which would complicate things)
Known issues and limitations:
- there is currently no sync between what is on-screen / what is searchable / layout options → planned to be fixed
- sometimes minor layout artifacts pattern matching callbacks) happen during dynamic updates
not too bad since they are resolved the next update.
- there is a 1s + processing min update delay between activity and actual updates.
multiple layout updates are optimized, but adds more time to the actual update
Many of your points aim towards a “redux-like” audit-trail type of functionality for the callbacks. who / what / when / how much … for a longer period in time (question: as of opening the callback graph, or since the app started)?
How far in detail do you want to go? do we need / can we track the actual request data/replies?
I think it would be good to brainstorm where we can get all this information and if if isn’t currently available, how we would go about it (in a way that it would be flexible for the future).
No, Why? it’s just ideas for improving the debug (Debug=True) mode when you develop the app. There is a button with callback which pops up a graph representation of the callback tree. The aim is the improve it since its bare minimums now (although not badly done:)
A couple ideas I’d love to see (thrilled you have a search feature already going!)
Function names are attached to green nodes. I should be able to see which functions are attached to which callback, as it’s likely easier to identify a callback by its function name than by its inputs/outputs (since outputs cannot be shared, of course I can dig and get back to the unique root, but… this is hard)
Better performance analytics. You can currently see how long the most recent run of a callback took as part of the green node. This is incredibly useful. Why not take this further… On clicking a node, I can see a full profile of the last run of that callback, specifically which lines inside the callback took the longest. There are ways to do this manually but it’d be great as native functionality
Ability to split it into a different tab. Maybe out of scope here, but you can’t look at the callback graph and your app at the same time. Allow the callback graph to be viewed in a second window (or maybe even all the debug tools) so it’s easier to compare the graph to your user interactions without constantly flipping it on and off.
Amazing stuff and glad you’re taking initiative here! Looking forward to seeing what you come up with.
These improvements sound great! What I’d like to see is the ability to do logging in Python with e.g. app.log("hi there") or somesuch, and have those (in debug mode only!) set over to the client so I can see per-callback logging in dev tools, rather than in the console where they’re all intermingled
Looks SO good @jcuypers ! Really excited that you are digging in here.
Some things on my wishlist
Only display visible callbacks - By default, only show the callbacks that correspond to elements that are currently rendered. So in a multi-page app, don’t show the callbacks from the other pages. Have a radio items toggle between “Show All Callbacks” vs “Show Visible Callbacks”
Table view - Display the callback history in a table that’s ordered by runtime. I still find that I’ll use the browser’s network requests for advanced debugging but that’s a pain and undiscoverable for most users. Imagine if there was a table (with sortable headers!) with: columns like:
I honestly might not even use the network graph if I had a clean table view!
Replay - Ability to replay a request with the same payload. So that you could make a change in your code (fix a bug, add a print statement, etc) and then retry the same request without needing to re-enter the UI parameters.
Hi, yes I thought about the same but to be able to replay after a code change is something entirely different.
I have still limited understanding of where everything is, but I see the following issues:
The callback graph is built dynamically from data pulled from the redux store. Which in it’s nature offers some form of history and playback. This information is temporary to the lifetime of the app.
There is no way to get to this information outside of that or after restarting the app.
Trying to overcome those limitations poses other problems:
many applications have big data requirements
It would be impossible to store 100,of MBs or some GBs for whenever they would like to replay
some apps have specific data needs
We are not going to have a backlog of data for uploaded pictures or documents . Would not be safe anyways…
Where to store this data offline, if redux dissappears.
structure of the app most of the time changes
Diminishing the overal effectiveness of this feature, since the is no match to what’s active. Building on this, the replay would mean it would need to re-appear in the actual callback graph history and would need to match something.
a callback event is mostly not a standalone event:
This means that when you tweak your app and want to run some callback / past event … Even if you even have it… You need to respect the initialization state of the modified app, since you don’t know what changed,. Then if you want to run callback 100, there might be a problem since the chain might have been started at callback 99 ,(like set output/data,) for callback 100. Even further, 100 might need to whole chain up to 1 to do anything useful including props changes.
Maybe something to try in a basic form in the future, but I think it would be hard.