This blog outlines how I did it and how you can help us make Zones even better.
When the Zones library was introduced by Bert, he had been concentrating on its design and use and had not yet spent time optimizing its performance. When I started looking for performance bottlenecks, I started with the built-in v8 profiler but quickly realized that I could not identify a major culprit for the drop in performance. It seemed to be evenly-spread on all calls. To get around this, I switched approaches, tore apart the library, and started enabling modules one at a time and optimizing as I went along.
- Using classes with prototypes instead of maps
- Minimizing object creation
- Isolating try/catch/finally so that functions would not be de-optimized
- Identifying and removing polymorphic function calls where possible
- Identifying and preventing leaking of the arguments array
- Removing extraneous closures and fn.bind(context) calls etc.
I also made gathering stack-traces a configurable option as this is very expensive in v8.
The end result can be illustrated by a few simple benchmarks. The first compares the performance of a simple “hello world” HTTP server, with and without a zone for every request. The second does the same but for a simple Express application.
|Benchmark scenario||Basic HTTP
(req/sec) [% drop]
(req/sec) [% drop]
|No zones loaded||11135.85 req/sec
|(0.1.0) zone per request||4014.29 req/sec
|(0.2.0) zone per request||9116.60 req/sec
The benchmarks show about a 30-40% improvement in speed between the original Zones library and version 0.2.0 which will be released in the next few days. With this improvement in speed, I hope more of you will be enticed to try Zones in real-world use cases and provide feedback on what else we can optimize. The repo is open for contributions here: https://github.com/strongloop/zone
Zones Library v0.2.0 is our first pass at coming up with this API. The main differences are:
- The concept of the Gate has been removed in favor of new methods to enable callbacks to be easily bound to a zone.
- New APIs such as before/after hooks have been added to bring Zones closer to Zone.js and Dart’s Zone libraries.
- Promise-style reject/resolve methods have been added. Note, however, that we did not add promise chaining, since there are some open design questions.
In addition, we are also working on behaviors which will bring our Zones library closer to Zone.js.
How Zones are different from Promises
Although the Zones library tries to solve the “callback hell” issue, it takes a different approach from Promises and other flow control libraries. It concentrates on encapsulation and composition rather than the explicit approach of Promises.
When using Promises, you have to explicitly indicate the asynchronous operations that make up the Promise. With Zones, you just have to wrap the function within a zone and this is handled automatically.
That said, depending on the situation, you might want to use Promises in some places and Zones in others. Zones are not a full alternative to promises.
To learn more about Zones, check out Bert Belder’s presentation given on May 2014 at the BayNode Meetup.
Version 0.2.0 has been a big step in getting Zones ready for prime time but the project still needs people like you: Developers who use it and suggest additional features, improvements, or API enhancements. Our running backlog for Zones includes:
- Writing an Express middleware module that wraps every incoming request in a zone.
- Modifying a few existing npm modules that need to be zone-aware to work with apps that use Zones. This need usually arises when a library lazily creates pooled resources: If a driver needs to lazily creates a connection to a database, and keep the connection open for later reuse, then the connections would need to be zone-aware so that they are not closed and cleaned up when the current zone exits. We need to design an API to make this really easy.
- We also want Zones to play nicely with Promises and Yield.
This is where you can come in: Try Zones in your project, tell us what’s missing, what you want improved. Submit issues and PRs, get on the Zones mailing list and help us take Zones to the next stage!