Ask HN: Why doesn't a time travel debugger exist yet for JavaScript?
I know Microsoft had a project going for this that is almost certainly scrapped now because Chakra went the way of the dodo but between Facebook, Google, Microsoft, and Mozilla there is some pretty good backing behind JavaScript projects. I've never used TTD before personally but it seems like a game changer. Is this just a really hard feature to make or is it incredibly resource intensive? Is it actually not that helpful for developers? Am I missing something or is this just something that'll happen when it happens? It seems like you could make a pretty good integration with a browser that would make this valuable.
36 comments
[ 6.9 ms ] story [ 83.9 ms ] threadhttps://developer.mozilla.org/en-US/docs/Mozilla/Projects/We...
This video highlights some of the existing functionality:
https://www.youtube.com/watch?v=yS5ai04TP5Y&t=4s
1. a realtime recording button 2. a timeline view of events on the top 3. the ability to scan back to a console message 4. the ability to rewind to a breakpoint 5. the ability to add a logPoint in the debugger and see the messages in the console quickly
I'll second other comments on the complexity side. Our architecture works on the Operating System level, which makes it fast and non-invasive, but the difficulty level in terms of pulling something like this off is very high as you have to understand the browser architecture from the system calls it makes, to way processes behave, to graphics, the JS engine, and DevTools architecture.
I think we're in a good place in terms of getting feedback and iterating on the product. There's lot's to do and it is very exciting!
Ditto for Chrome DevTools. If I recall correctly, it’s feasible but would be a huge undertaking. Demand for the feature would have to be very large to justify the work involved.
We have a WIP patch. At the moment, we're prioritizing MVP functionality, performance, and stability.
Would it reduce the graphics, OS, etc complexity to just have the basic single function IO recording?
1. JS is dynamic and a single function can do a lot, even if you try to stub out the world.
2. from a product perspective it would be hard to communicate what is going on.
3. Perhaps console logs could cover a lot of these cases.
Does that make sense? What are you thinking of?
---
We definitely want to make it easy to visualize function calls (inputs/outputs). For instance,
- see outlier function arguments (the time the first param was null) or the function returned early...
- see outlier call sites (the time when the function was called from a different call site)
- see outlier timings (the time when the function called when some other state was null or a promise was pending) i.e. race detection
On the other side, we would love to help users see the impact of a function call. For instance,
- program slicing: the other code that was run because this function was invoked
- data tainting: the data that was either read or written to because this function was invoked
The elm-dev channel contains most of the info coming from Evan :). I had the same feeling as you until I discover this.
Meanwhile, there is a forked version of the compiler with a hotfix for the debugger that works for most applications, even medium and large ones: https://github.com/elm/compiler/pull/1850
There is a PR for that already, but it has not yet been merged: https://github.com/elm/compiler/pull/1850
At CurrySoftware we run a fork of the Elm compiler which merges this PR and has a feature to use ports and the debugger with `elm reactor`: https://github.com/CurrySoftware/compiler
And an example how to use it here: https://github.com/CurrySoftware/elm-reactor-example
I think you would enjoy this write-up. WebReplay is explicitly not tracing for that reason.
https://developer.mozilla.org/en-US/docs/Mozilla/Projects/We...
Time is notoriously difficult for many reasons which have been discussed at length [1].
The trend now is that the number of programmers doubles every 5 years [2]. This rapidly expanding group of potential users and creators means features just on the fringe today might become available at any time.
1. https://infiniteundo.com/post/25326999628/falsehoods-program...
2. https://blog.cleancoder.com/uncle-bob/2014/06/20/MyLawn.html
Also designed isn't the word I'd use for Javascript.
It is neat to see how far we've come in a year though!
Literally years of development, edge cases and heuristics in order to be usable in face of changes that are meaningful in the page (since while replay is static the page itself changes).
Chrome used to have recording mode which was very decent.
It’s a huge amount of engineering work to implement a TTD, in a relatively simple (eg whole process) environment. But JS doesn’t do that, things like networking and page layout are very common so you get additional problems - at the semantically challenging end: what happens as deferred js scripts are loaded and subsequently rolled back; what happens to other resources that have load/unload handlers, etc.
There’s also another massive complexity challenge: by necessity you’d need the full DOM to support rollbacks as well. External TTDs work around this by the monumentally expensive task of essentially virtual using and tracing the entire process, but here you’re wanting to trace only a subset of the process (it needs to be a subset because you don’t want to be debugging machine instruction level, and you aren’t wanting to debug things like the GC).
Foremost mutable nature of JavaScript makes it usually heavly optimized for performance with low level in-place memory changes. These are hard to track and aggregate without some OS/HW level snapshoting support.
Next challenge is recording state of external dependencies: DOM, WebGL, events and other APIs - each would need some change tracking/snapshoting/resuming capabilities.
Recording complete low level app state changes with fine granularity would need lot of fast memory. A dedicated diffing algorithm could make it even usable on developer machine. However I think the current focus of runtime implementors is end-user performance.
Some sort of parial-TTD tradeoff is implemented in JavaScript famework/libraries level: Redux, Vuex, Elm etc. They efficently track high-level application state changes but on very small scale. The allowed changes are explicitly defined by developer and they are usually grouped into transactions/actions/scopes. Such update granularity together with reactive stateless code allows simple and cheap tracking of changes under framework control. Naturally that falls short when outside effects are involved.