-
Notifications
You must be signed in to change notification settings - Fork 28
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
Use of JSONEncoder or JSONDecoder massively increases final binary size #4171
Comments
You're welcome to extract JSONDecoder to a separate module, build one yourself in Swift, or use JavaScript interop to rely on the browser. Optimization is critical for WebAssembly. Using |
Thanks. I think this seems to have arraybuffer implications and it was the difference between my code working or not so I think documentation would have value. I agree my comment is subjective but I also think it's worth noting the impact somewhere. Honestly I'm happy if someone Googles arraybuffer swiftwasm and finds this issue in case it is helpful for others. I wish I had know to look out for JSON Codable in my module and now I know the impact. |
I'd also like to note that even with the optimized release version my code still didn't work so binary size alone isn't the problem here alone. |
JSONDecoder does work in a browser environment. If you find that it doesn't, please create a minimum reproducible project. |
It's not that it doesn't work, it's that the browser is highly constrained and including JSONDecoder will consume a huge portion of what fits, it seems. You mention that historically swift devs didn't care about binary size but that was for native mobile apps and it didn't affect the max number of other structures you could import. This is more impactful. It could be that I'm not explaining this well but my purpose is not to claim there's a bug but just to have a discussion about what devs should know coming into this project. There's a section in the book about unsupported types but maybe a section about types to look out for would be valuable too. In any case, I think my best course of action is just to make a PR against the documentation and it can be discussed from there what developers might find useful when first getting their feet wet. |
Do you see binary size increase with any Foundation type or just these two? |
Hi @MaxDesiatov , I realized all my code is open source so I've made an example that clearly demonstrates the issue: https://github.com/bitwit/swift-wasm-example If you swap between the 2 branches in the 'RedECS' package you'll see a massive change in binary size and an array buffer error in the browser when you run the branch that includes the lines with the JSONCoding work. I'm sorry also if the tone of this issue initially comes off as a trashing of the project, as my intention is the opposite. I'd love to help contribute and help new developers get through the gotchas. I don't actually believe this is a bug in SwiftWasm either, but just a limitation of the browsers right now, so it is important for Swift devs to understand those differences coming in. Lastly just want to say this project BLEW my expectations away and I'm elated with the results so far. I can't believe my random dungeon generator code is working in a browser and all I had to do was hook in to canvas. AMAZING 🎉 https://twitter.com/kylnew/status/1486556895653646343 |
Great, thanks for your feedback! If you use any Foundation other than |
Its after I use the JSONDecoder and JSONEcoder, from what I saw. Import alone didn't seem to trigger it. main diff here: RedECSEngine/RedECS@13e1a2d |
Yes, import alone does not trigger linking, that's why I'm asking about using specific types. Is the binary size increased when you start using |
I will try to do some more investigations later too and see if there are other structures that do this, such as Date. when I tried Date it wasn't working at all. |
I'll reopen the issue in the meantime until we reach a consensus how our documentation should be updated to clarify the binary size concerns. |
Okay so this was an interesting investigation:
So from this I have a few more thoughts (under an assumption that my questions in point no. 3 doesn't reframe the conversation):
So when it comes to documentation I was wondering if maybe there is a way to target both app developers and package maintainers who want their code to be SwiftWasm friendly. Understanding the Foundation overhead a little bit better might helps folks weigh the pros and cons of if they need to import Foundation, and organize their packages accordingly. Getting into the mindset of Wasm binary constraints like this is a new concept to me compared to mobile and linux. So worth the costs though, I still can't believe I see my modules working in the browser! |
@bitwit note that we ran into a related issue, whereby Foundation was implicitly being imported: https://forums.swift.org/t/how-to-disable-implicit-foundation-imports/59678 Due to that bug, using any API from Foundation, even if you don't Regarding JSON, You might have more luck using XJSONDecoder from this package. I haven't tried it myself, but doing things that way should mean you only get JSON Decoding and not the entirety of Foundation. FWIW, we removed Foundation from our stack and reduced our binary size on Wasm and Android by 70-90% |
@ephemer thanks for the reference. I love to look out for non-foundation-dependent swift packages I managed to remove foundation and it was a huge difference in what was possible in the browser. I didn't personally encounter issues with JavaScript kit (though I'm not up to date on latest versions) |
Example Code:
Result
Without optimization, browser reports wasm file size of ~27MB, and ~11MB without any code
Proposed solution:
Update wasm book: https://book.swiftwasm.org/getting-started/porting.html
The
Swift Foundation and Dispatch
should probably include JSONEncoder/Decoder with some sort of flag that it's not worth using even if it compiles.If this is a valuable improvement, I'd be happy to make that PR myself. I think it could help prevent other developers from going down the same rabbit hole
The text was updated successfully, but these errors were encountered: