perf(ivy): avoid unnecessary i18n pass while processing a template (#33284)

Prior to this commit, we always invoked second i18n pass (in case whitespace removal is on, which is a default), even if a given template doesn't contain i18n information. Now we store a flag (that indicates presence of i18n information in a template) during first i18n pass and use it to check whether second pass is needed.

PR Close #33284
This commit is contained in:
Andrew Kushnir 2019-10-20 22:14:34 -07:00 committed by Matias Niemelä
parent 5d86e4a9b1
commit 7f7dc7c294
2 changed files with 16 additions and 9 deletions

View File

@ -44,6 +44,9 @@ const setI18nRefs: VisitNodeFn = (htmlNode, i18nNode) => {
* stored with other element's and attribute's information. * stored with other element's and attribute's information.
*/ */
export class I18nMetaVisitor implements html.Visitor { export class I18nMetaVisitor implements html.Visitor {
// whether visited nodes contain i18n information
public hasI18nMeta: boolean = false;
// i18n message generation factory // i18n message generation factory
private _createI18nMessage = createI18nMessageFactory(this.interpolationConfig); private _createI18nMessage = createI18nMessageFactory(this.interpolationConfig);
@ -63,6 +66,7 @@ export class I18nMetaVisitor implements html.Visitor {
visitElement(element: html.Element): any { visitElement(element: html.Element): any {
if (hasI18nAttrs(element)) { if (hasI18nAttrs(element)) {
this.hasI18nMeta = true;
const attrs: html.Attribute[] = []; const attrs: html.Attribute[] = [];
const attrsMeta: {[key: string]: string} = {}; const attrsMeta: {[key: string]: string} = {};
@ -111,6 +115,7 @@ export class I18nMetaVisitor implements html.Visitor {
visitExpansion(expansion: html.Expansion, currentMessage: i18n.Message|undefined): any { visitExpansion(expansion: html.Expansion, currentMessage: i18n.Message|undefined): any {
let message; let message;
const meta = expansion.i18n; const meta = expansion.i18n;
this.hasI18nMeta = true;
if (meta instanceof i18n.IcuPlaceholder) { if (meta instanceof i18n.IcuPlaceholder) {
// set ICU placeholder name (e.g. "ICU_1"), // set ICU placeholder name (e.g. "ICU_1"),
// generated while processing root element contents, // generated while processing root element contents,

View File

@ -1965,20 +1965,22 @@ export function parseTemplate(
// before we run whitespace removal process, because existing i18n // before we run whitespace removal process, because existing i18n
// extraction process (ng xi18n) relies on a raw content to generate // extraction process (ng xi18n) relies on a raw content to generate
// message ids // message ids
rootNodes = html.visitAll( const i18nMetaVisitor = new I18nMetaVisitor(
new I18nMetaVisitor(interpolationConfig, !preserveWhitespaces, i18nLegacyMessageIdFormat), interpolationConfig, /* keepI18nAttrs */ !preserveWhitespaces, i18nLegacyMessageIdFormat);
rootNodes); rootNodes = html.visitAll(i18nMetaVisitor, rootNodes);
if (!preserveWhitespaces) { if (!preserveWhitespaces) {
rootNodes = html.visitAll(new WhitespaceVisitor(), rootNodes); rootNodes = html.visitAll(new WhitespaceVisitor(), rootNodes);
// run i18n meta visitor again in case we remove whitespaces, because // run i18n meta visitor again in case whitespaces are removed (because that might affect
// that might affect generated i18n message content. During this pass // generated i18n message content) and first pass indicated that i18n content is present in a
// i18n IDs generated at the first pass will be preserved, so we can mimic // template. During this pass i18n IDs generated at the first pass will be preserved, so we can
// existing extraction process (ng xi18n) // mimic existing extraction process (ng xi18n)
if (i18nMetaVisitor.hasI18nMeta) {
rootNodes = html.visitAll( rootNodes = html.visitAll(
new I18nMetaVisitor(interpolationConfig, /* keepI18nAttrs */ false), rootNodes); new I18nMetaVisitor(interpolationConfig, /* keepI18nAttrs */ false), rootNodes);
} }
}
const {nodes, errors, styleUrls, styles} = htmlAstToRender3Ast(rootNodes, bindingParser); const {nodes, errors, styleUrls, styles} = htmlAstToRender3Ast(rootNodes, bindingParser);
if (errors && errors.length > 0) { if (errors && errors.length > 0) {