A large part of the code bloat problem can be resolved if the JS ecosystem's most popular build tools had support for some of the advanced compilation features in Google Closure Compiler, like dead-code elimination and cross-module code motion [1].
ClojureScript makes heavy use of the Closure Compiler's advanced compilation features, and as a result generates code that is often orders of magnitudes smaller than what it would be without those features. Think of what a bloated mess a ClojureScript app would be if it had to include the entire ClojureScript standard library with every build. This is exactly what's happening in JS world, where developers include by default the entirety of any utility libraries they're using when they're only calling a handful of functions from them.
Before anyone starts suggesting "just use Closure Compiler for JS projects", it's really not that simple (at least when I last looked into it). There's a huge amount of friction involved in using the Closure Compiler for a regular JS project (most of which wouldn't apply to a ClojureScript project because its JS output is machine-generated, and its build chain is designed to work exclusively with the Closure Compiler and all its quirks), namely writing all your code as Closure Modules, defining externs for any third party libraries you use, and setting up the JVM-based compiler itself and integrating it with the rest of your build tools.
I hope to see some improvement in this area with the dawn of ES6 modules, since they were designed from the ground up with static analysis in mind. Robust and accessible dead-code elimination and cross module code motion for ES6 modules could easily bring about a revolution in JS code sizes on the web.
I was only commenting on the first-party code bloat side of the problem mentioned in the article, and I realize this only addresses a part of it. Asset bloat and third party scripts are entirely different beasts that can only really be tackled on a case-by-case basis.
The general term is "whole program optimizer". It what Google does to Chrome (but not Chromium IIRC), and what Proguard does to Java (e.g. Android) apps.
Define a couple entry points and use static analysis to pare down the code to that, for minification, obfuscation, and performance.
ClojureScript makes heavy use of the Closure Compiler's advanced compilation features, and as a result generates code that is often orders of magnitudes smaller than what it would be without those features. Think of what a bloated mess a ClojureScript app would be if it had to include the entire ClojureScript standard library with every build. This is exactly what's happening in JS world, where developers include by default the entirety of any utility libraries they're using when they're only calling a handful of functions from them.
Before anyone starts suggesting "just use Closure Compiler for JS projects", it's really not that simple (at least when I last looked into it). There's a huge amount of friction involved in using the Closure Compiler for a regular JS project (most of which wouldn't apply to a ClojureScript project because its JS output is machine-generated, and its build chain is designed to work exclusively with the Closure Compiler and all its quirks), namely writing all your code as Closure Modules, defining externs for any third party libraries you use, and setting up the JVM-based compiler itself and integrating it with the rest of your build tools.
I hope to see some improvement in this area with the dawn of ES6 modules, since they were designed from the ground up with static analysis in mind. Robust and accessible dead-code elimination and cross module code motion for ES6 modules could easily bring about a revolution in JS code sizes on the web.
[1] https://developers.google.com/closure/compiler/