published on February 26, 2024 in devlog
Michi is knee-deep in the process of preparing the admin centers to host the new government functionality. Instead of posting a work-in-progress devlog he writes about a curious bug, where a single misplaced parenthesis caused a lot of wasted CPU cycles.
Michi (molp)
By chance, I noticed a conversion in the in-game global com channel last week about the game's performance. A player reported that whenever they had the game open in their browser it would consume 100% of one of the CPU cores. Other players were quick to respond that the maps are a typical suspect for that kind of resource utilization. Sometimes browsers have the setting "hardware acceleration" set to disabled, which results in the CPU doing the work of the graphics card. This usually results in bad performance and a laggy game. The player however explained, that it wasn't that setting and that their screen doesn't even have a map on it. At this point I got curious and checked their account. To my surprise, I could reproduce the behavior and used Chrome's performance tools to record some data. The problem turned out to be in the countdown component. This component is used in almost all cases where we show a relative time, e.g. "in 5h 10m" or "10d 5h ago". Switching to a screen without any countdowns reduced the CPU load immediately.
I decided to try to find a fix for the problem immediately. This performance issue affected all players, at all times, even when they switched to a different tab. All those wasted CPU cycles! It turned out it was introduced with the Transmission release, and we didn't catch it during testing :/ I want to share the code with you for this one, since it is just a single misplaced character that caused the performance issue:
const [time, setTime] = useState(Date.now());
useEffect(() => {
const timer = setInterval(() => setTime(Date.now(), interval));
return () => {
clearInterval(timer);
};
}, [interval]);
In this part of the component we set up a javascript timer that updates a time field every interval-many milliseconds. The default is 60,000 milliseconds, for fast timers we use 1,000 milliseconds. Can you spot the error? This is the correct version:
const timer = setInterval(() => setTime(Date.now()), interval);
I misplaced the closing parenthesis for the setInterval, effectively removing the second parameter that defines the interval. The default interval for setInterval is one millisecond, so every instance of the countdown component was at least trying to a thousand times more work than it should!
As always: we'd love to hear what you think: join us on Discord or the forums!
Happy trading!