[HN Gopher] A 16.67 Millisecond Frame
       ___________________________________________________________________
        
       A 16.67 Millisecond Frame
        
       Author : luciodale
       Score  : 13 points
       Date   : 2025-10-08 10:01 UTC (1 days ago)
        
 (HTM) web link (koolcodez.com)
 (TXT) w3m dump (koolcodez.com)
        
       | luciodale wrote:
       | How do we even see anything on a browser? How do pixels turn into
       | shapes, color, and movement?
       | 
       | Every time we scroll, hover, or trigger an animation, the browser
       | goes through a whole routine. It calculates styles, figures out
       | layout, paints pixels, and puts everything together on screen.
       | All of that happens in just a few milliseconds.
       | 
       | It's kind of wild how much is happening behind what feels
       | instant. And the way we write code can make that process either
       | smooth and fluid or heavy and janky.
       | 
       | I wrote an article that walks through this step by step, with a
       | small demo showing exactly how these browser processes work and
       | how a few CSS choices can make a big difference.
        
         | johncolanduoni wrote:
         | A lot of these don't happen on scroll and hover under normal
         | circumstances. For example smooth scrolling on touchscreens is
         | implemented by only re-running the compositor on each frame,
         | and using the existing GPU-resident bitmap of the text being
         | scrolled. That's why non-passive onscroll callbacks make
         | scrolling suck, especially on mobile.
        
           | immibis wrote:
           | What's not stated, is that we used to re-render the text at
           | the bottom each time you scrolled up, and could still do it
           | pretty fast (not quite in 16.67 milliseconds but we could
           | have if computers had been today's speed), and in the
           | meantime, we seem to have forgotten how to do that. Although
           | we also have more pixels now, which probably changes things.
        
             | toast0 wrote:
             | > we used to re-render the text at the bottom each time you
             | scrolled up, and could still do it pretty fast
             | 
             | If you go back far enough, the IBM graphics cards used a
             | text mode where text was accelerated by the graphics card,
             | software would write a attribute byte and a data byte and
             | the card had a bitmapped font to render text. VGA text mode
             | at least could use hardware windowing so scrolling could
             | also be accelerated; not every system used it, but you can
             | set the start address and a line number where it returns to
             | the start of the data area. That makes it easy to scroll
             | without having to rewrite the screen buffer all at once.
             | (If you set the stride to something that evenly divides the
             | screen buffer and is at least as wide as your lines, it
             | makes things even easier)
        
         | vbezhenar wrote:
         | I think that many projects use wrong architecture, when it's a
         | possibility for business code to block animations.
         | 
         | IMO all the "user" code must run in a dedicated thread,
         | completely decoupled from the rendering loop. This code can
         | publish changes to a scene tree, performing changes, starting
         | animations, and so on, but these changes ultimately are
         | asynchronous. You want to delete an element from a webpage, but
         | it'll not be deleted at this JS line, it'll be deleted at the
         | next frame, or may be after that, if rendering thread is a bit
         | busy right now.
         | 
         | Animations must stay fluid and UI must react to the user input
         | instantly. FPS must not drop.
         | 
         | Browser does it wrong. Android GUI API does it wrong. World of
         | Warcraft addons do it wrong.
        
           | b_e_n_t_o_n wrote:
           | Multithreading in the browser kinda sucks though, it's too
           | slow to share significant data between workers (threads), and
           | if you try it with SharedArrayBuffer you eat the
           | serialisation costs.
        
           | gamer223 wrote:
           | I've only ever seen competitive video games get the
           | architecture right. They have the natural incentive of
           | needing stable high FPS.
           | 
           | Random GUI apps aren't incentivized enough and so garbage
           | leaks through. I die a bit every time a random GUI app
           | stutters drawing 2D boxes
        
           | Rohansi wrote:
           | That's basically what React Native does/did and it's
           | generally good but turns into a nightmare when you need to
           | synchronize interactions between the two threads. 16ms is a
           | long time - if your UI manipulations eat up most of that time
           | then there's something wrong. Entire video games can run
           | basically on one thread within that time and they do way
           | more.
        
           | simscitizen wrote:
           | Not really something anyone can change at this point, given
           | that the entire web API presumes an execution model where
           | everything logically happens on the main thread (and code can
           | and does expect to observe those state changes
           | synchronously).
        
           | AndriyKunitsyn wrote:
           | Which begs the question - if all of these projects got it
           | "wrong", what's the chance that the "right" thing isn't right
           | at all?
           | 
           | All animation is inherently discrete. No matter how many
           | threads you have, there always has to be the last rendering
           | thread, the thing that actually prepares the calls to the
           | rendering backend. It always has to have frames, and in every
           | frame, in the timestamp T, it will be interested in getting
           | the world state in the timestamp T. So, the things that work
           | on the world state - they have to prepare it as it was in T,
           | not earlier, not later. You cannot completely decouple it.
           | 
           | In one of game projects that I worked on, a physics thread
           | and a game thread actually were pretty decoupled, and what
           | the game thread did was extrapolating the world state from
           | the information provided by physics, because it knew not only
           | the positions of physics objects, but also their velocities.
           | Can we make every web developer to set velocities to the HTML
           | elements explicitly? Probably not.
        
         | AndriyKunitsyn wrote:
         | If that's wild to you, wait until you see video games.
        
       | don_neufeld wrote:
       | As an early 2000's game dev - I weep.
       | 
       | Scrolling? Animations? LOL.
        
       | ChuckMcM wrote:
       | This is both informative and kind of amazing that anything works
       | at all. Talk to anyone who did graphics at the turn of the
       | century and you'll hear about "racing the beam" which you had
       | only 16.67 mS before vertical retrace took you back to 0,0. Why
       | double and triple buffering was invented, and how "animation
       | time" is skewed by "frame time" and if you want to keep your
       | animations from jumping or jittering you really needed to know
       | how many milliseconds between the last frame and the one your
       | rendering will take so that all your assets are rendered where
       | they should be _at that time._
       | 
       | There is a lot of fun programming to be had in that space.
        
         | reactordev wrote:
         | We still race the beam, only on separate command chains. Across
         | threads. With 100x the vertices. It's still fun. Light,
         | shadows, volumes, SDRs, HDRIs, PBR, so much has been thoroughly
         | researched and standardized. We even have realistic clouds with
         | volume.
         | 
         | This is why I got into programming to begin with. Fun first,
         | visual second, technical challenges third, money fourth,
         | company last.
        
       | jimrandomh wrote:
       | This article says that using `transform` is faster than using
       | `left` and `top` because `transform` is handled on-GPU, while
       | `left` and `top` are not. This is a myth. I tried the demo page
       | in the Firefox profiler; neither the optimized nor the
       | unoptimized version missed frames. I tried it in the Chrome
       | profiler; the unoptimized version missed frames, but the time was
       | clearly labelled by the profiler as being GPU time, not reflow.
       | Neither browser did reflows (or, all reflows were fast enough to
       | not have any profiler-samples associated.)
       | 
       | The reality is that browsers contain large piles of heuristic
       | optimizations which defy simple explanation. You simply have to
       | profile and experiment, every time, separately.
        
         | MountDoom wrote:
         | This article is almost certainly AI-generated.
        
       ___________________________________________________________________
       (page generated 2025-10-09 23:00 UTC)