question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Size-optimized builds

See original GitHub issue

For “reasons”, one team is having a problem with the mere size of AutobahnJS.

We don’t want to publish even more variants of ABJS, possibly tuned down and optimized rgd deps for various specific scenarios, so instead we should:

  • Document the reasons for the deps, and the contexts in which a user can do away with some deps
  • Document the process of building ABJS for users, so they can build it themselfes
  • Come up with a way that allows to control the deps included while building that does not require to modify https://github.com/crossbario/autobahn-js/blob/master/package.json#L12

Current size:

-rw-rw-r--  1 oberstet oberstet 766902 Mär 20 16:52 autobahn.js
-rw-rw-r--  1 oberstet oberstet  82116 Mär 20 16:52 autobahn.min.jgz
-rw-rw-r--  1 oberstet oberstet 275983 Mär 20 16:52 autobahn.min.js

See here https://github.com/crossbario/autobahn-js-browser

Now, I don’t have the full info here (why is 82kB too big, when you need a complete JS run-time or even a full browser thing anyways), but lets just put that as a premise (ABJS is too big).

The actual reason that the built library has this size isn’t that our code is that large:

oberstet@thinkpad-t430s:~/scm/crossbario/autobahn-js$ cloc lib/
      21 text files.
      21 unique files.                              
       0 files ignored.

github.com/AlDanial/cloc v 1.76  T=0.05 s (416.9 files/s, 117970.8 lines/s)
-------------------------------------------------------------------------------
Language                     files          blank        comment           code
-------------------------------------------------------------------------------
JavaScript                      21           1187           1092           3664
-------------------------------------------------------------------------------
SUM:                            21           1187           1092           3664
-------------------------------------------------------------------------------

The reason is that we have a set of bigger required deps, from https://github.com/crossbario/autobahn-js/blob/master/package.json#L12:

  • crypto-js
  • tweetnacl
  • msgpack5
  • cbor
  • when
  • ws

However, not all of these are actually hard deps - depending on context!

Let me untangle the reasons for these deps:

msgpack5 and cbor are obviously only needed if you want those serialization formats. So if you are fine with JSON, those are not needed, as both browsers and Nodejs run-time envs have built-in JSON.

when is only needed if you run in an older JS env that doesn’t come with its own support for JS promises. if you have ECMAScript 6 or higher, ABJS itself doesn’t need “when” (though that library provides more sugar that isn’t in ECMAScript 6)

ws is only needed if the JS env doesnt come with WebSocket support. browsers have that built in.

crypto-js: this is required by ABJS itself for WAMP-CRA and WAMP-Cryptosign:

oberstet@thinkpad-t430s:~/scm/crossbario/autobahn-js$ find lib/ -name "*.js" -exec grep -Hi "crypto" {} \;
lib/polyfill/typedarray.js:// workaround for crypto-js on IE11
lib/polyfill/typedarray.js:// http://code.google.com/p/crypto-js/issues/detail?id=81
lib/autobahn.js:var cryptosign = require('./auth/cryptosign.js');
lib/autobahn.js:exports.auth_cryptosign = cryptosign;
lib/auth/cra.js:var crypto = require('crypto-js');
lib/auth/cra.js:      hasher: crypto.algo.SHA256
lib/auth/cra.js:   var key = crypto.PBKDF2(secret, salt, config);
lib/auth/cra.js:   return key.toString(crypto.enc.Base64);
lib/auth/cra.js:   return crypto.HmacSHA256(challenge, key).toString(crypto.enc.Base64);
lib/auth/cryptosign.js:        // we only know how to process WAMP-cryptosign here!
lib/auth/cryptosign.js:        if (method == "cryptosign") {
lib/auth/cryptosign.js:            // WAMP-cryptosign challenge as required
lib/auth/cryptosign.js:    // with WAMP-cryptosign being the only configured
lib/auth/cryptosign.js:        authmethods: ["cryptosign"],

However, we only (currently) actually use 3 functions from that (see above). So we could of course copy-pasta those and include it in ABJS, doing away with the full dep. Well, this kinda sucks of course.

lastly, tweenacl: https://tweetnacl.js.org/

we need this for WAMP-cryptosign and XBR. we cannot do away with this, but this is the smallest dep of all. nothing to win here …

Issue Analytics

  • State:open
  • Created 5 years ago
  • Reactions:6
  • Comments:8 (2 by maintainers)

github_iconTop GitHub Comments

2reactions
oberstetcommented, Jun 4, 2020

I tried to exclude when.js in my project but there are two usages of when.function.call in session.js.

oh, ok. that is a (separate) bug then. exactly to allow to switch the underlying promise implementation to be used in the whole library. @om26er could you have a look pls?

1reaction
guanzocommented, Jun 3, 2020

@nidi3 here’s my webpack config that completely removes when.js from the bundle. I had to remove a ton of unrelated config, hopefully I didn’t delete anything relevant.

const config = {
    module: {
        rules: [
            {
                test (p) {
                    const has = str => p.includes(path.normalize(str)) // Windows...
                    return /when\.js/.test(p) || has('when/monitor/console')
                },
                use: 'null-loader'
            },
        ],
    },
    plugins: [
        // Stubs when/function so "when" can be totally replaced.
        new webpack.NormalModuleReplacementPlugin(
            /when\/function/,
            corePath('common/webpack/when-func-stub.js')
        ),
    ],
}

corePath('common/webpack/when-func-stub.js') returns a filepath.

// when-func-stub.js
function call (endpoint, ...args) {
    const result = endpoint(...args)
    return Promise.resolve(result)
}

module.exports = { call }
Read more comments on GitHub >

github_iconTop Results From Across the Web

Optimizing a build for size - Godot Docs
Sometimes, it is desired to optimize a build for size rather than speed. This means not compiling unused functions from the engine, as...
Read more >
Best practices for speeding up builds
Best practices for speeding up builds · Building leaner containers · Using Kaniko cache · Using a cached Docker image · Caching directories...
Read more >
Optimize your build speed
Long build times slow down your development process. This page provides some techniques to help resolve build speed bottlenecks.
Read more >
Javascript build size optimization
It gives stats before minification, but it's still useful to get a rough idea of where the biggest wins are in terms of...
Read more >
Generating size-optimized browser bundles with ...
This tutorial demonstrates how to create a custom tensorflow.js module that can be used with a bundler to generate a size optimized build...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found