It's common in javascript at least because you're delivering the code across the network, frequently, and at dev time, you're probably pulling in large libraries of components and frameworks that you may not use in their entirety. Since the load time is one of the core metrics used by SEO, and has shown to have a significant impact on conversion rates, it's worth the investment to remove code that's not being used.
I'm sure there are other places where it's applicable, but modern javascript and webapps have to be the quintessential use case.
Most other compiled languages do dead code elimination, which sounds similar but is a little different. Think of dead code elimination as removing code that doesn't change the output, while tree shaking instead includes code that could run.
To apply this to python is interesting - if you were creating a packaged version, I could see "compiling" the code to a separate package with only the required imports.
I know that Microsoft is doing some kind of treeshaking in Blazor (basically a .NET runtime in WASM), since they do not want to ship a full .NET base library to the browser. Not JS related, but the problem is the same - you want to ship as little data as needed on websites that are dynamically loaded.
It could be, but I don't see it as too practical as dependencies are very likely quite transparent and don't themselves rely on many dependencies. But for JS?
There's no reason you can't write JS the same way you would write Java or C++. (And if you were writing "serious" applications in JS that weren't web apps before NodeJS came along, you did. Of course, you still can, too.)
They are not the same, and the term comes from Lisp in the early 90s, not JavaScript. Tree-shaking is actually "live code inclusion" - in other words, it approaches the problem from the other direction.
In Lisp this might work like this (did and still does work in some commercial Lisp systems):
For example a Lisp system may consist of starting a memory image from disk, which leads to a live running memory heap. The tree shaker then may break unused links in memory - either automatic or under programmer direction. The garbage collector then frees the unused memory. Lisp then dumps a new (typically smaller) image, which has unused code and data removed.
They both start at the entry block (or exported symbols if it's a lib) and traverse the program graph, keeping only live branches. There is no “other direction”. Tree shaking is the same as dead code elimination.
All tree shaking is dead code elimination, but not all dead code elimination is tree shaking (in webpack at least).
Tree shaking happens at the import level. If I say `import { abc } from 'some-lib'`, tree shaking won’t include any other objects some-lib may export.
Removing a branch that can never be true, like `if ('production' === 'production') { … } else { /* dead code */ }` is dead code elimination, but webpack wouldn’t consider that tree shaking.
Comments
TIL about tree shaking and that that's a thing in JS. Is that applicable to other languages? Why not Python?
It's common in javascript at least because you're delivering the code across the network, frequently, and at dev time, you're probably pulling in large libraries of components and frameworks that you may not use in their entirety. Since the load time is one of the core metrics used by SEO, and has shown to have a significant impact on conversion rates, it's worth the investment to remove code that's not being used.
I'm sure there are other places where it's applicable, but modern javascript and webapps have to be the quintessential use case.
Most other compiled languages do dead code elimination, which sounds similar but is a little different. Think of dead code elimination as removing code that doesn't change the output, while tree shaking instead includes code that could run.
To apply this to python is interesting - if you were creating a packaged version, I could see "compiling" the code to a separate package with only the required imports.
Those are both dead code elimination. Webpack even says:
I know that Microsoft is doing some kind of treeshaking in Blazor (basically a .NET runtime in WASM), since they do not want to ship a full .NET base library to the browser. Not JS related, but the problem is the same - you want to ship as little data as needed on websites that are dynamically loaded.
It could be, but I don't see it as too practical as dependencies are very likely quite transparent and don't themselves rely on many dependencies. But for JS?
s/for JS/on NPM/
There's no reason you can't write JS the same way you would write Java or C++. (And if you were writing "serious" applications in JS that weren't web apps before NodeJS came along, you did. Of course, you still can, too.)
It certainly is more the environment than the language itself, true.
Yes it is, it's just that Javascript has a stupid name for it. In other languages it is called dead code elimination.
They are not the same, and the term comes from Lisp in the early 90s, not JavaScript. Tree-shaking is actually "live code inclusion" - in other words, it approaches the problem from the other direction.
https://en.m.wikipedia.org/wiki/Tree_shaking
In Lisp this might work like this (did and still does work in some commercial Lisp systems):
For example a Lisp system may consist of starting a memory image from disk, which leads to a live running memory heap. The tree shaker then may break unused links in memory - either automatic or under programmer direction. The garbage collector then frees the unused memory. Lisp then dumps a new (typically smaller) image, which has unused code and data removed.
Such features appeared no later than end 1980s.
They both start at the entry block (or exported symbols if it's a lib) and traverse the program graph, keeping only live branches. There is no “other direction”. Tree shaking is the same as dead code elimination.
That's exactly how all dead code elimination works. How else would you do it?
I really don't understand the difference. Please enlighten me.
All tree shaking is dead code elimination, but not all dead code elimination is tree shaking (in webpack at least).
Tree shaking happens at the import level. If I say `import { abc } from 'some-lib'`, tree shaking won’t include any other objects some-lib may export.
Removing a branch that can never be true, like `if ('production' === 'production') { … } else { /* dead code */ }` is dead code elimination, but webpack wouldn’t consider that tree shaking.