...the wise words of Donald Knuth:
Premature optimization is the root of all evil
That aside...
readFile instead of readFileSync) wherever possible.try / catch statements to their own function, as V8 has a hard time optimizing functions that contain try / catch operators. Better yet, use a continuation monad like Promises or Tasks/Futures for async work that will emit errors and rely on the rejection mechanism of your monad. For sync work, consider an Either monad._slice.call(arguments), define an empty array and loop through the arguments object, pushing each item into said array.lodash.memoize(fn) will work.For anything outside of the realm of these rules, you can do something about that too...
Run your Node.js app with the profiler enabled:
$ node --prof server.js
This will generate a log file ({id} is just a placeholder):
isolate-{id}-v8.log
At this point, if you have Node v4.x or above, you can run:
$ node --prof-process isolate-{id}-v8.log
After some time, your console should have some output on how many CPU ticks were spent on different parts of your app. I won't go into too much detail on how to refer to this output (you can research it yourself) as I prefer to pass the log file into Chrome DevTools:

Just click the "load" button and import your log file from the previous step. Your profile should appear on the left hand sidebar, where you can click to access it and see an overview of your app's performance profile. There are 3 modes: bottom up (heavy), top down and chart. I find chart to be the most easy to grep.

The chart above is just a profile for a minified browser build, so passing in your node.js log file won't look as "hieroglyphic" as this example. You can click on any of those data points to open the DevTools source editor to see the source code - to the left will be a sidebar that contains numbers - these numbers represent the number of milliseconds the function defined on that line took to execute.