diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/internal/InternalEventListeners.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/internal/InternalEventListeners.kt
index fb604edaa..c09b5f303 100644
--- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/internal/InternalEventListeners.kt
+++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/internal/InternalEventListeners.kt
@@ -80,7 +80,25 @@ internal class Handler<in E : Event>
  */
 internal fun <E : Event> KClass<out E>.listeners(): EventListeners<E> = EventListenerManager.get(this)
 
-internal class EventListeners<E : Event> : LockFreeLinkedList<Listener<E>>()
+internal class EventListeners<E : Event>(clazz: KClass<E>) : LockFreeLinkedList<Listener<E>>() {
+    @Suppress("UNCHECKED_CAST")
+    val supertypes: Set<KClass<out Event>> by lazy {
+        val supertypes = mutableSetOf<KClass<out Event>>()
+
+        fun addSupertypes(clazz: KClass<out Event>) {
+            clazz.supertypes.forEach {
+                val classifier = it.classifier as? KClass<out Event>
+                if (classifier != null) {
+                    supertypes.add(classifier)
+                    addSupertypes(classifier)
+                }
+            }
+        }
+        addSupertypes(clazz)
+
+        supertypes
+    }
+}
 
 internal expect class MiraiAtomicBoolean(initial: Boolean) {
 
@@ -109,10 +127,10 @@ internal object EventListenerManager {
             }
         }
         if (lock.compareAndSet(false, true)) {
-            val registry = Registry(clazz, EventListeners())
+            val registry = Registry(clazz as KClass<E>, EventListeners(clazz))
             registries.addLast(registry)
             lock.value = false
-            return registry.listeners as EventListeners<E>
+            return registry.listeners
         }
         return get(clazz)
     }
@@ -125,19 +143,10 @@ internal suspend inline fun Event.broadcastInternal() {
 
     EventLogger.info { "Event broadcast: $this" }
 
-    callAndRemoveIfRequired(this::class.listeners())
-
-    var supertypes = this::class.supertypes
-    while (true) {
-        val superSubscribableType = supertypes.firstOrNull {
-            it.classifier as? KClass<out Event> != null
-        }
-
-        superSubscribableType?.let {
-            callAndRemoveIfRequired((it.classifier as KClass<out Event>).listeners())
-        }
-
-        supertypes = (superSubscribableType?.classifier as? KClass<*>)?.supertypes ?: return
+    val listeners = this::class.listeners()
+    callAndRemoveIfRequired(listeners)
+    listeners.supertypes.forEach {
+        callAndRemoveIfRequired(it.listeners())
     }
 }