-
Notifications
You must be signed in to change notification settings - Fork 19
Description
Description
When working on Thoth.Elmish.Toast I discovered that previous event handler are not cleaned HMR update. This is normal, because HMR can't know how to clean the old events handlers.
I managed to write a fix for this
// If HMR support is active, then we provide have a custom implementation.
// This is needed to avoid:
// - flickering (trigger several react renderer process)
// - attaching several event listener to the same event
if not (isNull HMR.``module``.hot) then
if HMR.``module``.hot.status() <> HMR.Idle then
Browser.window.removeEventListener(eventIdentifier, !!Browser.window?(eventIdentifier))
Browser.window?(eventIdentifier) <- fun (ev : Browser.Event) ->
let ev = ev :?> Browser.CustomEvent
dispatch (Add (unbox ev.detail))
Browser.window.addEventListener(eventIdentifier, !!Browser.window?(eventIdentifier))
else
Browser.window.addEventListener(eventIdentifier, !^(fun ev ->
let ev = ev :?> Browser.CustomEvent
dispatch (Add (unbox ev.detail))
))
This is a known problem when using HMR, we need to clean the "global states" (event listener, global variables, etc) by ourself even in pure JavaScript.
At the time I was thinking that the Program.toNavigable
was ok in current state because it's checking capturing when the newLocation
is equal to lastLocation
.
But it's not enough in fact, because when we have an HMR update I think we are creating a new Elmish instance. And so each instance is having its own handlers
and lastLocation
reference.
So for example, if in your code base when you have a page change you send a request to the server then you will send X
request to your server. In the same way, I do have some concurrent race and each application try to render it's own view when a page change and it's causing some visual flickering.
In general, the renderered view is the newest program registered so this is why no one noticed this problem yet.
I will send a PR to remove old events listeners when using Program.toNavigable
On a side note, I will try to see if we can also completly kill the previous Elmish instance as they are still in running in memories.
Here I triggered 3 updates of the code and so have:
- Fleet Mapping aka instance n°1
- Instance n°2
- Instance n°3
- Instance n°4