--- title: "Anatomy of a video game - Game development | MDN" chunk: 5/6 source: "https://developer.mozilla.org/en-US/docs/Games/Anatomy" category: "reference" tags: "web, html, css, javascript, documentation" date_saved: "2026-05-05T05:20:51.278426+00:00" instance: "kb-cron" --- ### [Other ways to handle variable refresh rate needs](https://developer.mozilla.org/en-US/docs/Games/Anatomy#other_ways_to_handle_variable_refresh_rate_needs) Other methods of tackling the problem exist. One common technique is to update the simulation at a constant frequency and then draw as much (or as little) of the actual frames as possible. The update method can continue looping without care about what the user sees. The draw method can view the last update and when it happened. Since draw knows when it represents, and the simulation time for the last update, it can predict a plausible frame to draw for the user. It does not matter whether this is more frequent than the official update loop (or even less frequent). The update method sets checkpoints and, as frequently as the system allows, the render method draws instants of time around them. There are many ways to separate the update method in web standards: * Draw on `requestAnimationFrame()` and update on a [`setInterval()`](https://developer.mozilla.org/en-US/docs/Web/API/Window/setInterval "setInterval\(\)") or [`setTimeout()`](https://developer.mozilla.org/en-US/docs/Web/API/Window/setTimeout "setTimeout\(\)"). * This uses processor time even when unfocused or minimized, hogs the main thread, and is probably an artifact of traditional game loops (but it is simple.) * Draw on `requestAnimationFrame()` and update on a [`setInterval()`](https://developer.mozilla.org/en-US/docs/Web/API/WorkerGlobalScope/setInterval "setInterval\(\)") or [`setTimeout()`](https://developer.mozilla.org/en-US/docs/Web/API/WorkerGlobalScope/setTimeout "setTimeout\(\)") in a [Web Worker](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers). * This is the same as above, except update does not hog the main thread (nor does the main thread hog it). This is a more complex solution, and might be too much overhead for simple updates. * Draw on `requestAnimationFrame()` and use it to poke a Web Worker containing the update method with the number of ticks to compute, if any. * This sleeps until `requestAnimationFrame()` is called and does not pollute the main thread, plus you are not relying on old-fashioned methods. Again, this is a bit more complex than the previous two options, and _starting_ each update will be blocked until the browser decides to fire rAF callbacks. Each of these methods have similar tradeoffs: * Users can skip rendering frames or interpolate extra ones depending on their performance. * You can count on all users updating non-cosmetic variables at the same constant frequency minus hiccups. * Much more complicated to program than the basic loops we saw earlier. * User input is completely ignored until the next update (even if the user has a fast device). * The mandatory interpolation has a performance penalty. A separate update and draw method could look like the following example. For the sake of demonstration, the example is based on the third bullet point, just without using Web Workers for readability (and, let's be honest, writability). **Warning:** This example, specifically, is in need of technical review. Another alternative is to do certain things less often. If a portion of your update loop is difficult to compute but insensitive to time, you might consider scaling back its frequency and, ideally, spreading it out into chunks throughout that lengthened period. An implicit example of this was found over at The Artillery Blog for Artillery Games, where they [adjust their rate of garbage generation](https://web.archive.org/web/20161021030645/http://blog.artillery.com/2012/10/browser-garbage-collection-and-framerate.html) to optimize garbage collection. Obviously, cleaning up resources is not time sensitive (especially if tidying is more disruptive than the garbage itself). This may also apply to some of your own tasks. Those are good candidates to throttle when available resources become a concern. ## [Summary](https://developer.mozilla.org/en-US/docs/Games/Anatomy#summary) I want to be clear that any of the above, or none of them, could be best for your game. The correct decision entirely depends on the trade-offs that you are willing (and unwilling) to make. The concern is mostly with switching to another option. Fortunately, I do not have any experience with this, but I have heard it is an excruciating exercise in chasing regressions. An important thing to remember for managed platforms, like the web, is that your loop may stop execution for significant periods of time. This could occur when the user unselects your tab and the browser sleeps (or slows) its `requestAnimationFrame` callback interval. You have many ways to deal with this situation and this could depend on whether your game is single player or multiplayer. Some choices are: * Consider the gap "a pause" and skip the time. * You can probably see how this is problematic for most multiplayer games. * You can simulate the gap to catch up. * This can be a problem for long drops and/or complex updates. * You can recover the game state from a peer or the server. * This is ineffective if your peers or server are out-of-date too, or they don't exist because the game is single player and doesn't have a server.