Chart.js: Need to reduce library size

Created on 5 May 2016  路  19Comments  路  Source: chartjs/Chart.js

With the addition of horizontal bars, v2 is huge! We need to refactor code to improve minification. I think we can shave off 20KB or more from the minified size

Largest individual source files

Minified size determined using: http://jscompress.com

Listed in decreasing order of minfied size

| File | Starting Unminified Size | Starting Minified Size | Current Minified Size |
| :-: | :-: | :-: | :-: |
| Core.helpers.js | 28.2 KB | 13.18 KB | |
| Core.scale.js | 24.1 KB | 12.46 KB | |
| Core.tooltip.js | 19.2 KB | 10.77 KB | |
| Core.controller.js | 18.0 KB | 9.74 KB | |
| Scale.radialLinear.js | 16.7 KB | 7.02 KB | |
| Controller.line.js | 12.1 KB | 7.69 KB | |
| Controller.doughnut.js | 11.9 KB | 7.32 KB | 5.33 KB |
| Scale.time.js | 13.1 KB | 6.92 KB | |
| Controller.radar.js | 9.6 KB | 6.49 KB | |
| Controller.polarArea.js | 9.5 KB | 6.36 KB | 4.24 KB |
| Controller.bar.js | 10.7 KB | 6.10 KB | |
| Core.legend.js | 10.1 KB | 5.13 KB | |
| Controller.bubble.js | 6.6 KB | 4.24 KB | |
| Scale.linear.js | 8.9 KB | 4.02 KB | 3.65 KB |
| Scale.logarithmic.js | 6.1 KB | 2.98 KB | 2.88 KB |
| Core.title.js | 5.0 KB | 2.73 KB | 2.16 KB |
| Element.line.js | 5.1 KB | 2.58 KB | |
| Element.point.js | 4.4 KB | 2.58 KB | 2.45 KB |
| Core.layoutService.js | 10.6 KB | 2.42 KB | |
| Core.animation.js | 4.0 KB | 2.28 KB | |
| Core.js | 3.3 KB | 1.66 KB | |

Other dependencies

| File | UnminifiedSize | Minified Size |
| --- | --- | --- |
| Color.min.js | 114 KB | 22.8 KB |

help wanted blocker bug

Most helpful comment

Use ES modules?

// like this?
import { Bar, Line } from 'chart.js';  // tree-shaking with Rollup bundler

new Bar({ ... });
new Line({ ... });

All 19 comments

@tannerlinsley @derekperkins @zachpanz88 can you help expand the table at the top?

From the Chart.js folder, the following will find all src files and order them by size from largest to smallest.

find ./src -type f -printf "%s\t%p\n" | sort -n

I added all of the biggest files. I left out smaller files because their size was so small that any reduction would not be significant to the overall build.

Thanks @zachpanz88

I think we should increase the docs about creating custom builds (is this still supported in v2?), which would allow users to create their own file with only the charts they need. This is all I found (v1.1.1).

If it is no longer supported, adding it back could be a good option to reduce file size.

Yeah, we can add it back. Certainly stuff like the controllers and scales can be dropped without too much work

+1 and that's why I'm still with v1

Made some progress on the doughnut / polar area controllers. I actually think the polar area controller could derive from the doughnut controller because they are almost identical

I'm thinking that we should revisit the idea of making the library smaller. I will work on setting up a build system where users can choose what types of charts/scales they want to use without having to use the entire library.

@zachpanz88 I don't think that's the solution because it seems that most users just want to use dist/* files (CDN/NPM/Bower) and don't want to build a custom version on their own. We can't generate all possible combinations (currently 5020?) of chart/scale types, so finally, changing the build process might be overkill since it will satisfy only a few users (in addition to become tricky and maybe confusing).

Instead, I really think we should focus our effort on making plugins _famous_ and easy to use: plugins should be accessible via a dedicated web page with proper descriptions, links, live examples and documentation - for all existing plugins - but also packag-able online (e.g. Zepto Builder or Prism). We could also provide an endpoint to dynamically generate a custom package (e.g. http://download.chartjs.org/?plugins=bar-chart,line-chart,linear-scale,time-scale,zoom,deferred). It should be also easy to use plugins with NPM/Bower (maybe via a centralized in a repository via submodules).

There is a lot to do around plugins, not only in the code, surely not exactly this way, so would require a deeper brainstorm from all of us. But as soon as we can _really_ rely on plugins, we could move charts/scales as plugins (in their own repositories), and keep the "core" pretty small. Of course that's a pretty huge / complex task, but I feel it's more the direction to go to make the library smaller with a robust build process. It would also encourage people to use plugins and/or create and distribute their own without pushing to make that part of the "core" - and so less GH issues :).

Hmmm, I do like the idea of being able to take things out of the build. I know that the V1 gulpfile had the ability to select chart types and it has been requested before that we provide a way to do this.

I also like the idea of having everything as a plugin in it's own repository. Certainly the legend and title block are already implemented as plugins internally. Since I am in the tooltip stuff, I can look at converting it to a plugin as well.

The way scales and controllers are already set up we can move them to their own repositories without any problems. The controllers just depend on the global chart variable and then register themselves there. Scales work the same way.

I don't really know if moving everything to separate repositories is the right option at this time. If we did that, it should be for a v3 IMO. I don't really see the need to completely restructure the library because it would make it a lot harder for new people to contribute and would overcomplicate things. Our download count has been steadily increasing every month so users must be liking the way the repo currently works.

You could break the project up and have each chart type and each scale type in separate modules or packages, the way other projects like Twitter Bootstrap and Angular.js have done it. Then devs can just npm install the parts they need. Of course, you'd probably still want to publish a bundle of everything.

@compwright yes, that's how the system worked in v1. I might start working on this for an upcoming version. npm install would still come with the 4 current built files but I would add something to gulp that allows users to create custom builds with just what they want.

Not sure if related, but I think making the library modular can help, with the advent of modern build systems that allow tree shaking an app and bundles only the required modules. to fix #3533 I experimented with restructuring the library using es modules here and got most the tests passing (with the exception of one test that relies on globals) so it you think it is pursing we can take it from there.

@salzhrani which globals were you running into ?

here, it fails because classes load the helpers they need as modules and not of Chart.helpers

ah, ok. off the top of my head i'm not sure of a quick solution to that

Use ES modules?

// like this?
import { Bar, Line } from 'chart.js';  // tree-shaking with Rollup bundler

new Bar({ ... });
new Line({ ... });

Closing since I think we've taken this as far as we can without taking out features. Converting the internals to ES6 modules is it's own issue

Was this page helpful?
0 / 5 - 0 ratings