# Trying to understand the view-update loop better

**URL:** https://discourse.elm-lang.org/t/trying-to-understand-the-view-update-loop-better/7136
**Category:** Learn
**Created:** [March 21, 2021, 11:23am UTC](https://discourse.elm-lang.org/t/trying-to-understand-the-view-update-loop-better/7136 "2021-03-21T11:23:16Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![paulh](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/paulh/32/5022_2.png) [@paulh](https://discourse.elm-lang.org/u/paulh)
#### Post date: [March 21, 2021, 11:23am UTC](https://discourse.elm-lang.org/t/trying-to-understand-the-view-update-loop-better/7136/1 "2021-03-21T11:23:16Z")

</div>

Hi,

I’m trying to achieve something that should be pretty simple (on the face of it), but it has highlighted my lack of knowledge of the view-update loop in respect to DOM re-draws, and so was hoping someone could enlighten me.

(I may also be suffering from a mind-blockage and simply missing the 'bleedin obvious` 😄)

### My Scenario

I am retrieving a heap of data from my server that takes a few seconds to be processed by Elm when it is received. I therefore want to provide information to the user of the current state - `Loading` then `Processing` then `Ready`.

### My Problem

When the data is received, I can switch the `state` on the `model` from `Loading` to `Processing`, and begin processing the data, but the update to the model `state` is not reflected in the view until the processing is complete. This I understand and expected.

### Solutions?

I guess I need to trigger a re-draw of the DOM? I thought the following might suffice:

1. When the data is received in `update`:  
a. update the model state: `{ model | state = Processing }`  
b. start a `Task`: `Task.perform TimeMsg Time.now`
2. When `TimeMsg` is received in `update` start processing the data

I figured the view would be updated between steps 1 and 2 and reflect the new `model`, but it appears that it isn’t.

I could try various other Tasks, and maybe try `ports` to force the view-update loop to be triggered with the updated model, but I feel that I don’t really understand the cycle, and although I might find a solution I would prefer to understand it rather than simply find it by experimenting and maybe end up with the wrong assumptions.

Also, using a built-in `Task` or a `port` loop feels a bit hacky, and doesn’t really express that all I want to do is to update the view prior to starting to process the data received in `update`.

Can someone explain further or point me to some reading? I would like to understand more about what is going on under the hood. (Do some `Tasks`, but not others, cause the view-update loop to be initiated with the updated `model`, if so, how do you determine which ones? Is there a way to create a custom `Task` that expresses better what I want to achieve - assuming this forces a DOM re-draw.)

TIA to anyone that can explain further.

---

<div class="post-metadata">

### Author: ![pdamoc](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/pdamoc/32/36_2.png) [@pdamoc](https://discourse.elm-lang.org/u/pdamoc)
#### Post date: [March 21, 2021, 12:49pm UTC](https://discourse.elm-lang.org/t/trying-to-understand-the-view-update-loop-better/7136/2 "2021-03-21T12:49:20Z")

</div>

> [@paulh](#):
>
> Can someone explain further or point me to some reading?

There are two update loops. The first one is the one that updates the model and the second one is the one that updates the DOM.

The first loop is capable of handling a high frequency of updates. The second one is bound to the animationFrame. This means no more than 60 updates per second.

In your case, most likely, the arrival of the data and the processing of the data happen on the same frame and this is why you are not seeing “Processing”. The call to `Time.now` returns too fast to matter. So, I would expect that if you use `Process.sleep 20 |> Task.perform (\_ -> StartProcessing) `, you should be able to see the change in the model.

---

<div class="post-metadata">

### Author: ![paulh](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/paulh/32/5022_2.png) [@paulh](https://discourse.elm-lang.org/u/paulh)
#### Post date: [March 21, 2021, 12:53pm UTC](https://discourse.elm-lang.org/t/trying-to-understand-the-view-update-loop-better/7136/3 "2021-03-21T12:53:50Z")

</div>

Thanks.

I’ve just this minute used a subscription to `Time.every 100 StartProcessing` which works, but hides the logic behind an `if` in `subscriptions` - your solution is more of what I was looking for, and your explanation clears up a few things for me. 👍

---

<div class="post-metadata">

### Author: ![mattpiz](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/mattpiz/32/860_2.png) [@mattpiz](https://discourse.elm-lang.org/u/mattpiz)
#### Post date: [March 21, 2021, 1:16pm UTC](https://discourse.elm-lang.org/t/trying-to-understand-the-view-update-loop-better/7136/4 "2021-03-21T13:16:34Z")

</div>

> [@pdamoc](#):
>
> The first loop is capable of handling a high frequency of updates. The second one is bound to the animationFrame. This means no more than 60 updates per second.

To complement this, JavaScript is single threaded, so the next frame has to wait for any computation started before it was scheduled. That is why pages sometimes feel unresponsive. If you want to be really sure that the view was updated, you can wait for message from [`onAnimationFrame`](https://package.elm-lang.org/packages/elm/browser/latest/Browser-Events#onAnimationFrame) before starting computation, or run it in a different web worker.

You might also be interested in those discussions:

- [Long-running computations in Elm that won't freeze the page](https://discourse.elm-lang.org/t/long-running-computations-in-elm-that-wont-freeze-the-page/5836)
- [How to deal with blocking JS code (using ports)?](https://discourse.elm-lang.org/t/how-to-deal-with-blocking-js-code-using-ports/818) (it seems you already participated in that conversation but still relevant)

---

<div class="post-metadata">

### Author: ![paulh](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/paulh/32/5022_2.png) [@paulh](https://discourse.elm-lang.org/u/paulh)
#### Post date: [March 21, 2021, 1:53pm UTC](https://discourse.elm-lang.org/t/trying-to-understand-the-view-update-loop-better/7136/5 "2021-03-21T13:53:40Z")

</div>

The processing is of data requested by the user, so if it makes the page unresponsive for a couple of seconds that’s acceptable in this case, they will be expecting a slight delay. The data is coming in over a WebSocket, so if it does become too large and slow to process I could push it from the server in chunks, and process it incrementally with feedback.

Thanks for the info, and the links (including the one to my [cringe] comment from when I first started with Elm 🤣 )

---

<div class="post-metadata">

### Author: ![Adriano](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/adriano/32/3842_2.png) [@Adriano](https://discourse.elm-lang.org/u/Adriano)
#### Post date: [March 21, 2021, 11:48pm UTC](https://discourse.elm-lang.org/t/trying-to-understand-the-view-update-loop-better/7136/6 "2021-03-21T23:48:24Z")

</div>

This is just off the top of my head, and may not apply, but have you also looked into using Web Workers to process that data, so it can be handled on a different thread?

Should mean it won’t make the page unresponsive.

---

<div class="post-metadata">

### Author: ![system](https://canada1.discourse-cdn.com/flex035/uploads/elm_lang/original/1X/50a05e53677a2c3b47776d7abd0f113eb50193a1.png) [@system](https://discourse.elm-lang.org/u/system)
#### Post date: [March 31, 2021, 11:48pm UTC](https://discourse.elm-lang.org/t/trying-to-understand-the-view-update-loop-better/7136/7 "2021-03-31T23:48:55Z")

</div>

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.
