32

I'm building a SPA (Single Page Application) using KO. the application looks like a book and the user can flip pages.

The problem is that every time a page loads, there is a short moment where the page 'flickers' and the user sees the unstyled version of the page. I guess this is caused due to the fact that a lot of the styling is dependant on ko bindings so until ko finishes it 'magic' the user gets a glimpse of the unstyled code.

Is it possible to tell when KO finished all its bindings and only then show the page?

I've managed to partially solve it by setting a timeout before loading the view but of course this is not a good solution.

Tomer
  • 17,787
  • 15
  • 78
  • 137
  • you could possibly look to rework how your page bindings are done. Can't tell much by not seeing code, but you could deal with your page renders, and assign your observables on the page using the afterRender binding – Thewads Jan 29 '13 at 16:15

2 Answers2

56

Yes, it is very easy actually. Apply display:none to the top level div (or w/e container), and data-bind="visible: true". This will cause the page to be hidden until knockout unhides it via binding (which obviously can't happen until its fully loaded).

Since you are using a non-observable value, Knockout won't even bother to re-check this again. There shouldn't be a performance concern after the initial binding.

Kyeotic
  • 19,697
  • 10
  • 71
  • 128
  • Sounds like a cool idea, i'll try it and if it works i'll be sure to mark your answer :) – Tomer Jan 29 '13 at 18:30
  • 4
    Just to expand on this, you can apply the binding to a "loading" animation DIV that overlays the area you where you're trying to prevent flicker. Once the main application initializes, you can hide the overlay, revealing the application. One advantage to this is that the logical "visibility" of the application elements are undisturbed, so any binding/setup logic can still operate correctly. One other thing - if displaying automatically when KO processing the binding isn't sufficient, you may want to bind to a flag in your view model you set to indicate when your initialization is complete. – Joseph Gabriel Jan 29 '13 at 21:43
  • 1
    What I see with the answer chosen is that the element, that is initially hidden, flashes on after the page loads. Which I think is fine for my purpose. If I do the opposite, make it visible, then use the knockout visible binding to hide it, I think the effect is worse. I need both because the element should be shown/hidden based on other state on the page, which changes as the user interacts with it. Any ides for this case? – Evan Sep 09 '16 at 20:55
  • Yea, just change the visible binding to use whatever observable tracks the state your intereste din – Kyeotic Sep 09 '16 at 21:18
  • it's more reliable to apply **static css** to the target element, then execute JS to remove the style (via `ko.subscribe`, or more explicitly, such as: after calling `ko.applyBindings`, or in a callback to whatever init/ajax methods you may call before showing a view.) the problem with using static true/false values and then relying on `data-bind` is that the eval is deferred until `ko.applyBindings` has begun execution, whereas static css is applied at the time the markup is evaluated (pre-render.) removing the style via JS allows you to truly defer display until after the binding is complete – Shaun Wilson Feb 03 '17 at 03:05
  • I don't think that is correct. Style attribues and static css both apply at the time markup is evaluated. `data-bind` attributes *are* observables. They *are* JS that is applied by `ko.applyBindings` binding being complete. They are one in the same. – Kyeotic Feb 03 '17 at 06:50
  • Cannot upboat this answer enough! – Leonardo Wildt Sep 07 '17 at 19:26
4

I think this was answered better previously by using templates.

What is the best way to hide the screen while knockout js bindings are being built?

Community
  • 1
  • 1
Matthew Will
  • 445
  • 5
  • 10