elm-spa icon indicating copy to clipboard operation
elm-spa copied to clipboard

Init is being called far too often

Open opsb opened this issue 3 years ago • 1 comments

I'm seeing that the init page callback is called far too often. I see it being called multiple times for the current page and also once for each of the other pages in my app. I traced through the calls for the current page and discovered that init was being triggered by the subscriptions call. Looking at the implemention of page it's now obvious what the issue is, init isn't lazy so every time page is called init is also evaluated. page is called many times in the elm-spa implementation when a page is loaded so init ends up being called many times.

page : Shared.Model -> Request.With Params -> Page.With Model Msg
page shared req =
    Page.element
        { init = init
        , update = update req
        , view = view
        , subscriptions = subscriptions
        }

If you look at the init callback on https://package.elm-lang.org/packages/elm/browser/latest/Browser#element for instance you can see that the Flags are passed in so the function is called lazily. afaict Page.element should have the type

(Cmd msg -> effect)
    -> { init : () -> ( model, Cmd msg )
       , update : msg -> model -> ( model, Cmd msg )
       , view : model -> view
       , subscriptions : model -> Sub msg
       }
    -> Page shared route effect view model msg

Fortunately, because the result of the init call is ignored unless the code explicitly wants the result the only cost here is that the model and cmd and constructed and thrown away. It is rather confusing though if you're debugging as I for instance ended up with init being called 12 times for a single page load.

opsb avatar Dec 27 '21 10:12 opsb

Multiple calls to init in a Page module also happens during a update call inside of a Page module, easily reproducible in https://github.com/ryannhg/elm-spa-realworld by adding a Debug.log call in for instance Home_ -> update -> ClickedFavorite and a Debug.log call in Home_ -> init, you'll notice the Debug call from init first, then the actual ClickedFavorite call and then multiple more calls to init.

petteraas avatar Feb 08 '22 11:02 petteraas