Skip to content
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

Reduce binary sizes of yaegicore apps #1473

Open
kkoreilly opened this issue Feb 3, 2025 · 5 comments
Open

Reduce binary sizes of yaegicore apps #1473

kkoreilly opened this issue Feb 3, 2025 · 5 comments
Assignees
Labels
approved This feature request will be implemented enhancement A new feature request
Milestone

Comments

@kkoreilly
Copy link
Member

Describe the feature

Apps that import yaegicore, such as the documentation website, end up including every symbol in a lot of packages (especially icons), in addition to the base size of yaegi itself. That substantially increases the binary size, impacting load times on web. We should use https://github.com/Zxilly/go-size-analyzer to figure out what packages are contributing the most and what we can cut. If we could figure out some way to include fewer icons in yaegicore, that would help a lot.

Relevant code

@kkoreilly kkoreilly added approved This feature request will be implemented enhancement A new feature request labels Feb 3, 2025
@kkoreilly kkoreilly added this to the v0.4 milestone Feb 3, 2025
@kkoreilly kkoreilly self-assigned this Feb 3, 2025
@AnyCPU
Copy link
Contributor

AnyCPU commented Feb 3, 2025

@kkoreilly just an idea in the air: put every icon into dedicated package :-D

@kkoreilly
Copy link
Member Author

@AnyCPU That is kind of what we did in #1003, as the icons are now different independent variables, which are only compiled in if needed. The main issue is that yaegicore includes all of the icons, thereby rendering that pointless. We could easily have it not include all of the icons, but then we would need to manually specify some subset of icons for that. It is possible, but it might be difficult to figure out what icons to include without leaving too much out. It is certainly possible though; that is likely what we will end up doing at some point.

If you want to contribute, you could find all of the icons we use in the docs, plus any other frequently used icons in core, and make a slice of pointers to them in yaegicore/symbols and then run a for loop to add them all to the symbols map. That would replace the existing icons file there, which would be deleted (and icons would be removed from the make file). This isn't a super urgent priority, but it would certainly be good to do. I will get around to it at some point otherwise.

@AnyCPU
Copy link
Contributor

AnyCPU commented Feb 4, 2025

@kkoreilly it sounds like a lot of friction and high focus are required every time if something changes in that case.

what if we update a code generation for icons and it will look like following?:

  • icon naming stays the same;
  • still use Go's embedding;
  • pack icons and embed them as standard zip file;
  • auto generate an init function for the icons package;
  • the init function loads icon content at runtime.

in theory it will increase memory use and slow down a little bit an app on start up, but it might decrease binary size:

  • a svg dir has 16.8 mb;
  • zip file (std macOS settings) has 1.9 mb.

@AnyCPU
Copy link
Contributor

AnyCPU commented Feb 4, 2025

@kkoreilly i did some kind of research and found that svg icons take not so much space being embedded ~ 1.5 mb,
they take more on disk because of file system settings.

i took a look at a content/examples/basic example.

i have following numbers:

build options size in mb
as is 58.2
-s -w 42.6
-s -w w/o the icons embedded 41.1
-s -w w/o the icons embedded + strip 40.5
UPX does not work on macOS

disabling "debug" mode or just using "-s -w" options are pretty much enough for good result.

i guess, using other options might be not so good idea because they are able to remove more info than expected from binary.

also i should admit that the yaegi is not fat, but wide, just because of its nature.

i have nothing more on this.

@kkoreilly
Copy link
Member Author

@AnyCPU Yes, the icons only take a couple of megabytes in the actual app. The relevant metric here is the size of the compressed web wasm file, as that is the most critical for binary size and load time considerations.

Removing the yaegicore icons reduces compressed web binary size by 4.65%, which is a substantial but not massive amount. For reference, our ongoing changes in #1457 should allow us to stop embedding fonts on web, which will decrease the compressed web binary size of the docs by 6.55%. Together, those changes would reduce binary sizes by over 10%, which is pretty good. Critically, the size of icons and fonts will not get smaller when we switch to GopherJS (#974), so once that is viable, the relative impact of the removed icons and fonts would be even bigger.

As such, I think we want to pursue icon reduction somehow. I agree it wouldn't be great to have only a manual subset of icons in yaegicore, but it might be worth it (I don't think rare icons are likely to be a frequent yaegicore use case).

Compressing the icon files would not help on web (which is already fully compressed in deployment), it would add delays on startup as you noted, and it would prevent our current automatic inclusion of only the icons you use (for non yaegicore apps). Therefore, I think my proposed solution might be the best option, although I would be glad to consider any further ideas you have.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved This feature request will be implemented enhancement A new feature request
Projects
None yet
Development

No branches or pull requests

2 participants