Optimizing Alexa lambda functions

A basic NodeJS Alexa fact skill based on the fact template builds to a 4.5 MB deployment package (and that is with best zip compression). This is way too much for code which does just spit out a random string.

The only dependency of this module is the alexa-sdk, and yet a npm install --production still leads to 33 MB of code:

$ du -hd1 node_modules/ | sort -hr
33M     node_modules/
25M     node_modules/aws-sdk
4.9M    node_modules/lodash
1.1M    node_modules/crypto-browserify
524K    node_modules/i18next
392K    node_modules/buffer
336K    node_modules/jmespath
120K    node_modules/alexa-sdk
112K    node_modules/xmlbuilder
112K    node_modules/events
100K    node_modules/i18next-sprintf-postprocessor
96K     node_modules/url
84K     node_modules/uuid
84K     node_modules/sax
80K     node_modules/querystring
64K     node_modules/xml2js
48K     node_modules/.cache
40K     node_modules/base64-js
36K     node_modules/punycode
36K     node_modules/isarray
36K     node_modules/ieee754
4.0K    node_modules/.bin

33 MB for the node modules in PRODUCTION mode. That’s just plain unacceptable, since no dependency is actually used within the skill.

The biggest part of this hell is the aws-sdk. It’s required by alexa-sdk, and seems to be used for state management (you can save skill state, which is internally saved to DynamoDB). But what if you don’t even need that functionality? Or, all the other parts of the aws-sdk (S3, RDS, …)

Actually, you wouldn’t even need the aws-sdk itself, since it is pre-installed in the Lambda function environment [1].

Solution

Use webpack

Using webpack to bundle and minify the dependencies into one script, the deployment package size goes down from 4.5 MB to around 17 KB. The main advantage is that only actual used dependencies are included, and the remaining ones are combined into one file.

So you tell webpack to exclude the aws-sdk:

externals: ['aws-sdk'],

Webpack introduces a new problem though: it can’t directly work with ES6 code or newer. Fortunately it can be configured to pre-process it’s input files via plugins, such as babel for transpilation to older Javascript.

Have a look at a working example over on my github: alexa-kempten-facts

comments powered by Disqus