feat: router-based wasm bundle splitting (#3683)
* feat: wasm-split base implementation * kinda sorta works with the cli * okay great it actually works * fix: cache busting for chunks * cleaned up version * it works with the router * wip: migrate to a faster linear solution using id remapping * add a good harness * it works completely on the docsite * the super tight build works too * make parallelizable * works on the docsite but not the harness * light cleanups, fix for both harness and docsite * make codegen smaller by extract some shared functions to prevent monos * chunking works, but tbd on tuning heuristics * extract used module * wip: cleaning up module * wip: much better understanding of how imports work * fix the call graph * working again... * wip: thinking about ifuncs * ifunc approach works * yes the ifunc approach works!! * it all works completely even with chunks * small cleanups * comments * actually locate all of the symbols * clean up final implementation * clean up tomls, revert some mono changs * clean up, add some more comments / docs in places * hoist more packages * clean up impl a bit more * clean cli * move harness to playwright * update playwright * extract codgen * add lazy to components * Add docs to split loader * clippy * typos * clippy, don't generate splits if not on wasm * whoops, const * Typos and docs * enable optimizations in ci * add optimizations to ci * add wasm-split router feature * parallel playwright? * fix no case check * disable pre-compress... think that might be the issue * better logging, no default pre-compress, caching of shared symbols * Fix: compressing assets * fix non-interactive logging for serve * cache playwright even on failure, use the cli with optimizations * fix prebuild * fix playwright webserver
This commit is contained in:
1 parent
14eb7597df
commit
bdeedc13eb
59 files changed
+4249
-299
No files matched your search
@@ -75,19 +75,27 @@ impl<F: ComponentFunction<P, M> + Clone, P: Clone + 'static, M: 'static> AnyProp
|
||||
}
|
||||
|
||||
fn render(&self) -> Element {
|
||||
let res = std::panic::catch_unwind(AssertUnwindSafe(move || {
|
||||
self.render_fn.rebuild(self.props.clone())
|
||||
}));
|
||||
|
||||
match res {
|
||||
Ok(node) => node,
|
||||
Err(err) => {
|
||||
let component_name = self.name;
|
||||
tracing::error!("Panic while rendering component `{component_name}`: {err:?}");
|
||||
let panic = CapturedPanic { error: err };
|
||||
Element::Err(panic.into())
|
||||
fn render_inner(name: &str, res: Result<Element, Box<dyn Any + Send>>) -> Element {
|
||||
match res {
|
||||
Ok(node) => node,
|
||||
Err(err) => {
|
||||
// on wasm this massively bloats binary sizes and we can't even capture the panic
|
||||
// so do nothing
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
{
|
||||
tracing::error!("Panic while rendering component `{name}`: {err:?}");
|
||||
}
|
||||
Element::Err(CapturedPanic { error: err }.into())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
render_inner(
|
||||
self.name,
|
||||
std::panic::catch_unwind(AssertUnwindSafe(move || {
|
||||
self.render_fn.rebuild(self.props.clone())
|
||||
})),
|
||||
)
|
||||
}
|
||||
|
||||
fn duplicate(&self) -> BoxedAnyProps {
|
||||
|
||||
@@ -450,6 +450,16 @@ impl Scope {
|
||||
hooks.push(Box::new(initializer()));
|
||||
}
|
||||
|
||||
self.use_hook_inner::<State>(hooks, cur_hook)
|
||||
}
|
||||
|
||||
// The interior version that gets monoorphized by the `State` type but not the `initializer` type.
|
||||
// This helps trim down binary sizes
|
||||
fn use_hook_inner<State: Clone + 'static>(
|
||||
&self,
|
||||
hooks: std::cell::RefMut<Vec<Box<dyn std::any::Any>>>,
|
||||
cur_hook: usize,
|
||||
) -> State {
|
||||
hooks
|
||||
.get(cur_hook)
|
||||
.and_then(|inn| {
|
||||
|
||||
@@ -162,6 +162,16 @@ impl Runtime {
|
||||
scope: ScopeId,
|
||||
task: impl Future<Output = ()> + 'static,
|
||||
ty: TaskType,
|
||||
) -> Task {
|
||||
self.spawn_task_of_type_inner(scope, Box::pin(task), ty)
|
||||
}
|
||||
|
||||
// a non-momorphic version of spawn_task_of_type, helps with binari sizes
|
||||
fn spawn_task_of_type_inner(
|
||||
&self,
|
||||
scope: ScopeId,
|
||||
pinned_task: Pin<Box<dyn Future<Output = ()>>>,
|
||||
ty: TaskType,
|
||||
) -> Task {
|
||||
// Insert the task, temporarily holding a borrow on the tasks map
|
||||
let (task, task_id) = {
|
||||
@@ -176,7 +186,7 @@ impl Runtime {
|
||||
scope,
|
||||
active: Cell::new(true),
|
||||
parent: self.current_task(),
|
||||
task: RefCell::new(Box::pin(task)),
|
||||
task: RefCell::new(pinned_task),
|
||||
waker: futures_util::task::waker(Arc::new(LocalTaskHandle {
|
||||
id: task_id.id,
|
||||
tx: self.sender.clone(),
|
||||
|
||||
Reference in new issue
Block a user