Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Small Browser Version #317

Open
doc987 opened this issue Apr 17, 2018 · 7 comments
Open

Small Browser Version #317

doc987 opened this issue Apr 17, 2018 · 7 comments

Comments

@doc987
Copy link

doc987 commented Apr 17, 2018

There's a lot of useful helpers in this library that would be handy in a browser setting. I followed the Quick Start section of the browserify example mentioned by doowb (#36). I ended up with a built app.js file that's 6MB. If I adjust the src/app.js file before building to first to remove the jQuery dependency parts, I end up with an built app.js file that's 5.3MB. A lot of that is comments, so I tried running Closure Compiler with simple optimizations (which gave 104 warnings), but that still leaves a file that's 1.2MB.

  1. Is the library that big, or does the example include extraneous items?
  2. If the library is that big, are there some parts that don't make sense in a browser setting (or are contributing significantly to the size) that could be removed for a browser build, so as to reduce the size?
  3. Is it possible to have a minified browser release version?
@SirRawlins
Copy link

@doc987 been toying with similar thoughts myself, I'm currently including the helpers using Browserify, and even though I only want a couple of the helpers it includes the entire bundle at 3mb.

Currently exploring other options to strip it back.

@jonschlinkert
Copy link
Member

Currently exploring other options to strip it back.

It would be awesome to have that discussion here. Hopefully, we can avoid having duplicate packages in the registry. I've considered publishing smaller helper bundles, with commonly used helpers. I also want to get rid of as many deps as possible.

@SirRawlins
Copy link

@jonschlinkert for sure, at the moment I'm approaching it like this:

// Include handlebars core.
var handlebars = require('handlebars');
// Register single helper bundle.
handlebars.registerHelper(require('handlebars-helpers/lib/comparison'));

This does a 'reasonable' job of stripping things back, but you still end up with the entire comparison collection, when in fact I may only need 1 or 2 of it's methods.

I think as a temporary work-around for myself I'm going to pull the method(s) I need into my own codebase without the things I don't.

One potential approach would be to break each function in a collection into it's own file, so people could require('handlebars-helpers/lib/comparison/is) for example, and include only the single helpers that they need.

@SirRawlins
Copy link

@jonschlinkert another idea which just sprung to mind would be to change the load behaviour when loading specific collections require('handlebars-helpers')(['math', 'string']) so that the collection lib isn't required until then, rather than eager-loading the entire lib directory.

@doowb
Copy link
Member

doowb commented May 30, 2018

One potential approach would be to break each function in a collection into it's own file

I like this approach to make it easier for users to be able to include specific helpers and tell bundlers which files to bundle. I don't like the approach because it could make maintenance a little more difficult.

We could also add a build step that "bundles" the files into a single file for node to reduce load time when the entire library is loaded.

I think another issue with bundle size is that Handlebars gets bundled with handlebars-helpers. We've talked about removing Handlebars completely and letting the user pass it in if it's needed.

edit: the second approach with passing in the collection and helper name will probably make a lot of bundlers complain because it's harder to statically analyze dynamic requires. If we made them getters, then they wouldn't be loaded initial but the bundlers will still bundle all of the files.

@jonschlinkert
Copy link
Member

We could also add a build step that "bundles" the files into a single file for node to reduce load time when the entire library is loaded.

Yeah, IMHO the best overall solution is to:

  1. publish every single helper as an individual helper
  2. publish helper collections, similar to the ones in lib currently, but also other mixes of collections for certain purposes.
  3. require the collections into this library.

Regarding package size, and browserifying/webpacking etc, first and foremost this approach allows users to use only the helpers they need. It's a common misconception that writing code locally will reduce the size of the final bundle. That's only true if you don't know how to use webpack or rollup to inline dependencies, and you're not doing anything to remove or reduce dead code.

If you use these tools correctly, there should be little to no difference in final size between code that is in your local lib/helper.js file versus node_modules/some-package/index.js file.

Also, as @doowb mentioned, in an effort to reduce dependencies here we can explore options that might allow us to inline dependencies before publishing. But there are tradeoffs with this, so it might not make sense.

@flyingL123
Copy link
Contributor

There really needs to be a way to reduce the size of this library. Using webpack, my main bundle went from 4.7 to 8.5 MB just by including a single import helpers from 'handlebars-helpers'; line. I only really need 3 or 4 of the helpers, but it was getting ridiculous rewriting the ones I need since there were all kinds of dependencies needed as well.

So I figured I might as well just include the library the right way using webpack. However, I think the file size increase is too drastic.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants