-
-
Notifications
You must be signed in to change notification settings - Fork 35.5k
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
CI: Report tree-shaking size in PR #25615
Conversation
Is it the full build size or just the test tree-shaken build size? I think it would be great to report both. And maybe we can report brotlied size instead or as addition to the gzipped size? I think brotli is starting to be used in various places so maybe it can reflect better the "true" size that user should download on network. |
Yeah makes sense, I personally don't want to know the full library size but I see how it could be useful for some people.
Ah I just copied what vite/create-react-app do, let's leave gzip since it's the most common one. It's on the user to decide if he wants to use brotli compression and reduce the bundle even more. |
This is awesome. Let's update the |
Brotli will be smaller. GZIP beats Brotli on speed. It's up to the web server config and negotiation with each users browser if it's even used. Developers don't have a choice. I hope people remember to optimise for accuracy and size, not how compressible text might be. |
I'll get started on the |
Not sure what you mean, that command is working fine already. Anyway, not related to this PR. |
The way it's setup it does not follow the builds, excludes some code, which reduces the accuracy of the report in this PR. |
It reads from the |
bc8dfae
to
5a8bf6c
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The difference is subtle, boring, but important. Here's a summary of what I'm pointing out.
The first report: bundle size.
You want to report on module bundle size and impacts that would be shipped. People can plainly see its 1.1 MB looking at the built file. Adding a terser step to minify this to be able to report 600 KB will confuse people. Reporting like this doesn't match up to any shipped file, it does not indicate the build size of any use case, it's an ESM build which shouldn't be minified but has, the current minimised file is based on UMD.
The final bundler is responsible for minification for good reasons. Chains of minification produce worse results on the final product, etc. It is very helpful when you introduce a new feature that adds 20 KB then are able to point out that it will not impact build sizes with the report that follows. We want to see that 20 KB here, not see it after tree-shake.
The second report: bundle size after tree shaking
This should combine the module build and module test file (not the source based test file) in a build, minify, tree-shake. Everything a real application consumer would do, then report on that. That looks like what it is still doing after this PR.
We don't want to minify the module bundle, then build it with the module test rig, minify again, and tree-shake. The minification from the first transformation can hide minifications from the final pass. We want it to all happen in a specific context of the test rig to get results that match what will happen in when we use it in our applications.
This PR doesn't modify the test rigs so its not creating any issues. The module test rig is still pointing to the build/three.module.js file because it's using the 'import' statement. I'm writing this out for clarity.
What I wanted to also point out is the current treeshake test rig has a few issues. It is too minimal to be practical. It's in a state that answers a very specific question from whoever was working on it last. It is not setup to be a general indication. I think this report and PR will have the most value with better data.
Not sure what you're trying to explain (I got the terser part), but it doesn't look related to this PR. Let's move the conversation elsewhere. |
Pretty easy to see its related to this PR. I am pointing out the lines in this PR where you are inventing a build type that will never ship and reporting on it. I'm trying to capture that the test rig this report relies on is not high quality. I want people to understand this PR is good. Any issues in the data are related to the quality of the test rig, not this PR. We just need a small modification on the first report. |
Answered in #25615 (comment), ultimately it's @mrdoob decision. |
Work with me here, I'm trying to help. You have a great setup pointing at the wrong thing. You haven't answered anything in that comment. You repeated something that that applies to applications not ESM libraries. It's not done by the three.js builds or any modern tools on ESM library projects for good reasons. I want to see your work merged as soon as possible so I am quickly pointing out any issue I see. You want to report on the minified build, call it bundle size, but it does not represent the minified build or ESM bundle size. What choice are you giving people ? This special build type you've created for "bundle size" reporting will never ship and has nothing to do with the tree-shaking test rig. Find a different home for it ? If it has a special meaning in some other context, I'm good with that. Maybe it just needs a different label ? It doesn't describe what the bundle size will be or help someone understand what the impacts of a change will be on minification. It's 200 KB out. I'm hoping for something that will show 5 KB differences accurately. |
test/treeshake/utils/format-size.js
Outdated
@@ -0,0 +1,7 @@ | |||
// used in report-size.yml | |||
import prettyBytes from 'pretty-bytes'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe just this function, instead of a new dependency?
export function formatBytes(bytes: number, decimals = 2): string {
if (bytes === 0) return '0 Bytes';
const k = 1000;
const dm = decimals < 0 ? 0 : decimals;
const sizes = ['Bytes', 'KB', 'MB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Less dependencies is good 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the function @donmccurdy! Updated.
@marcofugaro I agree with reporting the minified and gzipped ESM size, but I don't think we can put a large header into PRs that says "Bundle size after tree-shaking" like this. I expect it will mislead people into thinking we can predict average tree-shaking results. Is there another way to format this? For example, creating a tree-shaken build that just does |
@donmccurdy what is a pre-minified ESM size supposed to be or mean ? Why does no library ship such a thing ? What is it supposed to represent if it will never be a shipped build ? We are not predicting the average tree-shaking results. This is a sanity check against the build size of a minimum viable application using the library. The problem with that suggestion is it's not designed to fail when there is an issue. It suffers from the same problem that it does not have any meaning and does not inform reviewers of the impacts of merging a change (or if some investigation / refinement is required. #25595 is not the best example but it is what this sort of thing should catch. |
@epreston I expect you've seen badges like this on GitHub repository READMEs before: We are communicating the expected weight in the end-user's bundle, not size on npm's servers. That means reporting gzipped minified size, regardless of whether we publish minified code to npm.
I do understand that, but the message added to PRs by this change suggests otherwise, and needs to be rephrased.
That's precisely what my suggestion is designed to do. If it doesn't do so, then I'm open to alternatives. My main point is that the comment shown in PRs should communicate to the reader that "tree shaking did not break", but it currently communicates something else instead. |
There can be value in both of these reports.
|
I would prefer not to report a minimum viable tree-shake size on every PR, but to simply report that tree-shaking has or has not broken. Minified, gzipped size of the full ESM bundle is OK with me too. If someone can explain to me why the "minimum viable tree-shake" is a particularly meaningful subset of the library I am open to reconsidering that! |
@donmccurdy I have seen those. Usually they represent a number that can be associated to a shipped build product. I'm trying to point out that this is a number out of thin air. You are highlighting something that makes sense in the context of CJS or UMD when minified. It is not the same in ESM. Users will see a report of 600 kB, builds cost will actually be 418 kB, users linking via CDN will download 1.1 MB. |
@epreston it is not a good use of our time to argue about this. Reporting minified and gzipped bundle size is a widely accepted way to communicate the approximate size of a JavaScript library, whether it is imported from a CJS or ESM entrypoint. |
No trying to argue, I'm trying to get you what you actually want and avoid what looks a little dishonest (a report only build minification) from the outside. You nailed the issue. Report on the minified CJS build product that actually ships if you need to report a minified size. It will highlight important issues and has practical meaning. Each of these examples you are providing are reporting on something real. None of them are creating something inaccessible, only for reporting purposes, like this is. |
What is it ? It is an end-to-end test on build formatting and code structure. It should remain constant or slowly reduce over time. Marked increases to this size should be considered very carefully. What's the value ? Code can be correct and functional but have a usage penalty for the consumer of the library. Recently 10 lines of a change increased minimum build size by 4x. (full disclosure: I don't think the claims are fair but it still needs to be addressed because it is a size-effect in a library marked side-effect free). Why a minimum viable application ? I'm going to use the example above to explain. The build product they were creating is dubious at best with no practical usage. I can cherry pick 2 classes and claim 10x increases. I can also pick two others and show a 3x reduction. Instead of importing a constant or cherry picking classes, grab something that is meaningful and diverse enough that it can not be disputed. It should have enough room to show both improvements and regressions. Who does it benefit or inform ? When someone is fairly comparing libraries with their spinning cube test, this is the number that they will use for comparison. It's the inescapable cost. It's perceptions, expectations, and a quality indicator. It's an awareness that will benefit this project greatly. Authors of changes may consider other strategies. Reviews will understand the impacts to all users. |
What I mean is, which classes from three.js does the "minimum viable tree-shake" include, and why? If this concept will mentioned under a bold header in every new PR, it should be clear to readers what we mean by it. If it's the size of a spinning cube demo, then let's say that. We expect and recommend that users choose ESM. Please, let's use minified and gzipped ESM for reporting the size of the full library. That minified ESM isn't what's hosted on NPM does not matter — nothing on NPM is gzipped, either. We're talking past each other on this issue, and wasting time that could be spent productively. |
It's the smallest practical use case that still justifies using the library. For me, "minimum viable tree-shake" is rendering the cube without animation (no spin, its reasonable to expect to pay for animation like all other alternatives) from the example on the front page of the project. Yes, cube demo. I'm looking forward to the reality check. Right now, the value proposition is not strong unless the consumer is building something moderately substantial. |
I guess this is the list of imported classes: WebGLRenderer, PerspectiveCamera, and Scene https://github.com/mrdoob/three.js/blob/dev/test/treeshake/index.js @marcofugaro perhaps under that CI comment header we just add the line:
|
An opinion I can accept, pretending its equivalent to the those other examples will cause issues. I've done my best to warn people off doing special "reporting only" modifications to fudge numbers. |
We are not fudging numbers. This is exactly how third-party measurement tools like bundlephobia are going to report. They take the ESM entrypoint, minify and gzip it, then report the size. The goal is to measure the library in a standard way, so comparisons between packages are apples-to-apples. |
Worth looking at that closer if that is the goal. "bundlephobia" the beta site that has an error building three.js might not be the best example. It is certainly not standard or meaningful. |
Ugh... What happened here... |
Okay, I think I got the gist of it... @epreston you said this:
Pointing out issues is a thing. Trying so hard to convince the contributor is another thing. Your current approach achieves two things:
We really appreciate your willingness to help but let me suggest a different approach:
If we disagree with the change we can discuss it in your own PR, but that way you don't block someone else's PR. ❤ |
Thanks for diffusing the situation @mrdoob ❤️
Done! Thanks for the suggestion @donmccurdy. I agree it was not that clear what "size after tree-shaking" meant. Although yes as you said this still doesn't report if the WebGLRenderer itself is tree-shakeable, even if this situation is rare, it's still the case for some users (see #25595). But I can do this in a subsequent PR, we can merge this one if we want to test the feature! |
@marcofugaro I'm good with that, thanks! I'll wait and see how the PR comment looks "in action" and then try a PR for the message if it still seems like that would be helpful. |
@donmccurdy you can see it in action in #25599 |
Related issue: #25470 (comment)
Description
If a PR edits something inside the
src/
folder, this comment will appear on the PR:The comment will later be updated after changes in the PR.
/cc @LeviPesin @epreston