게임이 시작되기 전에 플레이어가 떠나야 하는 이유

작성자

카테고리:

← 피드로
DEV Community · Liza Bhadana · 2026-08-03 개발(SW)

Your game is listed on a portal. The page gets visits. The play count does not move.

It is tempting to read that as a verdict on the game — but nobody who left ever played it. Whatever they rejected, they rejected before the game started.

This article measures that window on a live portal, in numbers.

The short version. On a portal, the first ten seconds of your game are not yours. The host’s CSS decides how large your game is. The host’s page decides how much of it is on screen. Your own first frame decides whether either of those mattered. I measured all three on a live site — ours — and found a game box 330 by 205 pixels on a phone, several seconds of black rectangle before anything was drawn, and a start button that landed at the bottom edge of a laptop viewport.

What I measured, and on what

Everything below was measured on 3 August 2026, in Chrome on Windows, against live pages on slowden.com. We are the portal in this article, which is rather the point: this is data a developer cannot normally get, because it belongs to the host — and it is easier to publish honestly when the embarrassing parts are your own.

Three games, none of them made by SlowDen:

  • Hedgies — a Playgama partner game by RedSpell, embedded in a cross-origin frame.
  • Snake 2048 — a Playgama partner game by TurtleGamesStudio, in the same container.
  • The Cube — the open-source Rubik’s-cube project by Boris Šehovac, self-hosted with credit rather than embedded. It appears here as the counter-example.

Layout was measured by loading each live page into a same-origin frame set to an exact viewport size and reading the real bounding boxes, rather than by eyeballing a browser window. Timings come from the Navigation Timing and Resource Timing APIs on the live pages. Byte sizes were re-fetched with cache: 'no-store' and measured from the response body, because a cached resource reports zero bytes in Resource Timing and would have made the totals look far better than they are.

Finding 1: the box is much smaller than you are designing for

The container is one line of CSS: a full-width box with a fixed 16:10 aspect ratio. That means the height of your game is decided entirely by how wide the page happens to be.

Here is the same game page at seven viewport sizes.

Viewport (CSS px) Game box Box height vs viewport Visible without scrolling Page above the game 360 × 740 299 × 186 25% 100% 284 px 390 × 844 330 × 205 24% 100% 260 px 412 × 915 351 × 219 24% 100% 260 px 768 × 1024 707 × 441 43% 100% 238 px 1366 × 768 1054 × 658 86% 79% 251 px 1536 × 695 1054 × 658 95% 67% 251 px 1920 × 1080 1054 × 658 61% 100% 251 px

Two things fall out of that table, and neither is obvious.

On a phone your game is a postage stamp. 330 by 205 CSS pixels is about a quarter of the screen. If your first frame carries a logo, a tagline, a difficulty selector and a start button, none of it is legible. Developers routinely build a title screen in a 1280 by 720 canvas and never look at it at 330 by 205 — but that is the size a large share of players will meet it at.

The worst clipping is not on mobile, it is on a laptop. At 1536 by 695 — an extremely common real-world viewport once browser chrome is subtracted — the box is 658 pixels tall and sits 251 pixels down the page, so a third of your game is below the fold on arrival. The phone cases were not clipped at all, because the box was too small to be clipped.

The design rule this implies. Your first frame has to work in a landscape box roughly 300 pixels wide, and it has to put anything important in the upper middle, because the bottom third may not be on screen. That is a much tighter brief than the one most title screens are designed to.

Finding 2: for the first several seconds the player sees a black rectangle

Here is the load sequence for one game page, taken from Navigation and Resource Timing on the live site:

Moment Time from navigation start Host page HTML finished arriving (13,371 bytes decoded) 154 ms Web fonts finished (5 requests, 98 KB) 323 ms Host page DOM complete 323 ms Game frame’s document finished arriving 1,260 ms Host page load event 1,264 ms

On a second game in the same container, the host page fired its load event at 726 ms while the game frame’s own resources were still landing at roughly 4.5 seconds.

So the host page is finished and painted in about a third of a second, and the game is not. What fills the gap is a black box. I reloaded both pages repeatedly and screenshotted: immediately after load, the game area was a solid black rectangle with no play control anywhere on the page, and the partner player’s own splash screen appeared only several seconds later.

You cannot remove that window. You can decide what is in it. A first frame that draws a background colour, the game’s name and a progress indicator within a few hundred milliseconds is doing something no host can do for you, because the host cannot see inside your frame.

Finding 3: your start button is not where you think it is

You choose where the start control sits inside your frame. The host chooses where the frame sits on the page. Nobody reconciles those two decisions, and the result is measurable.

Two games, same container, same portal, same viewport of 1568 by 688:

  • Snake 2048 renders Tap to start near the vertical centre of the frame. It landed around y=590, comfortably on screen. This one works.
  • Hedgies renders its Let’s Play! button low in the frame. It landed at the very bottom edge of the viewport, clipped by the fold. A visitor who does not scroll never sees the control that starts the game.

Neither studio did anything wrong. Both start screens are perfectly sensible in isolation. The failure only exists in combination — and the combination is the only thing the player ever experiences.

What we changed on our side. Publishing this without saying what we did with it would be cheap. Our game pages now paint their own thumbnail and a real play button immediately, and create the game frame only when someone clicks it, so the page can never again show a black box with no control on it. That change is in our source and is not deployed as of this article’s publication date — the pages measured above are still live in the state described. I am not going to pretend otherwise.

Finding 4: the page around your game spends the budget first

On the page measured above, the host’s own HTML was 13,371 bytes. Its web fonts were 98 KB across five requests. Those fonts were fully downloaded at 323 ms; the game’s frame document did not finish until 1,260 ms.

You do not control that and you should not try to. But it is worth knowing, because it changes what your own budget is for. The player’s patience is being spent on the portal’s furniture before your first byte arrives, and whatever you were planning to spend on a splash animation is coming out of what is left.

A counter-example, on the same site

The Cube is not embedded — it is self-hosted on the same domain — so it is not a like-for-like comparison, and it is included for one specific reason: it shows what a fast first frame is actually made of.

File Bytes (decoded, re-fetched with no-store) index.html 7,144 style.css 35,932 js.js (the whole game) 101,851 three.min.js (from a CDN) 646,271 Total 791,198 ≈ 773 KB

DOM complete at 292 ms, load event at 303 ms. What lands on screen is a finished, readable frame: the title, a rendered 3D cube, and the words Double tap to start. Four files, no loading bar, nothing to wait for — and note that 82 percent of those bytes are the 3D engine, not the game. The game itself is 102 KB.

The lesson is not “be under 800 KB”. It is that a first frame worth showing can be very cheap, and that shipping one is a decision rather than a budget.

Seven things to do about it

  1. Open your own title screen at 330 by 205 and look at it. Not a mock-up — the real build, at that size. This takes two minutes and is the single highest-value item on this list.
  2. Draw something in the first frame. A background colour and the game’s name beats black. If you have a preload step, draw before you preload, not after.
  3. Put the start control in the upper middle of your frame. The bottom third can be below the host’s fold; the top is always on screen.
  4. Show progress if loading exceeds about a second. A bar that moves converts waiting into waiting-for-something. A static black box converts it into leaving.
  5. Do not gate the first frame on audio. Audio starts suspended until the player interacts, so anything waiting on an audio context will wait forever on load.
  6. Size your canvas after layout, not before. A canvas measured before the frame has its final box gets zero or a stale size, and then renders into the wrong dimensions.
  7. Re-test after every portal listing. The container is the host’s and it can change without telling you.

Test your own game in ten minutes

Open the portal page that hosts your game, open the console, and paste this. It measures the page rather than guessing at it.

// Paste into the console on the page that EMBEDS your game.
const f = document.querySelector('iframe');
const r = f.getBoundingClientRect();
const nav = performance.getEntriesByType('navigation')[0];

console.table({
  'viewport'          : innerWidth + ' x ' + innerHeight,
  'your game box'     : Math.round(r.width) + ' x ' + Math.round(r.height),
  'page above game'   : Math.round(r.top) + ' px',
  'visible on arrival': Math.round(100 * Math.max(0,
      Math.min(r.bottom, innerHeight) - Math.max(r.top, 0)) / r.height) + '%',
  'scroll to see all' : Math.max(0, Math.round(r.bottom - innerHeight)) + ' px',
  'host DOM done'     : Math.round(nav.domContentLoadedEventEnd) + ' ms',
  'host load event'   : Math.round(nav.loadEventEnd) + ' ms',
  'lazy loaded'       : f.getAttribute('loading') || 'no'
});

// When did YOUR frame's document actually arrive?
performance.getEntriesByType('resource')
  .filter(x => x.name.includes(new URL(f.src).host))
  .forEach(x => console.log(Math.round(x.responseEnd) + ' ms', x.name.split('?')[0]));

Enter fullscreen mode Exit fullscreen mode

Run it at a few widths — drag the window narrow, then wide — because the layout changes and the clipping is worst at sizes you would not think to check. If visible on arrival is under 100%, work out what is in the missing part.

Where these numbers came from

  • When and where: 3 August 2026, Chrome on Windows, against live pages on slowden.com. Every figure above is a reading, not an estimate.
  • Viewport table: produced by loading each live page into a same-origin frame of the stated size and reading real bounding boxes. This measures CSS layout faithfully, but it is not a phone: there is no mobile user-agent, no device pixel ratio, and no collapsing address bar. Treat the mobile rows as the layout a phone-width viewport produces, not as a device test.
  • Timings: Navigation Timing and Resource Timing on the live pages. I could not measure first paint: the automated tab loads in the background, and Chrome does not record paint timing for a page that was never visible. Every timing quoted is therefore a network or DOM milestone, and none is presented as a paint time.
  • Inside the frame is invisible to me. The game frame is cross-origin, so I can see when its document arrived but not what it drew. The claims about black rectangles and start-button positions come from screenshots of the rendered page, not from reading the frame.
  • Byte sizes: re-fetched with cache: 'no-store' and measured from the response body, so they are decoded sizes. On the wire they are compressed and smaller.
  • One browser. Chrome only. Do not assume Safari or Firefox behave identically without testing.
  • Credits: Hedgies is by RedSpell and Snake 2048 by TurtleGamesStudio, both listed on SlowDen through Playgama. The Cube is by Boris Šehovac, open source, hosted with credit. Most games listed on SlowDen are partner or third-party titles rather than SlowDen’s own work. Playgama, Chrome and Three.js are named for accuracy only; no affiliation or endorsement is implied.

If you make browser games

SlowDen lists browser games and takes submissions from developers. If you have a playable web build, you can send it to us.

Slow Cook is our creative challenge for developers: pick a challenge, build a small game around it, submit it before the round closes on 31 August 2026. Selected entries may receive a shoutout on SlowDen’s social accounts and a chance to be featured — nothing is guaranteed, and every entry is read by a person.

Related, if this was useful: Why your browser game loads to a black screen takes the same failure apart from inside one game, with a 203 MB preload queue. And Which browser-game portals actually have players on them covers where to list once the first ten seconds work.

Written for the SlowDen blog: https://slowden.com/blog/

원문에서 계속 ↗

코멘트

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다