Performance Comparisons - TheMouseNest/Chattynator GitHub Wiki

Average time per message

Recorded over 100 messages and the mean taken. Determined by wrapping the message handler with a timer and filtering out any events that didn't start with CHAT_MSG.

This does not include any rendering costs outside those incurred during the :AddMessage call, e.g. fading/scrolling.

2025-06-13 (updated Chattynator height processing)

Chat UI Average
Prat 1.05ms
BasicChatMods 0.56ms
Chattynator 0.47ms
alaChat 0.42ms***
LS: Glass 0.33ms
Blizzard (processing) 0.26ms

2025-06-11

Chat UI Average
Prat 1.18ms
BasicChatMods 0.63ms
Chattynator 0.60ms
alaChat 0.42ms***
LS: Glass 0.32ms
Blizzard (processing) 0.27ms

*** disabled blocking repeated messages

Average time per frame

Due to message frequency varying at different times of days the performance times will vary a bit, the relative positions of numbers are the most important bit.

2025-06-10, 11:25-11:40 BST

Chat UI Average over 30s
BasicChatMods 0.130ms*
Prat 0.122ms*
LS: Glass 0.083ms
Chattynator 0.058ms
Blizzard (all) 0.053ms*
alaChat 0.052ms*
Blizzard (processing) 0.015ms**

2025-06-09, 22:00-22:20 BST

Chat UI Average over 30s
Prat 0.054ms*
BasicChatMods 0.051ms*
LS: Glass 0.049ms
Chattynator 0.033ms
Blizzard (all) 0.022ms*
Blizzard (processing) 0.008ms**

Notes

Used addon profiling tools where possible.

Measured over 30s, starting 30s after reloading the client. These times were all recorded on a busy Services channel at 60fps.

All of these addons will include "Blizzard (processing)" time to format the text in the messages.

Due to the profiler being unable to capture times

* measured by hooking Blizzard scroll frame and ChatFrame_OnEvent functions and averaging times elapsed.
** measured by hooking Blizzard ChatFrame_OnEvent function and averaging times elapsed.

Test harness for * and **

local elapsed = 0
local started = false
local oce = ChatFrame_OnEvent
ChatFrame_OnEvent = function(...)
	local start = debugprofilestop()
	oce(...)
	elapsed = elapsed + debugprofilestop() - start
	if not started then
		started = true
		C_Timer.After(30, function()
			elapsed = 0
			C_Timer.After(30, function()
				DevTool:AddData(elapsed / 30 / 60)
				elapsed = 0
			end)
		end)
	end
end
local oce = ChatFrame1.RefreshIfNecessary
ChatFrame1.RefreshIfNecessary = function(...)
  local start = debugprofilestop()
  oce(...)
  elapsed = elapsed + debugprofilestop() - start
end
local oce = ChatFrame1.UpdateFading
ChatFrame1.UpdateFading = function(...)
  local start = debugprofilestop()
  oce(...)
  elapsed = elapsed + debugprofilestop() - start
end
local oce = ChatFrame1.UpdateSelectingText
ChatFrame1.UpdateSelectingText = function(...)
  local start = debugprofilestop()
  oce(...)
  elapsed = elapsed + debugprofilestop() - start
end