Merge "Do not re-render a <gr-comment-thread> when the thread has not changed"
diff --git a/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread.ts b/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread.ts
index a895a5b..7a4b6f2 100644
--- a/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread.ts
+++ b/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread.ts
@@ -69,6 +69,7 @@
 import {classMap} from 'lit/directives/class-map';
 import {ShortcutController} from '../../lit/shortcut-controller';
 import {ValueChangedEvent} from '../../../types/events';
+import {notDeepEqual} from '../../../utils/deep-util';
 
 const NEWLINE_PATTERN = /\n/g;
 
@@ -112,8 +113,17 @@
   @queryAll('gr-comment')
   commentElements?: NodeList;
 
-  /** Required to be set by parent. */
-  @property()
+  /**
+   * Required to be set by parent.
+   *
+   * Lit's `hasChanged` change detection defaults to just checking strict
+   * equality (===). Here it makes sense to install a proper `deepEqual`
+   * check, because of how the comments-model and ChangeComments are setup:
+   * Each thread object is recreated on the slightest model change. So when you
+   * have 100 comment threads and there is an update to one thread, then you
+   * want to avoid re-rendering the other 99 threads.
+   */
+  @property({hasChanged: notDeepEqual})
   thread?: CommentThread;
 
   /**
diff --git a/polygerrit-ui/app/utils/deep-util.ts b/polygerrit-ui/app/utils/deep-util.ts
index ff19635..694a8d7 100644
--- a/polygerrit-ui/app/utils/deep-util.ts
+++ b/polygerrit-ui/app/utils/deep-util.ts
@@ -37,6 +37,10 @@
   return false;
 }
 
+export function notDeepEqual<T>(a: T, b: T): boolean {
+  return !deepEqual(a, b);
+}
+
 /**
  * @param obj Object
  */