question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. ItĀ collects links to all the places you might be looking at while hunting down a tough bug.

And, if youā€™re still stuck at the end, weā€™re happy to hop on a call to see how we can help out.

Tree shaking not working as expected?

See original GitHub issue

Expected behavior

Using named imports to target what components are imported, the bundle size created with webpack by the host should be smaller than including everything in ChartJS, as described in the integration docs.

https://www.chartjs.org/docs/latest/getting-started/integration.html

Current behavior

Bundle size is the same for both the ā€œkitchen sinkā€ import and the named imports version.

Not really a reproducible issue that is code-based, itā€™s for bundling/minifying for production useā€¦ please note this is why the required reproducible sample is just the react-chartjs-2 template.

Reproducible sample

https://codesandbox.io/s/react-chartjs-2-chart-js-issue-template-cg7b5?file=/src/App.tsx

Optional extra steps/info to reproduce

Using this in a react app, where the targeted component is lazy-loaded to try and isolate the ChartJS code into its own bundle. Both of these import strategies result in the same 97.5kb minified dynamic import bundle.

Strategy 1: named imports

import {
  CategoryScale,
  Chart,
  Legend,
  LinearScale,
  LineController,
  BarController,
  LineElement,
  PointElement,
  Tooltip,
  BarElement
} from 'chart.js';

Chart.register(
  LineController,
  PointElement,
  Legend,
  Tooltip,
  CategoryScale,
  LinearScale,
  LineElement,
  BarController,
  BarElement
);

Strategy 2: ā€œkitchen sinkā€ registrables import:

import { Chart, registerables } from 'chart.js';
Chart.register(...registerables);

Lazy-loading technique (for reference):

const ChartJsTreeShakeTester = React.lazy(() => import('./ChartJsTreeShakeTester'));

//// elsewhere in the code, used with Suspense as directed:
<Suspense fallback={<div>Loading chart...</div>}>
    <ChartJsTreeShakeTester />
</Suspense>

Possible solution

No response

Context

We are trying to create small production bundles using chartJS, and only use a subset of the components. This affects us by forcing the bundle to contain code weā€™re not using, and affects our customers with longer download times.

chart.js version

3.7.1

Browser name and version

n/a

Link to your project

No response

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Reactions:6
  • Comments:10 (2 by maintainers)

github_iconTop GitHub Comments

3reactions
harrytran998commented, May 26, 2022

Hopefully someone can fix this šŸ„¹. The bundles size include 67kbs gzip šŸ„². Thanks image

1reaction
LeeLenaleeecommented, Mar 17, 2022

When I test this I do see a minimal change between importing the minimal things to show a bar chart or importing everything.

What I did was use create-react-app to create a new react app. Only show a canvas with the bar chart. Then I build the app and check the size of the build folder. When using the auto or ā€¦registerables way of importing/registering everything I noticed they both had (almost) the same size, When I only imported the basics for a bar chart I noticed it was a bit smaller (around 6 mb and 40kb on disk)

import './App.css';
import { useEffect } from 'react';

// Size: 1.43 MB (1,504,072 bytes)
// Size on disk: 828 KB (847,872 bytes)
//import Chart from 'chart.js/auto';

// Size: 1.43 MB (1,503,745 bytes)
// Size on disk: 828 KB (847,872 bytes)
// import {Chart, registerables} from 'chart.js';
// Chart.register(...registerables);

// Size: 1.37 MB (1,441,057 bytes)
// Size on disk: 788 KB (806,912 bytes)
// import {Chart, BarController, BarElement, CategoryScale, LinearScale} from 'chart.js';
// Chart.register(BarController, BarElement, CategoryScale, LinearScale);

// Size: 1.40 MB (1,469,466 bytes)
// Size on disk: 800 KB (819,200 bytes)
import {Chart, BarController, BarElement, CategoryScale, LinearScale, Legend, Tooltip} from 'chart.js';
Chart.register(BarController, BarElement, CategoryScale, LinearScale, Legend, Tooltip);

function App() {
  useEffect(() => {
    if (Chart.getChart('zz')) Chart.getChart('zz').destroy()

    new Chart('zz', {
      type: 'bar',
      data: {
        labels: ['F', 'D', 'X'],
        datasets: [{
          data: [2,3,4],
          backgroundColor: 'pink'
        }]
      }
    })
  }, [])


  return (
    <div className="App">
      <header className="App-header">
        <canvas id="zz"></canvas>
      </header>
    </div>
  );
}

export default App;

So it seems to me the treeshaking is working, only thing I can think off why it might seem that it doesnt work is that under the hood a lot of things depend on the same base classes. So the dataset controllers for example all use the core dataset controller which is a pretty big part. So the small parts dont matter anymore then.

This can bee seen when I add the legend and tooltip to the imports.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Tree shaking not working for ES module library #9337 - GitHub
What is the expected behavior? Looking at the webpack visualizer output opened in the browser, I don't expect @shopify/polaris-icons/index.jsĀ ...
Read more >
Webpack Tree Shaking not working when importing from a file ...
If I remove the moment import from module.js tree shaking works fine and i only see square in my bundle. Is this how...
Read more >
Tree Shaking - SurviveJS
Starting from webpack 5, tree shaking has been improved and it works in cases where it didn't work before, including nesting and CommonJS....
Read more >
Tree-Shaking a React Component Library in Rollup
In my understanding, "impure" in this case means that some import statements in your code contains side-effects, i.e. content not being used directly...
Read more >
API - ESBuild
Tree shaking ; Tsconfig; Working directory. #Simple options. #Alias. Supported by: Build. This feature lets you substitute one package for anotherĀ ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found