erikringsmuth / app-router

Router for Web Components
https://erikringsmuth.github.io/app-router/
MIT License
610 stars 83 forks source link

Add an option to asynchronously load imports #95

Closed plequang closed 9 years ago

plequang commented 9 years ago

Hi,

After #79, I'm continuing on working with app-router under slow network conditions. In such situation, it would be nice to be able to display a "Please wait" message during import of large template files.

I've found one solution using app-router with core-animated-pages, using the following app-router configuration :

<app-router core-animated-pages transitions="cross-fade-all" init="manual">
  <app-route path="/big-element1" import="pages/big-element-1.html" element="big-element-1"></app-route>
  <app-route path="/big-element2" import="pages/big-element-2.html" element="big-element-2"></app-route>
  <div id="loading" path="/loading">
    <h2>Please wait while loading...
  </div>

When event activate-route-start is fired, I do the following :

router.addEventListener('activate-route-start', function(event) {
  router.coreAnimatedPages.selected = '/loading';
});

This causes core-animated-page to display my "please wait" message. When HTMLImport load event is fired, app-router displays the selected route normally.

There is however an issue, because HTML imports block rendering (this is explained here http://www.html5rocks.com/en/tutorials/webcomponents/imports/).

So the "Please wait" message is not displayed immediately, but only when the load event is fired, so it only "flashes" before the selected route is activated.

But if I use "async" html import (<link rel="import" .. async>), then the message is displayed immediately.

app-router does not use the content of the import before the load event is fired, so it should cause no side effects if we had an option such as the following to either app-router or app-route element (or both) :

<app-router ... async-import >
   <app-route import="" ... async-import>

What do you think ? Can I create a PR to add this option to app-router ?

Thanks Pascal

erikringsmuth commented 9 years ago

Wow, I didn't realize imports blocked like scripts! I almost think we should switch all imports to async by default.

plequang commented 9 years ago

Well, why not if you think it's safe.

In the article, Eric Bidelman says :

The reason async isn't the default for HTML Imports is because it requires developers to do more work

To be honest, I do not understand all the consequences of this async attribute when importing polymer components or templates.

erikringsmuth commented 9 years ago

Synchronous loading means the import will be guaranteed loaded before it the browser starts rendering the elements that rely on the import.

<link rel="import" src="example-el.html">
<example-el></example-el>

This prevents <example-el> from rendering before the link finishes importing.

Alternatively,

<link rel="import" src="example-el.html" async>
<example-el></example-el>

This would render <example-el> as an unresolved element and then later upgrade it when the import finishes.

In the case of app-router, we already wait for the load event to fire so it's safe to use async all the time.

erikringsmuth commented 9 years ago

I added the async attribute and everything seems to be working. https://github.com/erikringsmuth/app-router/commit/1542c4d785fe5f660bbc42a154884fe758fa9be4 You can pull the master branch to test it out.

plequang commented 9 years ago

Tried with my "Loading view" message and it works. Thanks