Sharing behavior between lazy loaded app parts

538 views Asked by At

as the Polymer Starter Kit or the Polymer Shop demonstrate, we make use of lazy-loading in our Polymer application. This means we have a drawer-based layout and the app shell imports the drawer content as well as the main page content.

Now we introduce a behavior and use it in custom elements A and B where A is shown in the drawer and B in the main page. It's now the case that we get a browser (Chrome) warning, that flattenBehaviorsList couldn't find the behavior.

We assume this happens because the Polymer.importHref call (option asyncis true) for the main page recognizes the behavior (in custom element B) and adds its import to the HTML Import map. But before the content is imported, the Polymer.importHref (option asyncis true) call for the drawer wants to import the behavior for custom element A and takes the content from the HTML Import Map. But since the import isn't done, the behavior is null.

Is that assumption true? And if yes, is this a bug in Chrome – just an idea since it seems that Firefox handles this? Or is it bad design and we shouldn't share the same behavior in different lazy-loaded app parts?

What do you think?

Thanks in advance

2

There are 2 answers

11
alesc On BEST ANSWER

Lazy loading is the preferred way to load resources, that you don't need right away. But you have to do it right, which I will explain a bit later.

Having a behaviour in a separate file and re-using it across multiple custom elements is also very normal and even encouraged. However, all of the resources that a custom component needs must be loaded as a normal rel="import", meaning the async and defer flags must not be set.

For example, take a look at the following demo element, taken from the Polymer's devguide pages:

<link rel="import" href="highlight-behavior.html">

<script>
  Polymer({
    is: 'my-element',
    behaviors: [HighlightBehavior]
  });
</script>

As you can see, the behaviour is imported as a dependency. Without it, there would most likely be an error, as in your case.

Now comes the fun part - lazy loading. Here, you actually don't load everything that the component uses. So you must be well aware which resources you can, and which you cannot lazy load. As a rule of thumb, you must load everything that you use/instantiate directly inside the component.

Some common examples of lazy loading:

  • If you have an iron-pages element and all of the pages are custom elements, then you should eagerly load only the default (first) page, as others will not be used right away.
  • You can put non-esential GUI elements, such as slide-out sidebars inside a dom-if and render that dom-if after all of the components are lazy loaded. The easiest way for this is to use importHref.

A very good example for lazy loading elements is the Polymer's Shop app: source code, online demo.

To sum up: don't lazy load must-have dependencies for a custom element, but lazy load the element itself.

0
IntranetFactory On

I think I had the same problem today. When using importHref async I get errors like [paper-radio-button::_flattenBehaviorsList]: behavior is null, check for missing or 404 import, but when I change to async = false the error messages are gone.

It seems that this is a known bug of Polymer or probably Chrome https://github.com/Polymer/polymer/issues/2522