AmpersandJS / ampersand

Quickest way to get started with ampersand.
MIT License
812 stars 41 forks source link

Ampersand is much larger than backbone + underscore #111

Closed ben-eb closed 9 years ago

ben-eb commented 9 years ago

I've set up a very bare bones application which depends on:

The application's full source code is:

module.exports = {
    view: require('ampersand-view').extend({}),
    collection: require('ampersand-collection').extend(require('ampersand-collection-rest-mixin'), {}),
    router: require('ampersand-router'),
    state: require('ampersand-state')
};

Run through browserify and uglifyjs yields:

131731 21 Mar 11:39 ampersand-bundle.js

Now just by packing backbone, underscore and jQuery into a file I get this:

129546 21 Mar 11:42 backbone-bundle.js

That's not too bad right? But, Ampersand doesn't come with a large DOM manipulation library. Instead, it packs a lot of different dependencies together - you have underscore, backbone-events-standalone which ships another version of underscore, and some of the modules pack amp modules which are great, but completely irrelevant when you are already depending on underscore for much of the core.

In fact, if we strip out the jQuery from our backbone bundle, we get:

36446 21 Mar 11:51 backbone-bundle.js

Is this not much more desirable?

What are the benefits of using Ampersand modules over backbone and underscore? So far it appears that they present only a facade of modularity; of course, you can install its separate component parts, but they come with a large amount of dependencies that are not consistent with each other, so that when someone actually builds an Ampersand app it comes with a ton of unnecessary bloat.

One of the reasons why I wanted to build Ampersand apps is the modularity, the bundling that commonjs provides. I don't want to have to use AMD with backbone and require.js, I want to use tiny modules that do one thing well. But right now I am not seeing why I should use Ampersand when backbone is already available, is far smaller and even though it is less modular, the total sum of it and underscore is far smaller than Ampersand modules.

Please, do not be selfish with your dependencies and only include what you need. One of backbone's greatest strengths is its small size, and that is really relevant on mobile devices. I would love to say that of Ampersand, too.

prust commented 9 years ago

@ben-eb: I've just been watching ampersand (I'm not on the core team), so I'm not speaking with authority here, but I believe much (perhaps all?) of the size issue will be addressed if/when Ampersand converts to lodash.

Henrik's post introducing amp demonstrates his awareness and concern about long dependency chains, mismatched versions and total size -- that's what motivated the creation of Amp. But the Ampersand project hasn't realized those benefits yet because it hasn't fully moved to amp (as you noticed with multiple versions of underscore included).

This is most likely because of jdalton's great response on Amp's "We should quite possibly just use lodash-node" issue. It's great to see jdalton's readiness to address the points Henrik raised and to see Henrik's willingness to consider adopting lodash:

We've had some more discussions around l-dash, since they've pretty much point-by-point matched what my complaints were in that post and are wanting to do that work for us.

Henrik has mentioned that he's going to blog about this, so jdalton (and the rest of us) are waiting for it -- perhaps not quite as patiently as we should :-)

The conversion from Amp to lodash will take a bit of time, but IMO it will be well-worth it. Not only will the core team be more focused on Ampersand but it will also result in increased mindshare & adoption with the rest of the node community.

ben-eb commented 9 years ago

@prust At the moment I am concerned that things are being done half-heartedly with this migration. What we have ended up with is that some people have replaced underscore with amp in only some of the modules, so that the current latest major versions of all core modules are not on the same dependency graph.

In my opinion it is not acceptable to do a migration like this incrementally. Whichever the team decide to use, whether it is amp modules or lo-dash, the work should be done on branches for all core modules and a co-ordinated release should be done.

It is more acceptable for me that all core modules would stay on underscore@1.6.0 rather than the half baked mess we have now.

lukekarrys commented 9 years ago

Agree that we should be moving all core modules to one specific util library, and that will alleviate that specific issue.

I was curious about the numbers though, because last time I checked stuff like that out, a simple ampersand app was smaller than jQuery. Here's a gist I made with my findings: https://gist.github.com/lukekarrys/3a9b9fd229cce153145e#file-output-txt

It compares min+gzip size (which is what you would get in most production apps) and it comes out:

It is definitely still bigger than just Backbone+Underscore, but I think the number is pretty good and could be even smaller once we get the utility library situation handled.

And In my experience the extra 10.6 kB in the ampersand app from the Backbone+Underscore is worth it for the extra features in Ampersand. :smile:

ben-eb commented 9 years ago

Thanks, guess the gzip compression alleviates much of the problem, although I reckon the library could be more performant once duplicate code is eliminated entirely.

And yes the extra features are useful, which is why I'd prefer to use Ampersand over Backbone. :smiley:

lukekarrys commented 9 years ago

Now that we've announced the switch to lodash I think that will fix the last remaining point of this issue. Once that is done in all modules, I'm going to run my tests again and we can see how many bytes we've saved!

ben-eb commented 9 years ago

Sounds good to me. Thanks! :smiley:

lukekarrys commented 9 years ago

Just to give this an update now that all the modules (and dependencies) in this example have been published to use individual lodash.* packages and are free of amp-* and underscore packages:

The size of the ampersand-bundle (after npm dedupe and using bundle-collapser) is now 24.36 kB. So it's now 1.9 kB larger than it was with underscore, but I think that is pretty good.

I updated my gist with the latest output sizes and added a few other helpful things to confirm we're getting the smallest possible file size (like the output from npm dedupe and an npm run-script to list the all the modules used by the ampersand bundle).

prust commented 9 years ago

thanks @lukekarrys!

ben-eb commented 9 years ago

Awesome, thank you. :+1: :clap:

chrisbateman commented 9 years ago

@lukekarrys I ran the below on a file that simply requires state and view, and I'm at 29kb minified/gzipped. Did a npm dedupe. Am I missing something?

{
  "name": "SizeTest",
  "version": "1.0.0",
  "dependencies": {
    "ampersand-state": "*",
    "ampersand-view": "*"
  },
  "devDependencies": {
    "bundle-collapser": "^1.1.4",
    "uglify-js": "^2.4.20"
  },
  "scripts": {
    "build": "browserify -p bundle-collapser/plugin index.js | uglifyjs > bundle.js"
  }
}
lukekarrys commented 9 years ago

@chrisbateman What are you using to calculate the gzipped size? My example looks like its using the same stuff as yours, except for that part.

I'm using js-size which uses uglify-js and gzip-size under the hood, so I'm wondering if there are some inconsistencies with that measurement?

I re-ran my example from a clean repo just to test and it's only at 25.25 kB which includes a few of the other modules as well.

chrisbateman commented 9 years ago

@lukekarrys Hmm - so I'd looked at that size just in the browser served from a Cloud9 preview server (apparently they use cheap gzipping).

I ran your example and moved it to my own shared hosting server, and it's 68.6kb gzipped. Piped through the default uglifyjs it's 32.7kb gzipped (raw content shows as 132kb). Pretty close - but I guess gzipping implementations vary more than I thought.