perf: optimize event emission by passing filters by reference

This commit is contained in:
Tunglies 2026-01-30 10:09:50 +08:00
parent 32576120fd
commit 613b04cd28
No known key found for this signature in database
GPG Key ID: B9B01B389469B3E8
6 changed files with 16 additions and 10 deletions

View File

@ -0,0 +1,6 @@
---
"tauri": perf
"@tauri-apps/api": perf
---
Optimized event emission by passing filters by reference, reducing closure move overhead and improving memory ergonomics. No user facing changes.

View File

@ -198,7 +198,7 @@ impl Listeners {
Ok(lock) => {
if let Some(handlers) = lock.get(&emit_args.event) {
let handlers = handlers.iter();
let handlers = handlers.filter(|(_, h)| match_any_or_filter(&h.target, &filter));
let handlers = handlers.filter(|(_, h)| match_any_or_filter(&h.target, filter.as_ref()));
for (&id, Handler { callback, .. }) in handlers {
maybe_pending = true;
(callback)(Event::new(id, emit_args.payload.clone()))
@ -283,7 +283,7 @@ impl Listeners {
if let Some(handlers) = js_listeners.get(webview.label()).and_then(|s| s.get(event)) {
let ids = handlers
.iter()
.filter(|handler| match_any_or_filter(&handler.target, &filter))
.filter(|handler| match_any_or_filter(&handler.target, filter.as_ref()))
.map(|handler| handler.id)
.collect::<Vec<_>>();
webview.emit_js(emit_args, &ids)?;
@ -305,7 +305,7 @@ impl Listeners {
#[inline(always)]
fn match_any_or_filter<F: Fn(&EventTarget) -> bool>(
target: &EventTarget,
filter: &Option<F>,
filter: Option<&F>,
) -> bool {
*target == EventTarget::Any || filter.as_ref().map(|f| f(target)).unwrap_or(true)
}

View File

@ -1029,7 +1029,7 @@ pub trait Emitter<R: Runtime>: sealed::ManagerBase<R> {
{
let event = EventName::new(event)?;
let payload = EmitPayload::Serialize(&payload);
self.manager().emit_filter(event, payload, filter)
self.manager().emit_filter(event, payload, &filter)
}
/// Similar to [`Emitter::emit_filter`] but the payload is json serialized.
@ -1039,7 +1039,7 @@ pub trait Emitter<R: Runtime>: sealed::ManagerBase<R> {
{
let event = EventName::new(event)?;
let payload = EmitPayload::<()>::Str(payload);
self.manager().emit_filter(event, payload, filter)
self.manager().emit_filter(event, payload, &filter)
}
}

View File

@ -557,7 +557,7 @@ impl<R: Runtime> AppManager<R> {
&self,
event: EventName<&str>,
payload: EmitPayload<'_, S>,
filter: F,
filter: &F,
) -> crate::Result<()>
where
S: Serialize,
@ -578,7 +578,7 @@ impl<R: Runtime> AppManager<R> {
Some(&filter),
)?;
listeners.emit_filter(emit_args, Some(filter))?;
listeners.emit_filter(emit_args, Some(&filter))?;
Ok(())
}
@ -631,7 +631,7 @@ impl<R: Runtime> AppManager<R> {
match target {
// if targeting all, emit to all using emit without filter
EventTarget::Any => self.emit(event, payload),
target => self.emit_filter(event, payload, |t| filter_target(&target, t)),
target => self.emit_filter(event, payload, &|t| filter_target(&target, t)),
}
}

View File

@ -663,7 +663,7 @@ impl<R: Runtime> Webview<R> {
let payload = EmitPayload::Serialize(payload);
self
.manager()
.emit_filter(event, payload, |target| match target {
.emit_filter(event, payload, &|target| match target {
EventTarget::Webview { label } | EventTarget::WebviewWindow { label } => {
label == window_label
}

View File

@ -133,7 +133,7 @@ impl<R: Runtime> Window<R> {
let payload = EmitPayload::Serialize(payload);
self
.manager()
.emit_filter(event, payload, |target| match target {
.emit_filter(event, payload, &|target| match target {
EventTarget::Window { label } | EventTarget::WebviewWindow { label } => {
label == window_label
}