-
Notifications
You must be signed in to change notification settings - Fork 156
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
New EventListener patching, refactors, ElRef, nodes!, etc. #330
New EventListener patching, refactors, ElRef, nodes!, etc. #330
Conversation
I need to dive in more thoroughly, but from your summary and a skim of the code, I agree on all points. Highlights:
|
58f09fd
to
663338e
Compare
Have you noticed a performance improvement from the listener change? |
I think that examples in the repo are too small to notice slowdown due to listener attachments and Rust is too fast to notice slowdown due to DOM traversing by the naked eye. Maybe once benchmark is set up (#324) we can test it with adding listeners to window and test rows. |
Definitely like nodes! as a standin for vec! Node or Node. It will simplify a lot! |
It's a big PR, but each commit has been checked with
cargo make verify
so you can review them one by one. I recommend to readCHANGELOG.md
as the first step.I think the changelog is sufficient as the list of changes for this PR, I would rather write about reasons why or how I've made these changes.
Removed old
update
&trigger_update_ev
, lifecycle hooks, internal input listeners - they were incomplete or their behavior was surprising or better alternatives exist. Removing was the first step before other refactors because those features made codebase more complicated.Rewritten event listener patching. The biggest problem was constant reattaching of all listeners - it was slow and error-prone because it often kills fired event in fly.
How it works now:
El
containsEventHandlerManager
. (There is also a "special"EventHandlerManager
forwindow
.)EventHandlerManager
contains and managesEventHandler
s andListener
s for the givenEl
.EventHandler
is a user's handler - it's created in the app code and returnsMsg
.Listener
is the Seed internal representation of a native DOM EventListener.EventHandler
s are grouped by theirEv
(a.k.a event / trigger) and each group may have oneListener
. ThisListener
has the sameEv
like theEventHandler
s and it is created during VDOM patching or it can be moved from the old element version (i.e. reused).Listener
calls allEventHandlers
from the group once the associated eventEv
is fired.Listener
automatically detach associated DOM EventListener on drop.Listener
s should be reused as much as possible to prevent lost events and performance issues.Listener
s are connected to theEventHandler
s throughListener
fieldportal
.Portal
allows to modifyEventHandlers
group and also change referencedEventHandler
group even when theListener's
callback
has been already sent to the JS world and registered as the DOM EventListener.All examples refactored. I've added a simpler counter example (the old one is renamed to
counter_advanced
) because we need something for the beginners who see a Seed app (and maybe Rust) for the first time. And I've removed exampleserver_interaction_detailed
because I have no idea what is it, what users can learn from it and it doesn't work (?) + looks very incomplete.Added
el_ref
+ElRef
- users can use native DOM elements safely becauseElReg::get
checks if the referenced element exists, is in the DOM now and has the right type. And users don't have to use any error-prone selectors. See examples (canvas
,user_media
ortodomvc
).I'm not very happy with the implementation, but I've chosen the less invasive one and I want to refactor
patch.rs
,virtual_dom_bridge.rs
and related things in the future - there are too many "bad things" likeexpects
and side-effects scattered in this code, so it's very error-prone.Added macro
nodes!
. I had to often write something like:It can be rewritten to:
Or
nodes![]
can be the alternative tovec![]
as the equivalent toempty![]
for multiple nodes.Ev
,Tag
,St
andAt
have consistent API now and can be created byX:from(Into<Cow<'static, str>)
. I think the most custom instances are created with the'static str
(e.g.At::from("my-attribute")
) so it should improve performance a bit, because, for instance,Ev
is often cloned in the Seed codebase because of event-handling and patching requirements.However this change will be almost the internal one in the future, because we will have a different APIs for working with those entities - for instance new API for attributes is ready for implementation.
raw_ev
is deprecated in favor ofev
(i.e. renamed). Usingsimple_ev
is problematic because it requiresClone
implementation forMs
and you had to rewrite it intoraw_ev
when you want to call e.g.prevent_default.
It makes app code a little bit less consistent and someMsg
data can't be cloned so you have to wrap them with something likeRc
. So I'd rather useraw_ev
everywhere instead ofsimple_ev
. Butraw_ev
is unnecessary verbose + all events in handlers are "raw" (they have only different type) so the name isn't also very accurate.