Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parent views containing a router-view should be able to render before child activate promise resolves #26

Open
briannoyes opened this issue Jun 2, 2016 · 11 comments

Comments

@briannoyes
Copy link

With the latest code, if a child view placed into router-view within a parent view returns a promise from its activate method, the parent is not rendered until the child promise completes. For a shell view containing a router-view for its main content area, it would be pretty normal to show the shell and even let the user interact with it to possibly select a menu or view information in another child view while the child view in the router-view is loading (and probably showing some kind of progress indicator in the shell or in the main content area. With the current code that does not appear to be possible.

@EisenbergEffect EisenbergEffect self-assigned this Jun 2, 2016
@paulharker
Copy link

Hi Rob and Team,
I agree with Brian, if we are loading our child template with a promise, I would like to load my "shell" with a wireframe (like Facebook does) until my content comes in.

@EisenbergEffect
Copy link
Contributor

We can enable it by adding a new property on the router-view.

@briannoyes
Copy link
Author

Sounds like a straightforward approach to me. Not saying it has to be the default behavior, just want a simple approach to opt in to that behavior.

@rajajhansi
Copy link

@EisenbergEffect I agree with Brian. This issue doesn't shows up in skeleton-navigation because the progress indicator is wired in index.html even before the shell (i.e. app.html/.js) is loaded. Even there, for every navigation the full page "AURELIA SKELETON NAVIGATION" with an AJAX progress shows up, which becomes annoying after a point. I remember seeing a youtube style progress bar (like this: http://ricostacruz.com/nprogress/ ) down below the top navigation menu in earlier aurelia samples, which was much better.

@fkleuver
Copy link
Member

I know this has been sitting in limbo for a while, but afaik we still don't have a way to do this.

I'm very interested in having an opt-in for viewmodels to start rendering immediately after they activate, rather than waiting for all activates to resolve.

@EisenbergEffect you mention a property, but as far as I understand it the router in principle won't kick off the rendering process before aurelia knows precisely what to render (which is after all CommitChangesSteps have run), and then the rendering happens inside-out.

I've visualized this by proxying everything through a logger, and put a 300ms promise delay in the viewmodel activate functions to simulate some loading time. view-model 1 (and router-view 1) is the root.

35.298 [-view-model 1] activate
35.337 [-view-model 1] configureRouter
35.346 [-router-view 1] created
35.353 [-view-model 1] created
35.362 [-view-model 1] bind
35.377 [-router-view 1] bind
35.400 [--view-model 2] configureRouter
35.407 [---view-model 3] configureRouter
35.414 [----view-model 4] configureRouter
35.422 [--view-model 2] activate
35.726 [---view-model 3] activate
36.030 [----view-model 4] activate
36.335 [-router-view 1] process
36.351 [--router-view 2] created
36.359 [--router-view 2] process
36.366 [---router-view 3] created
36.371 [---router-view 3] process
36.377 [----router-view 4] created
36.381 [----router-view 4] process
36.393 [----router-view 4] swap
36.397 [---router-view 3] swap
36.401 [----view-model 4] created
36.404 [----view-model 4] bind
36.409 [----router-view 4] bind
36.413 [--router-view 2] swap
36.418 [---view-model 3] created
36.422 [---view-model 3] bind
36.426 [---router-view 3] bind
36.431 [-router-view 1] swap
36.435 [--view-model 2] created
36.439 [--view-model 2] bind
36.444 [--router-view 2] bind
36.451 [----router-view 4] _notify
36.454 [---router-view 3] _notify
36.455 [--router-view 2] _notify
36.455 [-router-view 1] _notify
36.458 [-view-model 1] attached
36.469 [--view-model 2] attached
36.471 [---view-model 3] attached
36.472 [----view-model 4] attached

After the last activate resolves, the entire rendering process of all pages happens in about 137ms. This means that with most webapi-ish delays in resolving an activate, a page can easily be rendered before the next activate resolves.

Currently the only way around this as being a constant, is by aggressively caching stuff on the client which makes initial load times for data-driven navigations even slower.

The pipeline steps seem to run (for the most part) one-by-one per type and there's no way around this without changing the pipeline. What's needed for this is an opt-in such that activate 2 still has to wait for activate 1 to resolve, but commitChanges 1 doesn't have to wait for activate 2 to resolve.
I'm thinking two possible approaches here:

  1. Allow for a different router pipeline implementation to be used
  2. Extend the existing router pipeline with something like "pipelineRunStrategy"

But it's not just a router concern, because the composition engine has to know that it should delay processing for a router-view whose child activation lifecycle has not completed yet. Rather than a fully inside-out rendering process, you'd have a multiple-passes rendering process.

I feel like I'm insane for suggesting to have a stab at this, but I need it. Is this something you think can be done?

@davismj
Copy link
Member

davismj commented Mar 21, 2018

@fkleuver why not just resolve the child activate immediately, then?

@fkleuver
Copy link
Member

@davismj Because activate, as far as I know, is the proper place to wait for server data to load.

Resolving that before the server data is loaded I need to pollute my custom elements with all kinds of "is the data there yet?" checks to delay rendering until it is.

Which is really what I'm hoping (and typically advise other people) to avoid in favor of awaiting the loading during activate.

If the router can neatly handle postponing page rendering until activates are resolved, but allows a resolved parent activate to start the rendering of that parent before the child activate is resolved, then that would be a router that just scratches the itch.

@Alexander-Taran
Copy link

@fkleuver how you you handle long loads? do you not show some spinner/progress?

@fkleuver
Copy link
Member

@Alexander-Taran Currently you can only do that in the top-level page of where the navigation starts which, in case of a full page load, is the index.html. Let me show you an example:

https://fkleuver.github.io/aurelia-recursive-navigation-sample/#/

  • Click "all at once" in the left -> imagine a loader and then after a few seconds all pages show up
  • Click "one by one" -> that is what I would like to happen (I'm currently "mimicking" that by actually loading them one by one, rather than the whole url at once)

@davismj
Copy link
Member

davismj commented Apr 8, 2018

@fkleuver excellent ideas as always, Fred.

@fkleuver
Copy link
Member

fkleuver commented Apr 8, 2018

@davismj I don't know what idea you're referring to, but I'm still kind of clueless on how to approach this without changes to router, templating-router and templating that would probably give the team a heart attack. Maybe this should be left for vNext..

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants