It’s the end of AWS Lambda support for Node.js v10. AWS Lambda support for Node.js 10 is due to end in August 2021. It’s time to switch! In this article, we’re discussing and comparing the differences of working with Node.js 10 and Node.js 14 + AWS Lambda, the impacts, and benefits of this change.
Original article with code snippets here: https://dashbird.io/blog/aws-lambda-nodejs-10-vs-14/
AWS Lambda supports multiple versions of programming language runtimes, but not forever. That’s because the creators of these programming languages don’t support them infinitely either.
AWS Lambda also only supports the long-term support (LTS) versions of Node.js: the even version numbers. Currently, versions 10, 12, and 14 are all supported, but in August 2021, the support for version 10 is running out.
So it’s time to switch, but besides evading the support end, what benefits does it bring to switch directly to version 14? In this article, I will go over the changes that have happened since version 10 of Node.js.
What Features were Added Since Version 10?
Let’s start with the ECMAScript additions to JavaScript. Usually, they are supported in the JavaScript engine before they are standardized. The idea is that nothing, that isn’t working in practice, gets standardized.
This doesn’t mean that all JavaScript engines support every ECMAScript feature before it is standardized. After all, the committee can’t wait for every JavaScript engine that is out there. For example, proper tail call optimization is standardized for years now, but only a few engines have implemented the feature.
Anyway, let’s check what happened since version 10!
Optional Chaining and Nullish Coalescing
This is one of the biggest additions, in my opinion. Gone are the crashes because you tried to access an attribute of an undefined variable, or you set a default for a value that was null-ish.
The optional chaining operator ?.
is an alternative to the regular chaining operator .
they can be used all the same; the only difference is that the regular chaining operator will crash if you try to access an attribute on an undefined variable. The optional chaining operator will simply return undefined
.
If at least one part of this chain isn’t an object, deepValue
will be set to undefined
.
The nullish coalescing operator ??
is an alternative to the logical or operator ||
used to set variables to a default value.
The problem with the logical or operator was that it also used the default when the value was something that could be automatically converted to false
, like the number 0
. The nullish coalescing operator would only use the default when the checked variable was null or undefined.
In the example, the logic or operator would set the amount to 20
even if the input
was 0
, but the coalescing operator would leave it at 0
.
The two new operators work nicely in tandem.
Symbol Additions
The Symbol class got two new additions. If you create a new symbol with a description, you can now check it later with the description property.
This example will log “description
” to the console.
There is also a new well-known symbol called matchAll
. It can be used to create custom matchAll functions for your data types.
The object numbers
needs a generator function (that’s what the *
means) in its Symbol.matchAll
property, so it can be used as a parameter for the String.prototype.matchAll
method. This example will output ["2021", "05", "12"]
.
Global This
The unification of window
, self
, frames
, and global
into one global object called globalThis
. Back in the days, the access to the global object differed from where your script was running, but if you tried to access window
inside Node.js or a worker thread, it would fail. With globalThis
your script doesn’t have to care anymore.
This example works in all current browser versions and Node.js:
Class Fields
Since Node.js 10, there have been some additions to classes as well: instance class fields, static class fields, and private class fields.
Before version 12, instance fields had to be set in the constructor, and static fields had to be set via the prototype, and both were always public. Now you can set them all in the class definition and modify their visibility.
Let’s see how it works in practice:
Flattening Arrays
If you end up with a nested array, and you want to lift the nested elements back to the top array, the new flat
method for arrays is the solution.
The example above, flattened, will contain [1, 2, 3, 4, 5, 6, 7]
. But keep in mind that it only flattens a depth of one; you have to call it again if you have deeper nested arrays you want to get rid of.
Since the flat
method is usually called to clear up the array structure before a call to the map
method, a shortcut method called flatMap() will work as a map
with a flat
applied before.
In the following example, the item is always a number and never an array because the nested array is flattened before passed to the callback function.
International Display Names
The new Intl.DisplayNames API allows to translate region, language, and script display names automatically.
This would display “德文”, the traditional Chinese translation of the language “German”.
Numeric Separators
It’s now possible to add underlines to number literals to make them more readable inside the code.
Performance Improvements
Since version 10, many performance improvements have happened. The startup time improved by 30%, which can shave quite some time from your cold start latency.
The heap size configuration was done with two default values before, but in version 14, Node.js will take the actual available memory into account when configuring the optimal heap size. Since AWS Lambda allows for very flexible memory configurations per function, this could help you get more bang for the buck.
Find out more about saving money on Lambdas in our 6 AWS Lambda Cost Optimization Strategies That Work article.
I tried a prime number calculation on AWS Lambda with Node.js 10 and 14 to see the differences. First, I calculated primes between one hundred and one thousand and then those between one hundred and one billion. I run this with 128MB and 1024MB memory configuration, to see how the init times and runtime durations changed between the two versions.
The following graphs illustrate the differences.
Blue marks Node.js 10 and red 14. As you can see, the init timings got better by ~20% and I just switched the runtime version. Because Lambda functions are billed by millisecond this is real money you can save. Also, short-running Lambda functions can reduce the latency quite a bit.
Again, blue marks Node.js 10 and red 14. This time I measured the duration an invocation took. The difference between the primes between hundred and thousand wasn’t much, so I left them out here, but for longer computations, like finding the primes between one hundred and one billion, it makes a huge difference. This saves a huge chunk of money and could even make it possible to do slow calculations synchronously as an API Gateway response now.
Other Additions
The diagnostic reports help with analyzing the behavior of a Node.js program. It will log out a JSON formatted string into a file that you can check for more details than CloudWatch gives you.
Find out how you can get even more detailed and faster AWS data analytics, observability and debugging.
TLS 1.3 and QUIC protocol support have landed in the LTS version of Node.js, so your Lambda can keep communicating with the latest services out there.
The worker threads API is now stable. You can use it for computation-intensive workloads. Usually, Node.js is a single-threaded environment, but you can now execute JavaScript with worker threads in parallel. When you configure Lambda memory, the vCPU cores are also configured implicitly. If you set a memory limit of 10 GB, you also get 6 vCPU cores, which you can now utilize with Node.js worker threads.
Full International Components for Unicode (ICU) support has landed in Node.js. ICU is a set of “libraries providing Unicode and Globalization support for software applications”. The full list of features can be found on Node.js’s GitHub Repository.
Conclusion
The sun is setting on the LTS for Node.js version 10 in a few months’ time, and so is the AWS Lambda runtime support. If you have to switch anyway, why not go straight to version 14? It will give you a longer support time in the future, and you get a whole bag of extra features that improve the coding of Lambda functions and their performance on the AWS platform.
Further reading:
AWS Lambda Node.js errors and exceptions
How to deploy a Node.js application to AWS Lambda using Serverless