prepack.I heard about prepack on Twitter today and decided to figure out what it was. When browsing through the documentation as well as the examples, it felt like the main ideas of the tool was overshed by theory on the topic instead of how it could be used for a faster web.
I really like the approach about backing up the documentation with details about what kind of Computer Science theories you've used in favor for the tool. The issue when trying to figure out how prepack worked on a lower level, was somewhat unclear to me. Even though you stated what it is, an evaluator..., Babel-Interpreter, these are hard topics to connect.
I wanted to know how you managed to read the values, not only the tool you used for it. I wanted to know how the underlying logic of prepack were in synergy with each other; such as reading, evaluating and (replacing the code) in a general point of view. Lastly, I wanted to know how the tool is helping making the web a faster place and some demo files to download.
Also, congrats on your release, the tool looks awesome! This Issue is optional feedback, but I feel like it could provide you with some insight about initial thoughts for the tool.
Summary, fixes are optional! :
Cheers!
You're basically dealing with a tool that tries to compete with the likes of what V8 is already capable of doing... but with zero stats to show its worth.
I also think the example code snippets provided are a weak argument for this tool. A loop, mutating a variable to get a determinate result... how often would a scenario like that occur? I don't think I've ever seen something like that more than a couple of times in my entire coding career. The second you add a more ambiguous variable to the loop, you need that loop to happen. So you might as well throw in the incrementing of x, as the computation required to modify that other variable may very well render the incrementing of x as negligible... unless you're doing something ridiculously intensive to x inside a loop (wtf).
I want concrete examples using realistic use cases, and I want benchmarks. Until then, I'll be avoiding it.
@ev1stensberg I found the "how does it work?" section of the website https://prepack.io/ to be very enlightening, and I think it addresses much of your question!
@jpike88 here's something more than fibonacci https://twitter.com/roman01la/status/859849691831422976 . Given your comparison to v8, I'm not sure you understand what this is for. v8 has to strike a delicate balance when JITing javascript, because it can't take so long analyzing the code that there's a lag before execution. This is ahead-of-time, and so can take as long as it wants, dramatically reducing the amount of work that v8 then has to do at runtime.
I understand the difference between JIT and pre-optimisation.
What I'm requesting is proper benchmarking on real examples. 50ms off a 150ms load may translate to 80ms off a 2000ms load. And while V8 has to work harder to do its job, I struggle to find scenarios on modern devices where it's sluggish. It's a valid question to ask, if I'm to consider a tool that may sacrifice my ability to trace errors easily.
I guess I'm curious why this is popping up now-- these aren't new ideas, nor was the JS community not ready for them earlier-- we've had minifiers for JS for over a decade. I kind of assumed if further preoptimization techniques were found to be effective in the real world, we'd have seen them by now. To me, the examples provided aren't particularly compelling for the reasons outlined above, JIT should handle most other runtime things, and the timing is off. If this does turn out to be useful in more than a handful of cases, it'll be pretty strange that a community like JS forgot to do this.
Solid real world metrics will make me shut up really fast.
In fact, existing minification libraries (like https://github.com/mishoo/UglifyJS2, which I use) already have optimisation techniques somewhat similar to this tool built into them. And they're already fully compatible with scripts that reference the DOM. In fact, many of these techniques are turned off by default as aggressively optimising JS can result in intended consequences.
Pre-optimization/minification/etc should go hand in hand in a single deployment build, otherwise you're having to deal with yet another source map, which would break existing error reporting methods.
@jaredly That section in specific is hard to connect without getting confused. I think you'retaking into account that you presume what every tool does, everyone also know
@ev1stensberg
There're links to the relevant tools and definitions all over the "How does it work?" section. I'm not sure what else would help. It's not the job of every library and tool to explain CS concepts in detail.
True, but I'm not only speaking from the point of view of not understanding CS concepts, it's also about trying to simplify things, so that non-native people can understand what is being expressed. This is quite important and relative.
So what you mean is, rewrite it as a continuous explanation at a high level ("do this, then this") and not as a collection of bullet points ("we're using this, and also this, it should be obvious to you what's between them and how they work together").
Not saying to cut it, but it would be nice to include a small snippet of description for these types of tools, their advanced, and helps people to grasp the context better. Based on personal experience, of course, may be only me thinking this way
Could you give an example of a tool or concept you'd like the page to expand upon?
Genuinely trying to help. :)
I've just re-read the "How does it work?" section, and it only mentions Babel:
Prepack operates at the AST level, using Babel to parse and generate JavaScript source code.
All other tools are implementation details. Even explaining what is AST is not particularly important. The fact that it first parses the code into an abstract model is itself an implementation detail.
In general I'd like the About section to be more relatable in terms of readability, it's just that. Example is all the other bullet points that are somewhat hard to grasp at first :)
@jpike88
In fact, many of these techniques are turned off by default as aggressively optimising JS can result in [un]intended consequences
Exactly. Prepack is actually in a position where it can optimize beyond what current minifiers can do. Even if this optimization results in "only" 5% less code and 5% faster startup, that's still 5% that the VM won't have to do every time the app runs.
Even better, it allows programmers to write code that is easy to understand and maintain but would be inefficient to run. DWIM.
@ev1stensberg Sorry if my answer seemed dismissive! I certainly didn't intend it that way. The readme gives a low-level perspective, I'l try for a mid-level one.
Prepack implements a JavaScript interpreter in JavaScript (although it cheats in some places). It then runs your initialization code -- all of the code that has to run before anything "real" happens like actually rendering your app. This includes the module definitions, instantiating a bunch of objects, etc.
At the end of this, it has a virtual "heap" with all of the objects that have been created, along with all the attributes/etc that are the result of the initialization. Prepack then writes a new javascript file that contains all of the objects, the way they are after initialization, along with all of the other code it didn't run, hooked up in such a way that the other code doesn't have to care that the initialization work which is normally done at runtime was already done at compile time.
This has the potential to cut down the startup time of an app dramatically! Instead of doing a bunch of logic & execution to initialize, the browser has all of the objects ready-made for it.
Looking back at this, I'm not sure if this is intelligible at all, but I hope it helps!
@jpike88 I apologize for being condescending -- your initial comment felt hostile, and I was defensive. In response to the question "are there really substantial benefits that would outweigh the costs involved", here's my take:
I see prepack as being most useful on mobile devices, where resources are much more constrained than on a desktop. As I understand it, the JIT tradeoffs are even starker there, and JSCore (on iOS) takes a long time to warm up before you start seeing benefits. In my work tailoring a large web app (khan academy) to mobile browsers, I've seen the js engine take multiple seconds just to evaluate the javascript modules & initialization code. If prepack can cut that in half, I'll be thrilled! On desktop, it might be the difference between 100ms and 50ms, and I'll agree with your point that the obfuscation cost might not be worth it.
Indeed, this seems to be the focus of the folks behind prepack, as their first target is to get it compatible with React Native javascript bundles.
Cheers!
@jaredly No worries, I don't take it personal or anything. This is just a user story, if people think feedback like this is bad, then I'd ask what they're thinking. Generally, this is excellent to improve and understand what parts the user doesn't understand. It makes room for improvement.
Likewise!
I have at least one real world use case for prepack, even if I cannot use prepack for it right now, I think that it should be possible in the near future.
Currently, there are a lot of API client generators that take your Swagger/OpenAPI definitions and generate an API client.
Generating code is a very efficient way (in a performance point of view) to create a REST API client compared to the fact of embedding the whole Swagger definition in your client and use it to dynamically generate the client at script initialization.
While the code generation is efficient, it is hard to debug due to the additional steps introduced by templating (see https://www.youtube.com/watch?v=EmGfdlixQHo).
With a partial evaluator, you could write code that dynamically generate the API client but optimize it with prepack in your production builds. That way you won't have to download the whole Swagger file in the client apps but you will still have easily understandable JavaScript code with no syntax overhead introduced by templates. Giving the same result than code generation but in a nicer way.
To be honnest, I failed to do so right now (this doesn't work https://gist.github.com/nfroidure/77090688788054033a4744e0d009b5d1) but i think I'll give it another try when prepack will be more smart and handle partial evaluation of JavaScript modules.
Closing as the discussion seems to have run its course.
Most helpful comment
@ev1stensberg I found the "how does it work?" section of the website https://prepack.io/ to be very enlightening, and I think it addresses much of your question!
@jpike88 here's something more than fibonacci https://twitter.com/roman01la/status/859849691831422976 . Given your comparison to v8, I'm not sure you understand what this is for. v8 has to strike a delicate balance when JITing javascript, because it can't take so long analyzing the code that there's a lag before execution. This is ahead-of-time, and so can take as long as it wants, dramatically reducing the amount of work that v8 then has to do at runtime.