Skip to content
YiBoard
Play

2026-10-19

Performance Work: A Smoother Board

Nobody asks for performance work, and everybody notices when it is missing. This is the YiBoard list: four numbers from a mid-range Android phone, why the board moved from 225 DOM nodes to one canvas, how the 500ms engine budget stopped freezing the board, and the optimizations we turned down.

#performance#engineering#roadmap

Game performance optimization is the kind of work nobody asks for and everybody notices when it is missing. On YiBoard it comes down to a few concrete numbers: how long the board takes to draw, how long a tap takes to become a stone, and whether the picture stays smooth while the engine is searching. Below are the measurements from a 2021 mid-range Android phone on throttled 4G, the changes that came out of them, and the optimizations we turned down. Place a few stones on the play page at yiboardgame.com first and the numbers will read differently.

The numbers we started from

We tested on a 2021 mid-range Android phone over a throttled 4G connection, because that is closer to our actual traffic than a laptop on fibre. Before any changes, the board took 380ms to first paint, an average move appeared 140ms after the tap, and the frame rate dropped to 41fps during the 500ms engine search. None of those numbers make the game unplayable. Together they make it feel cheaper than the work that went into it.

  • First paint of the board: 380ms on throttled 4G
  • Tap to stone on screen: 140ms average
  • Frame rate during engine search: 41fps
  • Payload before the first stone can be placed: 214KB gzipped

Board rendering optimization: one canvas instead of 225 divs

The first board was 225 DOM nodes, one per intersection, with the grid drawn as CSS borders. It was easy to style and it fell apart the moment the browser had to repaint. We moved the grid and the stones onto a single canvas and kept the DOM for the interface around the board. Redrawing a stone is now a clipped repaint of one cell rather than a layout pass over the whole board. That change took first paint from 380ms to 190ms, and it is one of the reasons we do not animate stone drops.

Web game performance and the 500ms engine budget

The gomoku engine runs alpha-beta in the browser on a 500ms budget. Written the obvious way, it eats the main thread for the whole half second, so we moved the search into a worker and let the board keep drawing while the engine thinks. When the position is already settled we cap the depth instead of the time. The search itself is described in the engine write-up. On that Android phone the frame rate during search went from 41 to 58, and the board no longer freezes just before the reply lands.

What a lag free game still owes the network

Every move goes to the server for validation. That is why cheating does not work here, and it is also why latency is impossible to hide. We replaced one request per move with a single reused connection, and we let your own stone appear locally before the server confirms it. If the server rejects the move, the stone is taken back and you are told why. A wrong guess costs one animation, while waiting for a round trip on every move costs the whole match.

  • One reused connection per match, not one request per move
  • Your stone appears locally first, server confirmation second
  • Reconnect replays the move log instead of restarting the match
  • No background polling for the leaderboard while a match is open

Optimizations we turned down

  • No animated stone drops. They look good in a screenshot and make a fast game feel slow
  • No prefetching the likely reply. Guessing wrong is worse than waiting another 40ms
  • No WebGL board. A 2D canvas draws a 15x15 grid at a full 60fps without a shader
  • No service worker caching of match state. A board showing the wrong position is worse than a slow one

FAQ

Does the board still stutter while the AI thinks?

It did before this round of work. The search now runs in a worker, and the board holds 58fps on the mid-range phone we test with. On a desktop browser you would not have noticed either way.

How much mobile data does YiBoard use?

About 214KB gzipped before you can place your first stone, and nothing after that apart from the moves themselves. There are no ads, no tracking scripts and no analytics bundles riding along.

With a worker and a server, can it really stay free?

Yes. Free is a design choice here, not a trial period. The engine runs on your own device, which is why we can keep the server cheap.

Do older phones get these improvements?

Most of them, with one exception: the worker needs a browser from roughly 2018 or later. Anything older falls back to the main thread, plays the same game, and keeps the old stutter.

Play a game at yiboardgame.com

Related

explore.title

YiBoard (yiboardgame.com) — 中华棋类,浏览器即玩,免费无注册。 去下一局 · 更多博客 · 玩法指南