message: perf(ivy): guard listening to outputs with isDirectiveHost
  PR Close
diff: @@ -111,6 +111,7 @@ function listenerInternal(
  listenerFn: (e?: any) => any, useCapture = false,
  eventTargetResolver?: GlobalTargetResolver): void {
  const tView = lView[TVIEW];
  + const isTNodeDirectiveHost = isDirectiveHost(tNode);
  const firstTemplatePass = tView.firstTemplatePass;
  const tCleanup: false|any[] = firstTemplatePass && (tView.cleanup || (tView.cleanup = []));
  @@ -150,7 +151,7 @@ function listenerInternal(
  // Also, we don't have to search for existing listeners is there are no directives
  // matching on a given node as we can't register multiple event handlers for the same event in
  // a template (this would mean having duplicate attributes).
  - if (!eventTargetResolver && isDirectiveHost(tNode)) {
  + if (!eventTargetResolver && isTNodeDirectiveHost) {
  existingListener = findExistingListener(lView, eventName, tNode.index);
  }
  if (existingListener !== null) {
  @@ -185,6 +186,7 @@ function listenerInternal(
  }
  // subscribe to directive outputs
  + if (isTNodeDirectiveHost && processOutputs) {
  let outputs = tNode.outputs;
  if (outputs === undefined) {
  // if we create TNode here, inputs must be undefined so we know they still need to be
  @@ -193,7 +195,7 @@ function listenerInternal(
  }
  let props: PropertyAliasValue|undefined;
  - if (processOutputs && outputs !== null && (props = outputs[eventName])) {
  + if (outputs !== null && (props = outputs[eventName])) {
  const propsLength = props.length;
  if (propsLength) {
  const lCleanup = getCleanup(lView);
  @@ -217,6 +219,7 @@ function listenerInternal(
  }
  }
  }
  +}
  function executeListenerWithErrorHandling(
  lView: LView, listenerFn: (e?: any) => any, e: any): boolean {
  