Angular: Simplified deferred loading for components

Created on 24 May 2017  Â·  17Comments  Â·  Source: angulardart/angular

Surprise! We have an experimental feature currently being validated, and we're ready to commit to landing it formally in 4.0.0. We've heard a lot of feedback that users wish deferred/lazy-loading was easier, even when not using a router.

As of an upcoming release, we've introduced a new "compile-time" directive:

<comp !deferred></comp>

What !deferred means is that the component that is annotated will _not_ be loaded eagerly, rather, we will load that component's library using Dart's deferred loading, and it will be loaded and initialized asynchronously after initial load.

Example use

import 'package:angular2/angular2.dart';
import 'expensive_comp.dart' show ExpensiveComp;

@Component(
  selector: 'my-comp',
  directives: const [ExpensiveComp],
  template: r'''
    <expensive-comp !deferred></expensive-comp>
  ''',
)
class MyComp {}

Caveats

  • You can only annotate a _component_, not an HTML element or a _directive_.
  • Because !deferred is a built-in directive, it won't go in your directives: [ ... ] list.
  • It can't be used in conjunction with a structural directive (i.e. *ngIf) but you can do this:
<!-- When a panel is expanded, lazy load and show <expensive-comp> -->
<template [ngIf]="isPanelExpanded">
  <expensive-comp !deferred></expensive-comp>
</template>

_Some of this functionality works already, but we aren't committing it formally with documentation and an exact contract or better error messages until 4.0_

Most helpful comment

nit: !deferred to me reads as "not deferred", which is the opposite of what you are actually doing. Maybe in angular context it makes sense though idk :D.

All 17 comments

Awesome!
Seriously, this is excellent news

nit: !deferred to me reads as "not deferred", which is the opposite of what you are actually doing. Maybe in angular context it makes sense though idk :D.

nit: !deferred to me reads as "not deferred", which is the opposite of what you are actually doing. Maybe in angular context it makes sense though idk :D.

Fair enough. We haven't committed to this exact prefix (though that's what we have parsed so far). Open to reasonable suggestions/alternatives.

Fair enough. We haven't committed to this exact prefix (though that's what we have parsed so far). Open to reasonable suggestions/alternatives.

What about ngDeferred?

Fair enough. We haven't committed to this exact prefix (though that's what we have parsed so far). Open to reasonable suggestions/alternatives.

What about ngDeferred?

One confusing bit is this isn't a directive, so we want to differentiate the syntax somehow to make this clear.

:deferred, or #deferred?

I'm okay with !deferred. You could probably pick any number of symbols which aren't already used by the template syntax though.

Some more ideas:

@deferred, $deferred,

#deferred would be a template reference however, so I don't think that is a good choice.

@deferred is better than !deferred, but it is not that important thought.
this is a very, very nice feature @matan, great job

anxious for 4.0

2017-05-24 16:41 GMT-03:00 Jonah Williams notifications@github.com:

I'm okay with !deferred. You could probably pick any number of symbols
which aren't already used by the template syntax though.

Some more ideas:

@deferred, $deferred,

deferred would be a template reference however, so I don't think that is

a good choice.

—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/dart-lang/angular2/issues/406#issuecomment-303830229,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AF6Y3m9xNleWHXHSYZTjCTghBewHcMRTks5r9IfsgaJpZM4NlW0y
.

--
Jonathan Rezende

... this isn't a directive, so we want to differentiate the syntax somehow to make this clear.

@matanlurey, do we _really_ need to have different syntax? E.g. <template> isn't a normal element but it doesn't have special syntax.

I like @deferred.

@chalin:

... this isn't a directive, so we want to differentiate the syntax somehow to make this clear.

@matanlurey, do we _really_ need to have different syntax? E.g. <template> isn't a normal element but it doesn't have special syntax.

Sure, we could just do <div deferred>, but is that obvious enough to folks?

@skybrian:

@deferred is an option.

The community wins, we are renaming to @deferred. 🎆

How do I control when this deferred component is loaded? E.g. I want to start loading a deferred component as soon as my main page is rendered.

The component is loaded ~immediately after first render.

You can always wrap with an *ngIf to have your own precise load:

<template [ngIf]="loadComponent">
  <expensive-comp @deferred></expensive-comp>
</template>

Looks like:

<expensive-comp [ngIf]="loadComponent"
                               @deferred></expensive-comp>

will always be loaded and ngIf is ignored.

If
` <template [ngIf]="loadComponent"> <expensive-comp @deferred></expensive-comp> </template>
is used, will deferred chunk still start downloading ~immediately after first render, or after ngIf is true?

Ignore my question, found it in caveat: "It can't be used in conjunction with a structural directive".

Does this mean the deferred component cannot have any input?

@wangyizhuo Caveat aside, there's a mistake in your first example. Structural directives manipulate the DOM and only work on <template> elements, so your first example wouldn't work anyways. For convenience, the asterisk * notation can be used on structural directives so they can be placed on arbitrary elements, which then desugars into the <template> syntax.

<expensive-comp *ngIf="loadComponent" @deferred></expensive-comp>

This is unrelated to inputs, which _are_ supported for deferred components.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ranquild picture ranquild  Â·  4Comments

AndreyChernykh picture AndreyChernykh  Â·  4Comments

zoechi picture zoechi  Â·  5Comments

supermuka picture supermuka  Â·  5Comments

Tomucha picture Tomucha  Â·  5Comments