It varies, but for most apps I'd wager it's library bloat, but in my experience doing iOS dev here are the common culprits:
- For games assets are a big issue. Some do not compress their assets, and unfortunately most image-authoring tools make it easy to output PNGs that are much larger than they can be. I think a lot of people by default assume bloat comes from images/icons/etc, but IMO this is a red herring for most non-game apps.
- Library bloat. Even simple apps pull in a large number of external dependencies, which contribute dramatically to app bloat. There's also a lot of code pulled in that replicate platform-provided functionality (see: the bajillions of layout libraries out there), which may be simpler to use than the stock Apple components, but add to your bundle size.
One of the common problems is that iOS open source dependencies are typically all-or-nothing - you end up pulling in a very large library even if you're only using a small slice of its functionality.
I think most disassemblies of iOS app bundles show that library bloat is typically a far larger problem than asset bloat.
In any case, I think the future will be something like Android Instant Apps - where apps are sliced up such that necessary bits can be downloaded on-demand. This gets users into apps faster, and saves space.
How so? The scenario being modeled here is a user who wants to use an app but does not already have it.
The status quo is that they must download a 150MB bundle before being able to proceed.
The proposed app slicing will allow them to download maybe 10-20MB before being able to proceed, with additional components (up to the 150MB total) downloaded on-demand.
If the user is on an intermittent or slow connection this is still a significant improvement over the status quo: the user gets into the app much more quickly.
Additionally, if the user only uses a small slice of the app's functionality (which is the 90% use case), additional downloading can be deferred until the user connects to wifi, at which point the rest of the app can be downloaded over a fast and reliable connection, all seamlessly without the user having to worry about it.
You're not allowed to include your own browser, and can only use the platform's web view, which is not duplicated on a per-app basis.
There are many culprits for app bloat, but using a browser is most certainly not one of them.