[Blue Ocean] Tracking NPM dependencies and managing the js download sizes

51 views
Skip to first unread message

Tom Fennelly

unread,
Jun 7, 2016, 11:49:56 AM6/7/16
to Jenkins Developers
Thought I'd share something with those interested in Blue Ocean wrt how we're building things there and some of the challenges we're trying to deal with.

The Blue Ocean (BO) UI is a single page app (SPA), with lots of client-side JavaScript, using new frameworks/tools/libs such as React, Redux and more. So there's lots of "new" stuff in there when compared with how Jenkins UI's have been built in the past ... a big learning process for everyone involved.

All of this client-side code is not in a single .js file, but instead split across multiple self-contained javascript "bundles", and using some js-builder and js-modules magic to "link" things together at runtime.

The main/startup "bundle" is currently defined in the "blueocean-web" and it is responsible for loading some/all of the "core" modules used by BO, including react, react-dom and some others. This means that these modules are all inside the blueocean-web "bundle" (it has to be this way because of how react works).

One of the ongoing challenges we are looking at is - how do we make sure these bundles don't get too bloated and cause suckie UX because the user is kept waiting on JS to load. This is always going to be a challenge and something we need to monitor, just like personal fitness and weight is a constant challenge for people.

Anyway ... what I wanted to share here was a simple tool we found for analysing browserify generated bundles (we're currently using Browserify to generate the actual .js bundles). It tells you the composition of the bundle and which npm packages and CommonJS modules are contributing most to the bundle size. It's called discify and after installing and running it, you can get some interesting info from it in the form of an interactive (hover the different slices to get details) chart that highlights the packages/modules going into the bundle, and the percentage of the bundle size each is contributing.


Yeah ... the above is just giving a flavour ... you really need to run it and interact with it to see. I'd encourage people to do that, especially if they are contributing to BO and adding dependencies ... we need to be very careful that the weight added by a new dependency is really justified in terms of the benefits that dependency brings. Adding every new "shinny" lib we see is just going to result in problems down the road !!

Installing discify is dead easy ...

npm install -g disc

Then in one of the BO plugins (e.g. blueocean-web), just run gulp build as normal, but adding the --full-paths switch ...

gulp --full-paths

As this runs, the build will output the locations to where the bundles are being generated. You can use this to work out the path that needs to be supplied to the discify command (or you can just look in the gulpfile.js). e.g. for the blueocean.js bundle generated by the blueocean-web build ....

discify /Users/tfennelly/projects/blueocean/blueocean-web/target/classes/io/jenkins/blueocean/blueocean.js -O

Of course, we can use minification and gzipping to reduce the full size, but we need to keep a close track on this and be careful when adding dependencies.



Robert Sandell

unread,
Jun 7, 2016, 12:15:04 PM6/7/16
to jenkin...@googlegroups.com
Are there any code sharing between bundles?
I mean if two bundles are using jquery 1.99.3 will there be two separate instances of that code downloaded and compiled? Or is the various packages downloaded independently and then just instantiated separately in each module?

/B

--
You received this message because you are subscribed to the Google Groups "Jenkins Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jenkinsci-de...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/jenkinsci-dev/640a15b7-ede1-421c-849d-c78bc9ffee1e%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
Robert Sandell
Software Engineer
CloudBees Inc.

Tom Fennelly

unread,
Jun 7, 2016, 1:45:27 PM6/7/16
to Jenkins Developers
On 7 June 2016 at 17:14, Robert Sandell <rsan...@cloudbees.com> wrote:
Are there any code sharing between bundles?
I mean if two bundles are using jquery 1.99.3 will there be two separate instances of that code downloaded and compiled? Or is the various packages downloaded independently and then just instantiated separately in each module?

/B

It can work either way. If you are creating a bundle that uses jQuery internally, it can be created to include its own copy of jQuery, or can be created to use an "externalized" shared instance of that particular version of jQuery.

Some more docs on how to do that can be found in this sample plugin.

So what this means then in this case is ... say plugin bundles A and B both externalizes jquery 1.99.3 (not even sure such a version exists ... doesn't matter) ... at runtime, plugin A loads first and triggers the loading of the externalized jquery 1.99.3 ... when plugin B is loaded (later) it will get the same/shared instance of jquery 1.99.3 loaded earlier by plugin A.



Robert Sandell

unread,
Jun 8, 2016, 6:52:24 AM6/8/16
to jenkin...@googlegroups.com
OK, thanks Tom,

I was just pondering possible optimization paths. If the static code could be shared but having separate runtime instances for the modules that needs it we could potentially save some download and compilation time.

/B

--
You received this message because you are subscribed to the Google Groups "Jenkins Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jenkinsci-de...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.
Reply all
Reply to author
Forward
0 new messages