Reduce bloat of your Lambdas
by Sérgio Ramos • November 11th, 2019 • 1min
serverless simplifies the creation of Lambdas by interpreting a - simpler than CloudFormation - configuration file and automating the packaging, uploading, and deployment lifecycles of applications. When packaging, it can be smart enough to exclude development dependencies. It is a good start, but it can’t:
- identify which files per production dependency are actually used;
- only bundle the dependencies used by each function.
There is a better, simpler, and faster way though: serverless-plugin-ncc. This plugin goes through each entry point of your functions and sends it to ncc, which bundles them into a single file with only the required code, tree-shaken.
Let’s see it in practice: we’re going to create 3 functions, one for a GraphQL endpoint, a Playground endpoint, and a simpler function to save payloads into an S3 bucket.
And our serverless config:
As you can see, nothing too fancy: three functions declared each with its route and handler.
Setting package.individually will generate a bundle per each function. We control that by assigning it to the INDIVIDUALLY environment variable. We also control whether serverless-plugin-ncc is active based on the NCC environment variable. For each to be active, the variable value needs to be truthy.
With this setup, we can test different configurations via the serverless cli:
λ time NODE_ENV=production ./node_modules/.bin/sls package --stage production 16.37s user 4.49s system 100% cpu 20.681 total λ ls -lah .serverless 4.7M sls-ncc-example.zip
With a global output and no ncc bundling, packaging takes ~20s and produces a 4.7MB zip.
Here’s what happens when we run the same code and set individually to true:
λ time NODE_ENV=production INDIVIDUALLY=1 ./node_modules/.bin/sls package --stage production 54.07s user 9.74s system 145% cpu 43.994 total λ ls -lah .serverless 4.7M GraphQL.zip 4.7M Playgroud.zip 4.7M Upload.zip
Because our handlers are small and serverless doesn’t exclude dependencies based on the handler, what we get is practically the same output size for each package. Also, it takes +3x the time it took previously because it’s in practice the same logic but for each function now.
Now, the exciting test:
λ time NODE_ENV=production INDIVIDUALLY=1 NCC=1 ./node_modules/.bin/sls package --stage production 9.36s user 0.86s system 129% cpu 7.923 total λ ls -lah .serverless 797K GraphQL.zip 5.5K Playgroud.zip 21K Upload.zip
Not only we reduced our packaging time in at least half, but we also reduced our packages by at least 6x.
You can check out the full source code of this example here.
Written by Sérgio Ramos • November 11th, 2019
Share this article