Skip to content

Commit

Permalink
refactor(compiler): introduce defer trigger instructions (angular#51315)
Browse files Browse the repository at this point in the history
Adds the logic for generating the instructions for the various deferred triggers.

PR Close angular#51315
  • Loading branch information
crisbeto authored and pkozlowski-opensource committed Aug 11, 2023
1 parent 79f9d49 commit 5212b47
Show file tree
Hide file tree
Showing 18 changed files with 444 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -352,3 +352,101 @@ export declare class MyApp {
static ɵcmp: i0.ɵɵComponentDeclaration<MyApp, "ng-component", never, {}, {}, never, never, true, never>;
}

/****************************************************************************************************
* PARTIAL FILE: deferred_with_triggers.js
****************************************************************************************************/
import { Component } from '@angular/core';
import * as i0 from "@angular/core";
export class MyApp {
constructor() {
this.message = 'hello';
this.isReady = true;
}
isVisible() {
return false;
}
}
MyApp.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: MyApp, deps: [], target: i0.ɵɵFactoryTarget.Component });
MyApp.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "0.0.0-PLACEHOLDER", type: MyApp, selector: "ng-component", ngImport: i0, template: `
{{message}}
{#defer when isVisible() || isReady; on idle, timer(1337); on immediate, hover;
on interaction(button); on viewport(button)}
{{message}}
{:placeholder}<button #button>Click me</button>
{/defer}
`, isInline: true });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: MyApp, decorators: [{
type: Component,
args: [{
template: `
{{message}}
{#defer when isVisible() || isReady; on idle, timer(1337); on immediate, hover;
on interaction(button); on viewport(button)}
{{message}}
{:placeholder}<button #button>Click me</button>
{/defer}
`,
}]
}] });

/****************************************************************************************************
* PARTIAL FILE: deferred_with_triggers.d.ts
****************************************************************************************************/
import * as i0 from "@angular/core";
export declare class MyApp {
message: string;
isReady: boolean;
isVisible(): boolean;
static ɵfac: i0.ɵɵFactoryDeclaration<MyApp, never>;
static ɵcmp: i0.ɵɵComponentDeclaration<MyApp, "ng-component", never, {}, {}, never, never, false, never>;
}

/****************************************************************************************************
* PARTIAL FILE: deferred_with_prefetch_triggers.js
****************************************************************************************************/
import { Component } from '@angular/core';
import * as i0 from "@angular/core";
export class MyApp {
constructor() {
this.message = 'hello';
this.isReady = true;
}
isVisible() {
return false;
}
}
MyApp.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: MyApp, deps: [], target: i0.ɵɵFactoryTarget.Component });
MyApp.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "0.0.0-PLACEHOLDER", type: MyApp, selector: "ng-component", ngImport: i0, template: `
{{message}}
{#defer prefetch when isVisible() || isReady; prefetch on idle, timer(1337);
prefetch on immediate, hover; prefetch on interaction(button); prefetch on viewport(button)}
{{message}}
{:placeholder}<button #button>Click me</button>
{/defer}
`, isInline: true });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: MyApp, decorators: [{
type: Component,
args: [{
template: `
{{message}}
{#defer prefetch when isVisible() || isReady; prefetch on idle, timer(1337);
prefetch on immediate, hover; prefetch on interaction(button); prefetch on viewport(button)}
{{message}}
{:placeholder}<button #button>Click me</button>
{/defer}
`,
}]
}] });

/****************************************************************************************************
* PARTIAL FILE: deferred_with_prefetch_triggers.d.ts
****************************************************************************************************/
import * as i0 from "@angular/core";
export declare class MyApp {
message: string;
isReady: boolean;
isVisible(): boolean;
static ɵfac: i0.ɵɵFactoryDeclaration<MyApp, never>;
static ɵcmp: i0.ɵɵComponentDeclaration<MyApp, "ng-component", never, {}, {}, never, never, false, never>;
}

Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,48 @@
}
],
"skipForTemplatePipeline": true
},
{
"description": "should generate a deferred block with triggers",
"angularCompilerOptions": {
"_enabledBlockTypes": ["defer"]
},
"inputFiles": [
"deferred_with_triggers.ts"
],
"expectations": [
{
"files": [
{
"expected": "deferred_with_triggers_template.js",
"generated": "deferred_with_triggers.js"
}
],
"failureMessage": "Incorrect template"
}
],
"skipForTemplatePipeline": true
},
{
"description": "should generate a deferred block with prefetch triggers",
"angularCompilerOptions": {
"_enabledBlockTypes": ["defer"]
},
"inputFiles": [
"deferred_with_prefetch_triggers.ts"
],
"expectations": [
{
"files": [
{
"expected": "deferred_with_prefetch_triggers_template.js",
"generated": "deferred_with_prefetch_triggers.js"
}
],
"failureMessage": "Incorrect template"
}
],
"skipForTemplatePipeline": true
}
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ MyApp.ɵcmp = /*@__PURE__*/ $r3$.ɵɵdefineComponent({
$r3$.ɵɵtext(1);
$r3$.ɵɵtemplate(2, MyApp_Defer_2_Template, 1, 0);
$r3$.ɵɵdefer(3, 2);
$r3$.ɵɵdeferOnIdle();
$r3$.ɵɵelementEnd();
}
if (rf & 2) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ MyApp.ɵcmp = /*@__PURE__*/ $r3$.ɵɵdefineComponent({
$r3$.ɵɵtemplate(4, MyApp_DeferPlaceholder_4_Template, 1, 0);
$r3$.ɵɵtemplate(5, MyApp_DeferError_5_Template, 3, 0);
$r3$.ɵɵdefer(6, 2, null, 3, 4, 5);
$r3$.ɵɵdeferOnIdle();
$r3$.ɵɵelementEnd();
}
if (rf & 2) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ MyApp.ɵcmp = /*@__PURE__*/ $r3$.ɵɵdefineComponent({
$r3$.ɵɵtemplate(2, MyApp_Defer_2_Template, 1, 0);
$r3$.ɵɵtemplate(3, MyApp_DeferLoading_3_Template, 1, 0);
$r3$.ɵɵdefer(4, 2, MyApp_Defer_4_DepsFn, 3);
$r3$.ɵɵdeferOnIdle();
$r3$.ɵɵelementEnd();
}
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ MyApp.ɵcmp = /*@__PURE__*/ $r3$.ɵɵdefineComponent({
$r3$.ɵɵtemplate(0, MyApp_Defer_0_Template, 1, 0);
$r3$.ɵɵtemplate(1, MyApp_DeferLoading_1_Template, 1, 0);
$r3$.ɵɵdefer(2, 0, null, 1, null, null, 0);
$r3$.ɵɵdeferOnIdle();
}
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ MyApp.ɵcmp = /*@__PURE__*/ $r3$.ɵɵdefineComponent({
$r3$.ɵɵtemplate(2, MyApp_Defer_2_Template, 1, 0);
$r3$.ɵɵtemplate(3, MyApp_DeferLoading_3_Template, 1, 0);
$r3$.ɵɵdefer(4, 2, MyApp_Defer_4_DepsFn, 3);
$r3$.ɵɵdeferOnIdle();
$r3$.ɵɵelementEnd();
}
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ MyApp.ɵcmp = /*@__PURE__*/ $r3$.ɵɵdefineComponent({
$r3$.ɵɵtemplate(0, MyApp_Defer_0_Template, 1, 0);
$r3$.ɵɵtemplate(1, MyApp_DeferPlaceholder_1_Template, 1, 0);
$r3$.ɵɵdefer(2, 0, null, null, 1, null, null, 0);
$r3$.ɵɵdeferOnIdle();
}
},
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import {Component} from '@angular/core';

@Component({
template: `
{{message}}
{#defer prefetch when isVisible() || isReady; prefetch on idle, timer(1337);
prefetch on immediate, hover; prefetch on interaction(button); prefetch on viewport(button)}
{{message}}
{:placeholder}<button #button>Click me</button>
{/defer}
`,
})
export class MyApp {
message = 'hello';
isReady = true;

isVisible() {
return false;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
function MyApp_Template(rf, ctx) {
if (rf & 1) {
$r3$.ɵɵtext(0);
$r3$.ɵɵtemplate(1, MyApp_Defer_1_Template, 1, 1);
$r3$.ɵɵtemplate(2, MyApp_DeferPlaceholder_2_Template, 3, 0);
$r3$.ɵɵdefer(3, 1, null, null, 2);
$r3$.ɵɵdeferOnIdle();
$r3$.ɵɵdeferPrefetchOnIdle();
$r3$.ɵɵdeferPrefetchOnImmediate();
$r3$.ɵɵdeferPrefetchOnTimer(1337);
$r3$.ɵɵdeferPrefetchOnHover();
$r3$.ɵɵdeferPrefetchOnInteraction("button");
$r3$.ɵɵdeferPrefetchOnViewport("button");
}
if (rf & 2) {
$r3$.ɵɵtextInterpolate1(" ", ctx.message, " ");
$r3$.ɵɵadvance(3);
$r3$.ɵɵdeferPrefetchWhen(ctx.isVisible() || ctx.isReady);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import {Component} from '@angular/core';

@Component({
template: `
{{message}}
{#defer when isVisible() || isReady; on idle, timer(1337); on immediate, hover;
on interaction(button); on viewport(button)}
{{message}}
{:placeholder}<button #button>Click me</button>
{/defer}
`,
})
export class MyApp {
message = 'hello';
isReady = true;

isVisible() {
return false;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
function MyApp_Template(rf, ctx) {
if (rf & 1) {
$r3$.ɵɵtext(0);
$r3$.ɵɵtemplate(1, MyApp_Defer_1_Template, 1, 1);
$r3$.ɵɵtemplate(2, MyApp_DeferPlaceholder_2_Template, 3, 0);
$r3$.ɵɵdefer(3, 1, null, null, 2);
$r3$.ɵɵdeferOnIdle();
$r3$.ɵɵdeferOnImmediate();
$r3$.ɵɵdeferOnTimer(1337);
$r3$.ɵɵdeferOnHover();
$r3$.ɵɵdeferOnInteraction("button");
$r3$.ɵɵdeferOnViewport("button");
}
if (rf & 2) {
$r3$.ɵɵtextInterpolate1(" ", ctx.message, " ");
$r3$.ɵɵadvance(3);
$r3$.ɵɵdeferWhen(ctx.isVisible() || ctx.isReady);
}
}
20 changes: 20 additions & 0 deletions packages/compiler/src/render3/r3_identifiers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,26 @@ export class Identifiers {
static templateCreate: o.ExternalReference = {name: 'ɵɵtemplate', moduleName: CORE};

static defer: o.ExternalReference = {name: 'ɵɵdefer', moduleName: CORE};
static deferWhen: o.ExternalReference = {name: 'ɵɵdeferWhen', moduleName: CORE};
static deferOnIdle: o.ExternalReference = {name: 'ɵɵdeferOnIdle', moduleName: CORE};
static deferOnImmediate: o.ExternalReference = {name: 'ɵɵdeferOnImmediate', moduleName: CORE};
static deferOnTimer: o.ExternalReference = {name: 'ɵɵdeferOnTimer', moduleName: CORE};
static deferOnHover: o.ExternalReference = {name: 'ɵɵdeferOnHover', moduleName: CORE};
static deferOnInteraction: o.ExternalReference = {name: 'ɵɵdeferOnInteraction', moduleName: CORE};
static deferOnViewport: o.ExternalReference = {name: 'ɵɵdeferOnViewport', moduleName: CORE};
static deferPrefetchWhen: o.ExternalReference = {name: 'ɵɵdeferPrefetchWhen', moduleName: CORE};
static deferPrefetchOnIdle:
o.ExternalReference = {name: 'ɵɵdeferPrefetchOnIdle', moduleName: CORE};
static deferPrefetchOnImmediate:
o.ExternalReference = {name: 'ɵɵdeferPrefetchOnImmediate', moduleName: CORE};
static deferPrefetchOnTimer:
o.ExternalReference = {name: 'ɵɵdeferPrefetchOnTimer', moduleName: CORE};
static deferPrefetchOnHover:
o.ExternalReference = {name: 'ɵɵdeferPrefetchOnHover', moduleName: CORE};
static deferPrefetchOnInteraction:
o.ExternalReference = {name: 'ɵɵdeferPrefetchOnInteraction', moduleName: CORE};
static deferPrefetchOnViewport:
o.ExternalReference = {name: 'ɵɵdeferPrefetchOnViewport', moduleName: CORE};

static text: o.ExternalReference = {name: 'ɵɵtext', moduleName: CORE};

Expand Down
Loading

0 comments on commit 5212b47

Please sign in to comment.