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

View File

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