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

Large filesize (1MB of raw WASM) #269

Open
nedtwigg opened this issue Mar 29, 2024 · 3 comments
Open

Large filesize (1MB of raw WASM) #269

nedtwigg opened this issue Mar 29, 2024 · 3 comments

Comments

@nedtwigg
Copy link

Has any effort gone into filesize? Maybe there are some low hanging fruit?

So there's no sudden jump, seems like it's always been very large.

@nedtwigg
Copy link
Author

nedtwigg commented Apr 3, 2024

Making this change

-wasm-opt = ['-O4', '--dce']
+wasm-opt = ['-g']

takes the filesize from 1.1MB to 1.4MB. I then ran twiggy top -n 100 pkg/rapier_wasm2d_bg.wasm and I get:

        176912 ┊    13.27% ┊ "function names" subsection
         58362 ┊     4.38% ┊ data[0]
         32104 ┊     2.41% ┊ bincode::internal::serialize_into::h9c67780eb59bd61a
         22347 ┊     1.68% ┊ <rapier_wasm2d::pipeline::serialization_pipeline::_::<impl serde::de::Deserialize for rapier_wasm2d::pipeline::serialization_pipeline::DeserializableWorld>::deserialize::__Visitor as serde::de::Visitor>::visit_seq::hcb3a1a05d383bd85
         21225 ┊     1.59% ┊ rapier2d::dynamics::solver::island_solver::IslandSolver::init_and_solve::h6d40cceb24c47b4a
         19003 ┊     1.43% ┊ rapier2d::pipeline::physics_pipeline::PhysicsPipeline::step::he63f937bba9aee1c
         17815 ┊     1.34% ┊ rapier2d::dynamics::solver::contact_constraint::contact_constraints_set::<impl rapier2d::dynamics::solver::solver_constraints_set::SolverConstraintsSet<rapier2d::dynamics::solver::contact_constraint::contact_constraints_set::ContactConstraintTypes>>::init::hd775727cb8322408
         16811 ┊     1.26% ┊ <rapier2d::geometry::contact_pair::_::<impl serde::de::Deserialize for rapier2d::geometry::contact_pair::ContactPair>::deserialize::__Visitor as serde::de::Visitor>::visit_seq::h553a4a284606788f
         14515 ┊     1.09% ┊ <parry2d::query::default_query_dispatcher::DefaultQueryDispatcher as parry2d::query::query_dispatcher::PersistentQueryDispatcher<ManifoldData,ContactData>>::contact_manifold_convex_convex::hd28447885c2a09f0
         13906 ┊     1.04% ┊ rapier2d::dynamics::ccd::ccd_solver::CCDSolver::predict_impacts_at_next_positions::hca3ac1bd5fe821f5
         13040 ┊     0.98% ┊ <rapier2d::dynamics::joint::multibody_joint::multibody_joint_set::_::<impl serde::de::Deserialize for rapier2d::dynamics::joint::multibody_joint::multibody_joint_set::MultibodyJointSet>::deserialize::__Visitor as serde::de::Visitor>::visit_seq::h47391b3cb5ed43ea
         11654 ┊     0.87% ┊ serde::de::SeqAccess::next_element::hd48afb38c8a8cffd
          9936 ┊     0.75% ┊ rapier2d::geometry::broad_phase_multi_sap::broad_phase::BroadPhase::update::h10e5444a295b9905
          9109 ┊     0.68% ┊ rapier2d::pipeline::query_pipeline::QueryPipeline::update_incremental::hf3a43aa5b73ce754
          9063 ┊     0.68% ┊ rapier2d::dynamics::joint::multibody_joint::multibody::Multibody::update_dynamics::h867560f561f919f6
          8264 ┊     0.62% ┊ parry2d::query::point::point_support_map::local_point_projection_on_support_map::h27fc9cb5041f9927
          7725 ┊     0.58% ┊ rapier_wasm2d::pipeline::debug_render_pipeline::RawDebugRenderPipeline::render::h13b3761db95291bb
          7678 ┊     0.58% ┊ parry2d::query::point::point_support_map::local_point_projection_on_support_map::h3e538169760cd486
          7388 ┊     0.55% ┊ parry2d::query::point::point_support_map::local_point_projection_on_support_map::h96f3cb29f9cf5247
          7355 ┊     0.55% ┊ rapier2d::geometry::narrow_phase::NarrowPhase::handle_user_changes::h4f9581887bd14a40
          7339 ┊     0.55% ┊ parry2d::query::point::point_support_map::local_point_projection_on_support_map::hb0b85d522fe6df78
          7240 ┊     0.54% ┊ rapier2d::dynamics::joint::multibody_joint::multibody_joint_set::MultibodyJointSet::remove::h91b01baef05578a9
          7109 ┊     0.53% ┊ parry2d::query::contact::contact_support_map_support_map::contact_support_map_support_map::hb339cc4d5ab8dec0
          6638 ┊     0.50% ┊ rapier2d::pipeline::query_pipeline::QueryPipeline::cast_shape::ha3a6f21fee0b1067
          6092 ┊     0.46% ┊ core::num::flt2dec::strategy::dragon::format_shortest::h26c9497c8755513a
          5830 ┊     0.44% ┊ rapier2d::dynamics::solver::contact_constraint::generic_two_body_constraint::GenericTwoBodyConstraint::solve::h155b3405f325ab00
          5799 ┊     0.44% ┊ <parry2d::shape::shared_shape::SharedShape as serde::ser::Serialize>::serialize::h43c4482166ea26a4
          5697 ┊     0.43% ┊ parry2d::query::nonlinear_time_of_impact::nonlinear_time_of_impact_composite_shape_shape::nonlinear_time_of_impact_composite_shape_shape::h175a53e5a295a82e
          5239 ┊     0.39% ┊ rapier2d::dynamics::joint::multibody_joint::multibody::Multibody::forward_kinematics::hc39c6254a5235b47
          5215 ┊     0.39% ┊ serde::de::SeqAccess::next_element::hdc34583d46f0de47
          5130 ┊     0.38% ┊ core::num::flt2dec::strategy::dragon::format_exact::he7b18f9a1bb660cf
          4932 ┊     0.37% ┊ parry2d::partitioning::qbvh::update::<impl parry2d::partitioning::qbvh::qbvh::GenericQbvh<LeafData,parry2d::utils::array::DefaultStorage>>::do_recurse_rebalance::h595cd9e55650cc8f
          4823 ┊     0.36% ┊ parry2d::transformation::convex_hull2::convex_hull2_idx::hd595ea64a9483d04
          4750 ┊     0.36% ┊ rapier2d::dynamics::solver::joint_constraint::joint_velocity_constraint::JointOneBodyConstraint<f32,1_usize>::lock_axes::hdcf3c6d776a249ab
          4668 ┊     0.35% ┊ parry2d::query::time_of_impact::time_of_impact_composite_shape_shape::time_of_impact_composite_shape_shape::h27925e4858d73d91
          4607 ┊     0.35% ┊ dlmalloc::dlmalloc::Dlmalloc<A>::malloc::hdb36f5487b24f5cc
          4591 ┊     0.34% ┊ rapier_wasm2d::pipeline::serialization_pipeline::RawSerializationPipeline::serializeAll::h39fdc638ffec94ce
          4513 ┊     0.34% ┊ compiler_builtins::math::libm::rem_pio2_large::rem_pio2_large::h8923d9b88a8ae82e
          4494 ┊     0.34% ┊ parry2d::shape::trimesh::GenericTriMesh<parry2d::utils::array::DefaultStorage>::compute_topology::h7befaa830565d721
          4480 ┊     0.34% ┊ rapier2d::geometry::narrow_phase::NarrowPhase::compute_contacts::heafebf9aa1522893
          4471 ┊     0.34% ┊ <parry2d::query::default_query_dispatcher::DefaultQueryDispatcher as parry2d::query::query_dispatcher::PersistentQueryDispatcher<ManifoldData,ContactData>>::contact_manifolds::h250a0e05a500d88f
          4453 ┊     0.33% ┊ parry2d::query::point::point_composite_shape::<impl parry2d::query::point::point_query::PointQuery for parry2d::shape::trimesh::GenericTriMesh<Storage>>::project_local_point_and_get_feature::hd3374371e8a1caf6
          4267 ┊     0.32% ┊ <rapier2d::pipeline::event_handler::ChannelEventCollector as rapier2d::pipeline::event_handler::EventHandler>::handle_contact_force_event::h4edbb4061c3139ce
          4216 ┊     0.32% ┊ parry2d::query::point::point_composite_shape::<impl parry2d::query::point::point_query::PointQueryWithLocation for parry2d::shape::trimesh::GenericTriMesh<Storage>>::project_local_point_and_get_location_with_max_dist::hc9cc3dc7eb3869b2
          4009 ┊     0.30% ┊ parry2d::query::closest_points::closest_points_composite_shape_shape::closest_points_composite_shape_shape::h1cac593bba680fa4
          3997 ┊     0.30% ┊ parry2d::query::contact_manifolds::contact_manifolds_heightfield_composite_shape::contact_manifolds_heightfield_composite_shape::h869c40f23450748a
          3946 ┊     0.30% ┊ rapier2d::dynamics::solver::joint_constraint::joint_velocity_constraint::JointTwoBodyConstraint<f32,1_usize>::lock_axes::h99dbf329b5e4b39c
          3939 ┊     0.30% ┊ serde::de::SeqAccess::next_element::h3fd691a32b1bc337
          3914 ┊     0.29% ┊ libm::math::rem_pio2_large::rem_pio2_large::h1355fe0047b31edb
          3860 ┊     0.29% ┊ parry2d::query::contact_manifolds::contact_manifolds_trimesh_shape::contact_manifolds_trimesh_shape::h390716fbfaf5eb3a
          3817 ┊     0.29% ┊ rapier2d::pipeline::query_pipeline::QueryPipeline::project_point_and_get_feature::h66f317b0a5f15735
          3610 ┊     0.27% ┊ parry2d::query::ray::ray_composite_shape::<impl parry2d::query::ray::ray::RayCast for parry2d::shape::trimesh::GenericTriMesh<parry2d::utils::array::DefaultStorage>>::cast_local_ray_and_get_normal::hea516715909c253a
          3567 ┊     0.27% ┊ <rapier2d::pipeline::event_handler::ChannelEventCollector as rapier2d::pipeline::event_handler::EventHandler>::handle_collision_event::h1deb023466e61444
          3509 ┊     0.26% ┊ rapier2d::control::character_controller::KinematicCharacterController::detect_grounded_status_and_apply_friction::h177b31eff3493fe2
          3418 ┊     0.26% ┊ rapier2d::dynamics::ccd::ccd_solver::CCDSolver::find_first_impact::h70e453dd82bb6437
          3412 ┊     0.26% ┊ rapier2d::dynamics::solver::contact_constraint::generic_one_body_constraint::GenericOneBodyConstraint::solve::h642749a4714ae204
          3408 ┊     0.26% ┊ parry2d::query::ray::ray_composite_shape::<impl parry2d::query::ray::ray::RayCast for parry2d::shape::polyline::Polyline>::cast_local_ray_and_get_normal::h016c330d45d142f8
          3407 ┊     0.26% ┊ rapier2d::pipeline::query_pipeline::QueryPipeline::cast_ray::hb79c293bb011ea32
          3395 ┊     0.25% ┊ parry2d::query::point::point_composite_shape::<impl parry2d::query::point::point_query::PointQuery for parry2d::shape::compound::Compound>::project_local_point::h59dfb6fc21c74a47
          3387 ┊     0.25% ┊ rapier2d::pipeline::query_pipeline::QueryPipeline::intersection_with_shape::h61567a2b68adda42
          3376 ┊     0.25% ┊ rapier2d::geometry::broad_phase_multi_sap::sap_axis::SAPAxis::batch_insert::h4ce26563fa2d63e5
          3335 ┊     0.25% ┊ parry2d::query::contact_manifolds::contact_manifolds_heightfield_shape::contact_manifolds_heightfield_shape::hfab5690a30a20d74
          3321 ┊     0.25% ┊ parry2d::query::ray::ray_composite_shape::<impl parry2d::query::ray::ray::RayCast for parry2d::shape::compound::Compound>::cast_local_ray_and_get_normal::hcb86f735794828ae
          3297 ┊     0.25% ┊ parry2d::query::distance::distance_composite_shape_shape::distance_composite_shape_shape::h804a8bb6a0dab34c
          3243 ┊     0.24% ┊ rapier2d::pipeline::query_pipeline::QueryPipeline::update_with_mode::h3b1e680e0be966b4
          3239 ┊     0.24% ┊ rapier2d::pipeline::query_pipeline::QueryPipeline::project_point::hd76e0da043a3b215
          3207 ┊     0.24% ┊ rapier_wasm2d::dynamics::multibody_joint_set::RawMultibodyJointSet::createJoint::h5aa2f9260d256796
          3185 ┊     0.24% ┊ parry2d::partitioning::qbvh::build::<impl parry2d::partitioning::qbvh::qbvh::GenericQbvh<LeafData,parry2d::utils::array::DefaultStorage>>::do_recurse_build_generic::h93202e2d3c297e18
          3180 ┊     0.24% ┊ rapier2d::control::character_controller::KinematicCharacterController::solve_character_collision_impulses::h8b4231367b06dc19
          3170 ┊     0.24% ┊ <parry2d::query::default_query_dispatcher::DefaultQueryDispatcher as parry2d::query::query_dispatcher::QueryDispatcher>::distance::hf9225cd0bff61f9a
          3156 ┊     0.24% ┊ rapier2d::dynamics::solver::joint_constraint::joint_generic_constraint::JointGenericOneBodyConstraint::lock_axes::h6c10f108c129f74c
          3144 ┊     0.24% ┊ parry2d::shape::polyline::Polyline::new::hd35f81efeb394064
          3143 ┊     0.24% ┊ parry2d::query::contact_manifolds::contact_manifolds_composite_shape_shape::contact_manifolds_composite_shape_shape::h1864c24cfa265ba3
          3129 ┊     0.23% ┊ rapier2d::dynamics::solver::joint_constraint::joint_generic_constraint::JointGenericTwoBodyConstraint::solve::h64f4f4787e8cbba9
          3115 ┊     0.23% ┊ rapier2d::pipeline::query_pipeline::QueryPipeline::cast_ray_and_get_normal::h32fc8e1428b200c9
          3094 ┊     0.23% ┊ rapier2d::dynamics::joint::impulse_joint::impulse_joint_set::ImpulseJointSet::remove_joints_attached_to_rigid_body::h89bae8b9232a76d8
          3085 ┊     0.23% ┊ parry2d::query::ray::ray_composite_shape::<impl parry2d::query::ray::ray::RayCast for parry2d::shape::trimesh::GenericTriMesh<parry2d::utils::array::DefaultStorage>>::cast_local_ray::hc9565955fe56ce7d
          3066 ┊     0.23% ┊ parry2d::query::point::point_composite_shape::<impl parry2d::query::point::point_query::PointQueryWithLocation for parry2d::shape::polyline::Polyline>::project_local_point_and_get_location::h99b353ac7251ad9f
          3046 ┊     0.23% ┊ serde::de::SeqAccess::next_element::h31858f5ca3e0df8e
          2975 ┊     0.22% ┊ parry2d::query::point::point_composite_shape::<impl parry2d::query::point::point_query::PointQuery for parry2d::shape::polyline::Polyline>::project_local_point_and_get_feature::heeb9e21397c5d9ab
          2947 ┊     0.22% ┊ serde::de::SeqAccess::next_element::h6d34eb6525f36641
          2945 ┊     0.22% ┊ parry2d::query::ray::ray_composite_shape::<impl parry2d::query::ray::ray::RayCast for parry2d::shape::polyline::Polyline>::cast_local_ray::h1e11d09a850e8966
          2913 ┊     0.22% ┊ rapier2d::geometry::broad_phase_multi_sap::sap_layer::SAPLayer::complete_removals::h24db480d6b9f69d7
          2901 ┊     0.22% ┊ rapier2d::dynamics::solver::joint_constraint::joint_generic_constraint::JointGenericTwoBodyConstraint::lock_axes::h61a9e4ab91a70c80
          2852 ┊     0.21% ┊ parry2d::query::ray::ray_composite_shape::<impl parry2d::query::ray::ray::RayCast for parry2d::shape::compound::Compound>::cast_local_ray::h7a6384104f53a395
          2804 ┊     0.21% ┊ <parry2d::query::default_query_dispatcher::DefaultQueryDispatcher as parry2d::query::query_dispatcher::QueryDispatcher>::intersection_test::hb98f20412e22d5c0
          2797 ┊     0.21% ┊ rapier_wasm2d::geometry::collider_set::RawColliderSet::do_create_collider::h869f86bcacdb9422
          2779 ┊     0.21% ┊ crossbeam_channel::channel::Receiver<T>::try_recv::h37a9a9e8e289a9a3
          2673 ┊     0.20% ┊ rapier_wasm2d::pipeline::event_queue::RawEventQueue::drainContactForceEvents::he7d837b80757e360
          2651 ┊     0.20% ┊ rapier2d::dynamics::joint::multibody_joint::multibody::Multibody::update_acceleration::h3257f85dd54fbd5a
          2579 ┊     0.19% ┊ rapier2d::pipeline::user_changes::handle_user_changes_to_rigid_bodies::h1d016521f689d3d7
          2565 ┊     0.19% ┊ parry2d::shape::trimesh::GenericTriMesh<parry2d::utils::array::DefaultStorage>::rebuild_qbvh::h5b9a3c9638fe2f84
          2492 ┊     0.19% ┊ parry2d::shape::trimesh::GenericTriMesh<parry2d::utils::array::DefaultStorage>::set_flags::h7b9fda1f1b5775be
          2446 ┊     0.18% ┊ rapier_wasm2d::pipeline::query_pipeline::RawQueryPipeline::intersectionsWithShape::{{closure}}::h1d4978e6014a7d21
          2440 ┊     0.18% ┊ hashbrown::raw::RawTable<T,A>::reserve_rehash::h75dd7e9f148ef85c
          2407 ┊     0.18% ┊ parry2d::query::nonlinear_time_of_impact::nonlinear_time_of_impact_support_map_support_map::compute_toi::hcbd6e7e49fd62fb5
          2401 ┊     0.18% ┊ rapier_wasm2d::dynamics::impulse_joint_set::RawImpulseJointSet::createJoint::he529caa09550fa63
          2367 ┊     0.18% ┊ <parry2d::query::default_query_dispatcher::DefaultQueryDispatcher as parry2d::query::query_dispatcher::QueryDispatcher>::closest_points::hd08705905d76b0cf
          2356 ┊     0.18% ┊ rapier2d::geometry::narrow_phase::NarrowPhase::add_pair::h7673dd2f0ec4aba2
          2355 ┊     0.18% ┊ parry2d::query::contact_manifolds::contact_manifolds_composite_shape_composite_shape::contact_manifolds_composite_shape_composite_shape::{{closure}}::{{closure}}::{{closure}}::{{closure}}::h87ffb528ede6bf77
        547147 ┊    41.05% ┊ ... and 2639 more.
       1332723 ┊   100.00% ┊ Σ [2739 Total Rows]

I'm not familiar with these tools, but it looks like there's no giant blob of some dependency getting smashed in. Seems like this is just how much it takes.

FWIW, matter.js seems to be ~120kB.

@Vrixyz
Copy link
Contributor

Vrixyz commented Jun 18, 2024

I'm not too familiar with codesize optimizations, but that's a valuable topic for sure!

I see a few serde items on the larger items, I'm curious how the filesize changes when the serialize feature is disabled 🤔.

Also, from guidelines at https://rustwasm.github.io/book/reference/code-size.html#use-trait-objects-instead-of-generic-type-parameters ; heavy generic-based codebase tends to generate a lot of code (due to monomorphization), and rapier heavily uses those.

It might be interesting to parse somehow the top dependencies rather than the top functions 🤔

@frankieali
Copy link

frankieali commented Aug 14, 2024

I'm currently trying to implement Rapier on CloudFlare Workers, but they have a 1MB limit on code size and version 0.14 is at 1.4MB. Thankfully, with gzip, it comes in under 1MB, but it's limiting other features I want to add. It would be great if there was a way to customize the build to exclude specific functionality. For example, I do not need joints or vehicles in my project. How much would that shrink the payload?
I'm transitioning over from AmmoJS and they did have a custom build system that wasn't too difficult to use. I was able to take the Ammo wasm build down to 310k (with brotli compression it's 115k).

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

No branches or pull requests

3 participants