I have a large JS file that's generated by a build process. I've noticed that after I make a change it takes much longer to run the first time, and then subsequent executions are quicker:
$ node --version
v12.5.0
$ time node build/jsx/my_script.js
real 0m4.188s
user 0m0.144s
sys 0m0.417s
$ time node build/jsx/my_script.js
real 0m0.602s
user 0m0.141s
sys 0m0.404s
$ time node build/jsx/my_script.js
real 0m0.569s
user 0m0.145s
sys 0m0.369s
Over 4 seconds for the first run, but then around half a second for subsequent runs. Even if I leave the terminal and do other work for a while, re-running my script stays fast, until its source gets rebuilt. So I don't think it's just a generic operating system cache.
I know that other scripting languages can cache an internal representation of the script to speed up subsequent runs, e.g. Python has its *.pyc
files. However, I was not aware that node.js did anything like this. It certainly doesn't leave any obvious cache files around that I've noticed.
Most of the answers on Does nodejs/V8 store compiled machine code anywhere on disk? are stale, and the currently accepted one only reveals the --print-bytecode
option without answer where or if node.js stores the bytecode between runs. It certainly looks like it's possible for node.js to be using some sort of bytecode cache (e.g. https://github.com/nodejs/node/issues/11842) but it's unclear if it actually does.
How is node.js able to run my script so much faster after one initial slower execution? Is there a way to "warm up" the mechanism without actually running the script? Is there a way to "bypass" the mechanism for testing worst-case performance?