perf(ivy): move attributes array into component def (#32798)
Currently Ivy stores the element attributes into an array above the component def and passes it into the relevant instructions, however the problem is that upon minification the array will get a unique name which won't compress very well. These changes move the attributes array into the component def and pass in the index into the instructions instead. Before: ``` const _c0 = ['foo', 'bar']; SomeComp.ngComponentDef = defineComponent({ template: function() { element(0, 'div', _c0); } }); ``` After: ``` SomeComp.ngComponentDef = defineComponent({ consts: [['foo', 'bar']], template: function() { element(0, 'div', 0); } }); ``` A couple of cases that this PR doesn't handle: * Template references are still in a separate array. * i18n attributes are still in a separate array. PR Close #32798
This commit is contained in:

committed by
Alex Rickabaugh

parent
b2b917d2d8
commit
d5b87d32b0
@ -13,7 +13,7 @@ import {TemplateRef} from '@angular/core/src/linker/template_ref';
|
||||
import {ViewContainerRef} from '@angular/core/src/linker/view_container_ref';
|
||||
import {Renderer2} from '@angular/core/src/render/api';
|
||||
import {createLView, createTView, getOrCreateTNode, getOrCreateTView, renderComponentOrTemplate} from '@angular/core/src/render3/instructions/shared';
|
||||
import {TNodeType} from '@angular/core/src/render3/interfaces/node';
|
||||
import {TAttributes, TNodeType} from '@angular/core/src/render3/interfaces/node';
|
||||
import {getLView, resetComponentState, selectView} from '@angular/core/src/render3/state';
|
||||
import {stringifyElement} from '@angular/platform-browser/testing/src/browser_util';
|
||||
|
||||
@ -100,10 +100,10 @@ export class TemplateFixture extends BaseFixture {
|
||||
* `if (rf & RenderFlags.Update) { __here__ }`.
|
||||
*/
|
||||
constructor(
|
||||
private createBlock: () => void, private updateBlock: () => void = noop, consts: number = 0,
|
||||
private createBlock: () => void, private updateBlock: () => void = noop, decls: number = 0,
|
||||
private vars: number = 0, directives?: DirectiveTypesOrFactory|null,
|
||||
pipes?: PipeTypesOrFactory|null, sanitizer?: Sanitizer|null,
|
||||
rendererFactory?: RendererFactory3) {
|
||||
rendererFactory?: RendererFactory3, private _consts?: TAttributes[]) {
|
||||
super();
|
||||
this._directiveDefs = toDefs(directives, extractDirectiveDef);
|
||||
this._pipeDefs = toDefs(pipes, extractPipeDef);
|
||||
@ -119,8 +119,8 @@ export class TemplateFixture extends BaseFixture {
|
||||
this.updateBlock();
|
||||
}
|
||||
},
|
||||
consts, vars, null !, this._rendererFactory, null, this._directiveDefs, this._pipeDefs,
|
||||
sanitizer);
|
||||
decls, vars, null !, this._rendererFactory, null, this._directiveDefs, this._pipeDefs,
|
||||
sanitizer, this._consts);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -131,7 +131,8 @@ export class TemplateFixture extends BaseFixture {
|
||||
update(updateBlock?: () => void): void {
|
||||
renderTemplate(
|
||||
this.hostElement, updateBlock || this.updateBlock, 0, this.vars, null !,
|
||||
this._rendererFactory, this.hostView, this._directiveDefs, this._pipeDefs, this._sanitizer);
|
||||
this._rendererFactory, this.hostView, this._directiveDefs, this._pipeDefs, this._sanitizer,
|
||||
this._consts);
|
||||
}
|
||||
|
||||
destroy(): void {
|
||||
@ -236,24 +237,25 @@ export function resetDOM() {
|
||||
*
|
||||
* @param hostNode Existing node to render into.
|
||||
* @param templateFn Template function with the instructions.
|
||||
* @param consts The number of nodes, local refs, and pipes in this template
|
||||
* @param decls The number of nodes, local refs, and pipes in this template
|
||||
* @param context to pass into the template.
|
||||
* @param providedRendererFactory renderer factory to use
|
||||
* @param host The host element node to use
|
||||
* @param directives Directive defs that should be used for matching
|
||||
* @param pipes Pipe defs that should be used for matching
|
||||
* @param consts Constants associated with the template.
|
||||
*/
|
||||
export function renderTemplate<T>(
|
||||
hostNode: RElement, templateFn: ComponentTemplate<T>, consts: number, vars: number, context: T,
|
||||
hostNode: RElement, templateFn: ComponentTemplate<T>, decls: number, vars: number, context: T,
|
||||
providedRendererFactory: RendererFactory3, componentView: LView | null,
|
||||
directives?: DirectiveDefListOrFactory | null, pipes?: PipeDefListOrFactory | null,
|
||||
sanitizer?: Sanitizer | null): LView {
|
||||
sanitizer?: Sanitizer | null, consts?: TAttributes[]): LView {
|
||||
if (componentView === null) {
|
||||
resetComponentState();
|
||||
const renderer = providedRendererFactory.createRenderer(null, null);
|
||||
|
||||
// We need to create a root view so it's possible to look up the host element through its index
|
||||
const tView = createTView(-1, null, 1, 0, null, null, null, null);
|
||||
const tView = createTView(-1, null, 1, 0, null, null, null, null, null);
|
||||
const hostLView = createLView(
|
||||
null, tView, {}, LViewFlags.CheckAlways | LViewFlags.IsRoot, null, null,
|
||||
providedRendererFactory, renderer);
|
||||
@ -263,8 +265,9 @@ export function renderTemplate<T>(
|
||||
selectors: [],
|
||||
type: Object,
|
||||
template: templateFn,
|
||||
consts: consts,
|
||||
decls: decls,
|
||||
vars: vars,
|
||||
consts: consts,
|
||||
});
|
||||
def.directiveDefs = directives || null;
|
||||
def.pipeDefs = pipes || null;
|
||||
@ -285,12 +288,14 @@ export function renderTemplate<T>(
|
||||
* @deprecated use `TemplateFixture` or `ComponentFixture`
|
||||
*/
|
||||
export function renderToHtml(
|
||||
template: ComponentTemplate<any>, ctx: any, consts: number = 0, vars: number = 0,
|
||||
template: ComponentTemplate<any>, ctx: any, decls: number = 0, vars: number = 0,
|
||||
directives?: DirectiveTypesOrFactory | null, pipes?: PipeTypesOrFactory | null,
|
||||
providedRendererFactory?: RendererFactory3 | null, keepNgReflect = false) {
|
||||
providedRendererFactory?: RendererFactory3 | null, keepNgReflect = false,
|
||||
consts?: TAttributes[]) {
|
||||
hostView = renderTemplate(
|
||||
containerEl, template, consts, vars, ctx, providedRendererFactory || testRendererFactory,
|
||||
hostView, toDefs(directives, extractDirectiveDef), toDefs(pipes, extractPipeDef));
|
||||
containerEl, template, decls, vars, ctx, providedRendererFactory || testRendererFactory,
|
||||
hostView, toDefs(directives, extractDirectiveDef), toDefs(pipes, extractPipeDef), null,
|
||||
consts);
|
||||
return toHtml(containerEl, keepNgReflect);
|
||||
}
|
||||
|
||||
@ -362,24 +367,26 @@ export function toHtml<T>(componentOrElement: T | RElement, keepNgReflect = fals
|
||||
}
|
||||
|
||||
export function createComponent(
|
||||
name: string, template: ComponentTemplate<any>, consts: number = 0, vars: number = 0,
|
||||
name: string, template: ComponentTemplate<any>, decls: number = 0, vars: number = 0,
|
||||
directives: DirectiveTypesOrFactory = [], pipes: PipeTypesOrFactory = [],
|
||||
viewQuery: ComponentTemplate<any>| null = null, providers: Provider[] = [],
|
||||
viewProviders: Provider[] = [], hostBindings?: HostBindingsFunction<any>): ComponentType<any> {
|
||||
viewProviders: Provider[] = [], hostBindings?: HostBindingsFunction<any>,
|
||||
consts: TAttributes[] = []): ComponentType<any> {
|
||||
return class Component {
|
||||
value: any;
|
||||
static ngFactoryDef = () => new Component;
|
||||
static ngComponentDef = ɵɵdefineComponent({
|
||||
type: Component,
|
||||
selectors: [[name]],
|
||||
consts: consts,
|
||||
decls: decls,
|
||||
vars: vars,
|
||||
template: template,
|
||||
viewQuery: viewQuery,
|
||||
directives: directives, hostBindings,
|
||||
pipes: pipes,
|
||||
features: (providers.length > 0 || viewProviders.length > 0)?
|
||||
[ɵɵProvidersFeature(providers || [], viewProviders || [])]: []
|
||||
[ɵɵProvidersFeature(providers || [], viewProviders || [])]: [],
|
||||
consts: consts,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
Reference in New Issue
Block a user