8000 refactor(Scalar.AspNetCore): compress embedded resource to reduce the Scalar.AspNetCore.dll size by stratosblue · Pull Request #5569 · scalar/scalar · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

refactor(Scalar.AspNetCore): compress embedded resource to reduce the Scalar.AspNetCore.dll size #5569

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

Merged
merged 8 commits into from stratosblue:reduce_aspnetcore_dll_size
May 13, 2025

Conversation

stratosblue
Copy link
Contributor
@stratosblue stratosblue commented May 5, 2025

Problem

Currently, the size of Scalar.AspNetCore.dll is about 3000KB. The reason why the file is so large is that the embedded resources are relatively large.

Solution

Using gzip to compress the StaticAssets/* at build time. And decompress it before response it.
This change can compress the size of theScalar.AspNetCore.dll from 3000KB to 1000KB.

Closes #5604

Checklist

I’ve gone through the following:

  • I’ve added an explanation why this change is needed.
  • I’ve added a changeset (pnpm changeset).
  • I’ve added tests for the regression or new feature.
  • I’ve updated the documentation.

Copy link
changeset-bot bot commented May 5, 2025

🦋 Changeset detected

Latest commit: ef23420

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@scalarapi/api-reference Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@hanspagel
Copy link
Member

OMG, so cool! Waiting for @xC0dex to review.

@xC0dex
Copy link
Collaborator
xC0dex commented May 5, 2025

Hey @stratosblue,

Thank you for the PR and for looking into reducing the size of dll!

We generally try to keep our dependencies to a minimum wherever possible. Additionally, runtime performance is our main priority for this package.
Out of curiosity, have you encountered any significant runtime issues or drawbacks specifically related to large .dll sizes? It would be great to hear if there’s a concrete scenario where this change makes a noticeable difference.

For reference, here are some benchmark results comparing the default and GZIP-decompressed stream approaches:

Method Mean Error StdDev Ratio RatioSD Allocated Alloc Ratio
DefaultReadStreamSync 638.9 ns 10.76 ns 9.54 ns 1.00 0.02 2.7 KB 1.00
GZipDecompressedReadStreamSync 6,993.4 ns 29.48 ns 26.13 ns 10.95 0.17 3.04 KB 1.12

As you can see, decompression adds quite a bit of unnecessary overhead.

Anyway, this PR brings our attention to the topic of compression in general, thanks!

@stratosblue
Copy link
Contributor Author

We generally try to keep our dependencies to a minimum wherever possible. Additionally, runtime performance is our main priority for this package. Out of curiosity, have you encountered any significant runtime issues or drawbacks specifically related to large .dll sizes? It would be great to hear if there’s a concrete scenario where this change makes a noticeable difference.

Hi @xC0dex ,

Thank you for your reply.

The starting point for this requirement is a single file publishing scenario, such as PublishSingleFile or PublishAot, the difference in file size of 2MB is a considerable size for single file distribution. For other distribution scenarios, the smaller the file is better too.

As for the performance issue, at the beginning of writing the code, I believed that the main usage scenario of this project was during development, and the related files included client-side caching processing, so performance may not need to be considered here. So for convenience, I directly performed GZip decompression every time I returned. If performance needs to be considered, there are some methods to alleviate it:

  • Cache decompressed content: This will only decompress on the first request, and there will be no performance impact in the future
  • Directly writing gzip data: When the client supports gzip (or the server enforces compression), the compressed content is directly written into the response, so there is no need to decompress and performance may be better. Currently, mainstream browsers support gzip. The code is like (of course, we still need to do some work to ensure compatibility):
    httpContext.Response.Headers.ContentEncoding = "gzip";
    
    return ifNoneMatch == etag ? Results.StatusCode(StatusCodes.Status304NotModified) : Results.Stream(resourceFile.CreateReadStream(), MediaTypeNames.Text.JavaScript, entityTag: new EntityTagHeaderValue(etag));

@hanspagel hanspagel marked this pull request as draft May 6, 2025 13:44
@stratosblue stratosblue force-pushed the reduce_aspnetcore_dll_size branch from bc1b193 to 5be62b6 Compare May 10, 2025 10:51
@stratosblue
Copy link
Contributor Author

Now when the client supports gzip, it will directly use gzip response without any additional decompression overhead (and this is the effect in most cases), and it will also have a smaller response size.
1
2

@stratosblue stratosblue marked this pull request as ready for review May 10, 2025 15:13
@xC0dex
Copy link
Collaborator
xC0dex commented May 11, 2025

Now when the client supports gzip, it will directly use gzip response without any additional decompression overhead

This is awesome!

I think for the compression itself we'll probably use the built-in gzip CLI feature of Ubuntu (our GitHub Runner). And we have to fully cover this with tests.

Have you noticed any performance improvement by using [MethodImpl(MethodImplOptions.AggressiveInlining)]?

@xC0dex
Copy link
Collaborator
xC0dex commented May 12, 2025

This is what I'd push to your PR later 3eda84d Once I fixed the tests I'd say your PR is ready! 🚀

@stratosblue
Copy link
Contributor Author

I think for the compression itself we'll probably use the built-in gzip CLI feature of Ubuntu (our GitHub Runner). And we have to fully cover this with tests.

Except for some additional operations that may be required to obtain compressed files when developing on Windows, everything else is fine

Have you noticed any performance improvement by using [MethodImpl(MethodImplOptions.AggressiveInlining)]?

It can eliminate some method call overhead (although there is not much improvement in the current scenario, there are also no side effects)

@hanspagel hanspagel changed the title refactor(Scalar.AspNetCore): Compress embedded resource to reduce the Scalar.AspNetCore.dll size refactor(Scalar.AspNetCore): compress embedded resource to reduce the Scalar.AspNetCore.dll size May 12, 2025
@xC0dex xC0dex requested a review from geoffgscott as a code owner May 12, 2025 13:02
@xC0dex xC0dex force-pushed the reduce_aspnetcore_dll_size branch from ba7fec7 to 497f220 Compare May 12, 2025 13:04
Copy link
Collaborator
@xC0dex xC0dex left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know I'm repeating myself, but this PR is awesome! Thanks! 🚀

I think later we may improve the JS setup to use vite and TS, so the way how to compress will probably change.

@hanspagel
Copy link
Member

Nice work!

@hanspagel hanspagel force-pushed the reduce_aspnetcore_dll_size branch from 92ff224 to ef23420 Compare May 13, 2025 11:25
@hanspagel hanspagel merged commit 85e2a85 into scalar:main May 13, 2025
26 checks passed
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

Successfully merging this pull request may close these issues.

Compression support
3 participants
0