JavaScript counters the hard way - HTTP 203

Поділитися
Вставка
  • Опубліковано 24 сер 2024
  • You’ve seen loads of counter tutorials online, but they’re all a bit wrong… or at least most of them are. Jake and Surma dissect different techniques and identify how to make the counter work accurately and efficiently across browsers.
    The optimal reusable solution → goo.gle/2LY9GNI
    Browser bugs for suboptimal CSS animations:
    Chrome (empty JS anim) → goo.gle/3qS3vt7
    Chrome (other animations) → goo.gle/39izDjS
    WebKit → goo.gle/2Mnkt3F
    Mozilla → goo.gle/2Nt4T74
    Other videos in the series → goo.gle/2wneQLl
    Subscribe to Google Chrome Developers here → goo.gle/Chrome...
    Also, if you enjoyed this, you might like the HTTP203 podcast! → goo.gle/2y0I5Uo

КОМЕНТАРІ • 179

  • @ChromeDevs
    @ChromeDevs  3 роки тому +110

    Hey, you cared enough to scroll down to the comments! At this point you might as well subscribe.

    • @TheRealCAPerry
      @TheRealCAPerry 3 роки тому +1

      How d'you think I got here?

    • @ColinRichardson
      @ColinRichardson 3 роки тому

      @spYro double subscribe! I hear you need to SMASH the button

    • @Khobalt664
      @Khobalt664 3 роки тому

      Yeah, we're going to need an else clause. We programmers generally spend much time with interpreters and compilers and are therefore fastidious.

    • @ajhalili2006
      @ajhalili2006 3 роки тому

      My UA-cam recommendations sent me here, even the algorithms looks broken for some people.

    • @Stoney_Eagle
      @Stoney_Eagle 3 роки тому

      THE perfect way to use the pinned comment!

  • @Netrole
    @Netrole 3 роки тому +62

    This is the only channel, where a seasoned javascript developer can still learn something in a basic counter tutorial. Very well done, and so incredibly informative.

    • @jakearchibald
      @jakearchibald 3 роки тому +4

      Thank you! Glad it's interesting & useful

  • @cintron3d
    @cintron3d 3 роки тому +160

    Taking simple things and making them complicated - exactly why I'm here. I don't just want to get stuff done. I want to get it done right, and understand why it's right 👍
    Kudos for making such excellent content!

  • @sjorsborsoborsobors
    @sjorsborsoborsobors 3 роки тому +61

    If I ever get asked to implement a counter during a job interview I'm hitting them with this bad boy.

  • @NateLevin
    @NateLevin 3 роки тому +80

    You might not be getting the billions of views, but the videos you do make are always great!

    • @TheNewton
      @TheNewton 3 роки тому +2

      Though work like this does end up *affecting* billions of views of webpages when it becomes standard in libraries, Frameworks and tutorials.

  • @MaxArt2501
    @MaxArt2501 3 роки тому +10

    Fun fact: you can clear a setInterval using clearTimeout.
    Because, as Surma said, setInterval is literally setTimeout that schedules itself.

  • @mathisbullinger45
    @mathisbullinger45 3 роки тому +40

    Thanks for complicating. Without it, I wouldn't have known about CSS steps() function being a thing.

  • @juliohintze595
    @juliohintze595 3 роки тому +14

    Beginners tutorial: how to build a counter
    Advanced tutorial: how to (not?) build a counter

  • @albertodeagostini6143
    @albertodeagostini6143 3 роки тому +1

    This is the hardest thing to do with a seemingly simple task I've ever seen, congratulations. I loved it

  • @akshitkrnagpal
    @akshitkrnagpal 3 роки тому +12

    Now I know how should I build a counter.
    Thank you.

  • @stenalpjolly
    @stenalpjolly 3 роки тому +7

    @Jake Archibald, Great episode. Thank you so much for making things complicated ;). Please make a video on how you debug things behind the scene. How do you approach this kind of issue. I think everyone wants to see the pain went behind the scene as well.

  • @PeerReynders
    @PeerReynders 3 роки тому +3

    11:54 Nitpick:
    Technically the `%` operator is the "remainder" operator - not *modulo*
    tc39.es/ecma262/#sec-numeric-types-number-remainder
    The _remainder_ operator calculates the remainder of division rounded towards *zero*, i.e.:
    dividend - divisor * Math.trunc(dividend / divisor);
    _modulo_ calculates the remainder of division rounded towards *negative infinity*, i.e.:
    dividend - divisor * Math.floor(dividend / divisor)
    Both produce identical results when both operands have the same sign but produce different results when the operands have different signs.
    const modulo = (dividend, divisor) =>
    ((dividend % divisor) + divisor) % divisor;
    const tests = [
    { dividend: 5, divisor: 3, mod: 2, rem: 2 },
    { dividend: 5, divisor: -3, mod: -1, rem: 2 },
    { dividend: -5, divisor: 3, mod: 1, rem: -2 },
    { dividend: -5, divisor: -3, mod: -2, rem: -2 },
    ];
    for (const { dividend, divisor, mod, rem } of tests) {
    console.assert(
    dividend % divisor === rem,
    `${dividend} % ${divisor} is not ${rem}`
    );
    console.assert(
    modulo(dividend, divisor) === mod,
    `${dividend} mod ${divisor} is not ${mod}`
    );
    }
    So in this use case it doesn't matter but when you're doing "clock arithmetic" you want *modulo*, not remainder.

  • @dougrudolph5400
    @dougrudolph5400 3 роки тому +1

    although not pulling in millions of views, these videos are gold for the more experienced developer that wants still wants to learn something new. and the teaching style is great. it never feels like im learning, rather im discovering a topic with the both of you

  • @rkgkjr
    @rkgkjr 3 роки тому +5

    This is super helpful for me! I've been working on a web player for a proprietary bitmap animation format from a Nintendo DS app, and getting the frames to render at the right interval has been a really annoying challenge for me. Gonna give this a whirl!

  • @thepaintedsock
    @thepaintedsock 2 роки тому

    Excellent, thorough assessment of problems implementing time accuracy for js animation

  • @mekelius
    @mekelius 2 роки тому

    I ran into these issues and had to figure them out while I was making a drum machine. Wish I'd had this video to hand back then :D. Even if your eyes would never detect the drift you can definitely hear it, especially when it's inconsistent.

  • @InPlainEnglishHQ
    @InPlainEnglishHQ 3 роки тому +3

    Great video, thoroughly enjoy these scenic-route explanations.

  • @childishalbino9548
    @childishalbino9548 3 роки тому +1

    That intro segment is exactly why I watch these videos XD

  • @orlovsskibet
    @orlovsskibet 3 роки тому +2

    You guys are great presenters, and provide tremendous value with your videos.
    Big thank you

  • @kingsleyoji649
    @kingsleyoji649 3 роки тому +8

    Thank you for this!

  • @vitabramov89
    @vitabramov89 3 роки тому

    Making simple things hard - is the best of this channel)) because it is our frontend life, here is absolutely no simple things, but LOTS of details!

  • @AndreiNedelus
    @AndreiNedelus 3 роки тому +4

    Hey, thanks for the explanation, I never know about document timeline :)

  • @okletsdoitt
    @okletsdoitt 3 роки тому +2

    My favorite UA-cam channel! Love you guys

  • @KevinSheppard
    @KevinSheppard 3 роки тому +2

    I learned so much about document.timeline. thanks for the complication!

  • @rasulturganov3421
    @rasulturganov3421 3 роки тому +1

    Great episode. Enjoyed watching

  • @Pfoffie
    @Pfoffie 3 роки тому +1

    I actually really loved this. Where to learn complex stuff better than in simple problems.
    Also: never heard of steps in CSS before, thanks for that, too :)

  • @tuomokulomaa6995
    @tuomokulomaa6995 3 роки тому +2

    My usual 10 min morning coffee got extended to 24:08. Riveting geekery 👍

  • @Abhishek-dp5tc
    @Abhishek-dp5tc 3 роки тому +1

    Hey Jake
    Please put more time in explaining what code is written, would be more helpful then
    Loved the video, thanks

  • @wmhilton-old
    @wmhilton-old 3 роки тому +1

    Well done! Another mind-blowing episode

  • @karlheinzneugebauer
    @karlheinzneugebauer 3 роки тому +1

    I always enjoy your tinkering videos!

  • @mayo2001
    @mayo2001 3 роки тому +1

    I was wrapping my head around where time arg comes from. It turns out it's passed by raf - "passed a single argument, a DOMHighResTimeStamp, which indicates the current time"

  • @vhoyer
    @vhoyer 3 роки тому +1

    Oh danm, I got to know this program last epsode, but I'm confident in saying that's one of the best shows/video series I've seen in a long while. Better than the shows I've been watching on netflix, but probably that on my poor ability to choose series ahha

  • @Vladhin
    @Vladhin 3 роки тому +1

    Good work digging there and
    SAVE CPU WHENEVER YOU CAN!

  • @nedeljkom
    @nedeljkom 3 роки тому +1

    Very clever solution with targetNext.

  • @shamsartem
    @shamsartem 3 роки тому +1

    this was just amazing. Thank you guys

  • @Abhishek-dp5tc
    @Abhishek-dp5tc 3 роки тому +1

    Why would anyone dislike it

  • @thekwoka4707
    @thekwoka4707 2 роки тому

    The requestAnimationFrame example could be improved...the animation frame callback gets a timestamp given to it, so you can use that in place of date.now()

  • @drd2093
    @drd2093 Рік тому

    I literally hate Chrome timing. Implementing JSMoo, a currently 4-system emulator, getting timing to happen in any consistent way is a serious challenge.

  • @DisfigurmentOfUs
    @DisfigurmentOfUs 2 роки тому

    Great episode, thanks!
    One thing that I think is wrong in the last solution is that it does not account for some browsers (safari) rounding performance.now() so it can actually be smaller than requestAnimationFrame argument. So the scheduling is not great, but rounding will take care of this.

  • @TheNewton
    @TheNewton 3 роки тому

    Thank you for doing the deep work

  • @kezzu5849
    @kezzu5849 Рік тому

    Fascinating!

  • @mustang19ms
    @mustang19ms 3 роки тому +1

    This is gold

  • @Manivelarino
    @Manivelarino 3 роки тому +1

    I like this video concept.

  • @mokkamokka4097
    @mokkamokka4097 3 роки тому

    love ya guys!

  • @nataliaromankevich2351
    @nataliaromankevich2351 3 роки тому +1

    Love this one!!

  • @sajankhandelwal8570
    @sajankhandelwal8570 3 роки тому +1

    Thanks for the great videos..

  • @DanBlackStreams
    @DanBlackStreams 3 роки тому +1

    As a developer who has written a lot of css animations... I can confirm they're pretty wonky.

  • @herokenzan2231
    @herokenzan2231 Рік тому

    Thank you

  • @Artea37
    @Artea37 2 роки тому

    so great thanks

  • @dwighthouse
    @dwighthouse 3 роки тому +1

    Well done.

  • @EdigleyssonSilva
    @EdigleyssonSilva 3 роки тому +2

    Thank you for this rich content!

  • @FelipeFrancisco8
    @FelipeFrancisco8 3 роки тому +1

    This is exactly why I stay away from the front-end

  • @nenadvicentic
    @nenadvicentic 3 роки тому

    This was BRILLIANT! :)

  • @tristanfraipont3782
    @tristanfraipont3782 3 роки тому

    Regarding Chrome's rAF bug I did open crbug.com/1018120 you might want to check.
    Also, an other mean to have a timer is to use the Web Audio API and its AudioScheduledSourceNode. These won't tick the "Avoids running in background" case, but on the contrary they'll prevent the browser from throttling the tab's timers at all. So not great for the trees, though I didn't measure overall CPU usage, but in some cases (e.g stackoverflow.com/questions/40687010/40691112#40691112 ), we want our code to run no matter what.

  • @mathisbullinger45
    @mathisbullinger45 3 роки тому +4

    What did you mean by the "double wrath"? (16:23)

    • @jakearchibald
      @jakearchibald 3 роки тому +7

      It's "double raf", as in call requestAnimationFrame within requestAnimationFrame

    • @pulga961
      @pulga961 3 роки тому +1

      requestAnimationFrame(()=>{
      requestAnimationFrame(callback)
      }
      )

  • @trivender007
    @trivender007 3 роки тому +2

    Interesting!

  • @paulamicel
    @paulamicel 3 роки тому +1

    ❤️🤓 thank you guys, this is premium web-nerd food 🍱

  • @AlvarLagerlof
    @AlvarLagerlof 3 роки тому +1

    Amazing!

  • @AndreLaBranche
    @AndreLaBranche 3 роки тому +1

    Very nice job. These two perspectives are just super useful in this context, and I hope it appeals to ‘the kids’ too :)

  • @wezelkrozum
    @wezelkrozum 3 роки тому +1

    But what if we schedule the frame function in the video.requestVideoFrameCallback method on a looped, 1 frame per second and 1x1 resolution video?

    • @jakearchibald
      @jakearchibald 3 роки тому

      Ohhhhh that's a great idea!

    • @jakearchibald
      @jakearchibald 3 роки тому +1

      (I mean, it might be a terrible idea for all sorts of reasons, but I like your thinking)

    • @wezelkrozum
      @wezelkrozum 3 роки тому

      Ah, it seems to suffer from drifting (~10ms per frame). But I'm not sure if the video framerate is precisely 1fps or if chrome does not render it precisely at 1fps.
      codepen.io/wesselkroos/pen/MWbjypz
      Also, with a ogv video the videoFrameCallback is only called once per ~11 frames...

    • @jakearchibald
      @jakearchibald 3 роки тому

      @@wezelkrozum ah well, thanks for giving it a go

  • @NitinPasumarthy
    @NitinPasumarthy 3 роки тому +1

    Wow! Excellent interview question. So many gotchas. I liked the way you presented the drift. Thanks for teaching us something new. How did you benchmark the CPU usage for each approach though? Is fair to say high CPU usage => high main thread usage for rAF, body.animate and CSS keyframes approaches?

    • @jakearchibald
      @jakearchibald 3 роки тому +1

      I just watched the task manager to measure the CPU. Not very scientific, but the difference was extreme enough to see.

    • @NitinPasumarthy
      @NitinPasumarthy 3 роки тому

      @@jakearchibald Got ya. Is fair to say high CPU usage => high main thread usage for rAF, body.animate and CSS keyframes approaches?
      Just trying to understand why higher CPU usage is bad if it doesn't block the main thread

    • @jakearchibald
      @jakearchibald 3 роки тому

      @@NitinPasumarthy even off the main thread, CPU usage uses battery

    • @NitinPasumarthy
      @NitinPasumarthy 3 роки тому

      @@jakearchibald Totally makes sense. Thank you.
      In general, which of rAF, body.animate and CSS keyframes approaches you shared, block the main thread and potentially impact user experience when used in other complex counters? Say, in my case, CPU & battery are less of a problem, than interactivity.

    • @31redorange08
      @31redorange08 3 роки тому

      @@jakearchibald It's visible in the task manager? I was sure the difference would be too small to show up.

  • @cybersecurity3523
    @cybersecurity3523 3 роки тому +1

    Thats good job google

  • @Stoney_Eagle
    @Stoney_Eagle 3 роки тому

    Is there an example why UA-cams counter on ads are wrong and take 1 extra second 🤷‍♂️ yeah I notice...

  • @gregfletcher2360
    @gregfletcher2360 3 роки тому

    This should be the video that auto plays after every js counter tutorial.

  • @vitabramov89
    @vitabramov89 3 роки тому

    Is this a GameOfThrones Whiskey on the background?))

    • @jakearchibald
      @jakearchibald 3 роки тому

      Yep! Someone bought me it, and it was surprisingly nice

  • @arpitdubey870
    @arpitdubey870 3 роки тому

    I like complicated stuff. So thanks. :)

  • @KevinFarrugia
    @KevinFarrugia 3 роки тому

    Time to refactor all my timers!

  • @Martin-4D
    @Martin-4D 3 роки тому +1

    Count efficiently!!!

  • @Ostap1974
    @Ostap1974 3 роки тому

    What is your recommendation to handle longer timeouts that would be handled well over computer sleep? As an example, one minute timeout/interval to show time (hours and minutes) does not work very well over sleep.

  • @benlu
    @benlu 3 роки тому

    Lol I used to do the basic thing of checking the difference of setTimeouts and the date time and calling it a day. Then I started using millisecond level clocks and stopped caring :D

  • @mfbx9da4
    @mfbx9da4 3 роки тому

    Can't help but think this should be renamed "How to implement the tag". The counting part is not really relevant to the video and excellent insights.

  • @ciberman
    @ciberman 3 роки тому

    Since you are talking about animation, It would be interesting if you explain how requestAnimationFrame can be used with canvas in an worker thread.

    • @jakearchibald
      @jakearchibald 3 роки тому

      Although we don't have an episode about this, there's developers.google.com/web/updates/2018/08/offscreen-canvas

    • @dassurma
      @dassurma 3 роки тому +2

      Browsers that have OffscreenCanvas also have requestAnimationFrame in a Worker context

    • @ciberman
      @ciberman 3 роки тому

      @@dassurma Interesting. Is that available in all major browsers? Last time I experimented with multi thread webGL rendering was a few years ago and offscreen canvas was still experimental

  • @ShawnBiddle
    @ShawnBiddle 3 роки тому +2

    I feel like using `document.timeline` should immediately disqualify this as the "right" solution given that it's still in working draft, regardless if browsers technically implement it or not.

    • @jakearchibald
      @jakearchibald 3 роки тому

      That's a bad take 😀. The HTML spec is a living spec, somewhat equivalent to a working draft. I guess you refuse to use HTML too?

    • @ShawnBiddle
      @ShawnBiddle 3 роки тому +1

      ​@@jakearchibald Maybe I'm just jaded by Google's premature use of the Shadow DOM v0 spec but there is an obvious difference between an accepted standard and one still labeled as experimental. Google in particular has been entirely too sanguine with considering its own implementation of a fledgling spec as ready for wide adoption. That's a "bad take" not unlike using the HTML living standard in an apples to oranges comparison to a Web API which isn't in living standard status. The "bad take" would be forgetting the Google privilege that if you shoot for the moon on a bad spec you have an army of developers to change direction (See: Polymer v2) which 99% of the web world does not have. Foisting potentially unstable tech on teams which can't afford the maintenance cost should the rug be pulled out from under them is a "bad take."

    • @jakearchibald
      @jakearchibald 3 роки тому

      @@ShawnBiddle the web components thing was bad, agreed. However, the animation API I'm using here isn't Google only, it's in all browser engines, so the comparison to web components is apples/oranges.

    • @jakearchibald
      @jakearchibald 3 роки тому

      Also, check out the list of editors in the spec. Mozilla + Apple + Google.

    • @ShawnBiddle
      @ShawnBiddle 3 роки тому

      @@jakearchibald Totally fair enough, like I said I'm just jaded :D Though given how many things you went over in this video that are further along than WD in the spec that just doesn't work how you'd expect or explicitly ignores the spec I think we can both also agree that there's a big gray area between "use everything" and "use it after it's been stable for 5 years." Smaller companies are necessarily more conservative and a lot of the time companies with dev bandwidth they take for granted signal prematurely the readiness of feature XYZ. Google certainly isn't the only culprit nor is the web the only susceptible platform.

  • @Manivelarino
    @Manivelarino 3 роки тому

    Surprised safari is the one to have those optimizations. I just wish they also kept up with implementing new js/css features 😅

    • @TheNewton
      @TheNewton 3 роки тому

      Animations are one of apples jam

  • @pulga961
    @pulga961 3 роки тому +1

    is there a way to stop it without AbortController?

    • @jakearchibald
      @jakearchibald 3 роки тому

      You can adapt the solution to do it however you want 😀

  • @markbailey2729
    @markbailey2729 3 роки тому +1

    No other series on web development will make you so sad to be a web developer. Guaranteed!

    • @jakearchibald
      @jakearchibald 3 роки тому

      Might make some "HTTP 203: bringing the sadness" t-shirts

    • @markbailey2729
      @markbailey2729 3 роки тому

      @@jakearchibald Maybe it says something about me that I make sure to watch every episode you guys make. Keep up the good fight!

  • @user-ln9yl6rn4p
    @user-ln9yl6rn4p 3 роки тому

    Thanks!!!!

  • @HolarMusic
    @HolarMusic 3 роки тому

    What about a simple requestAnimationFrame loop where you floor the time every time, but only update the UI if it's floored value changed?

    • @jakearchibald
      @jakearchibald 3 роки тому

      That still performs badly (similar to the web animation example). It's the 60hz timer that uses most of the CPU, not the DOM update.

    • @HolarMusic
      @HolarMusic 3 роки тому

      @@jakearchibald Interesting

  • @GottZ
    @GottZ 3 роки тому

    currentTime seems nice.
    I used to combine the elapsed time calculated with Date.now in setTimeout with requestAnimationFrame and tried to hit the next true second elapsing.
    So far this works perfectly fine for me and doesn't show any drift.
    Now I would wonder what happens if NTP syncs time throughout the timer running..
    I remember that double hit with setTimeout and I also remember that I solved it.
    I should re read through my timer code.. I'm confident about it.
    I made it like.. 10 years ago before requestAnimationFrame existed and extended it with requestAnimationFrame as soon as it shipped xD
    Ok a quick look led me there:
    let timeout = now % 1000;
    timeout = timeout !== 0 ? 1000 - timeout : 1000;

  • @IDisposable
    @IDisposable 3 роки тому

    What if you simply took the negative deltas and made them zero? (thus avoiding the double-render)

    • @jakearchibald
      @jakearchibald 3 роки тому

      It isn't clear that they're a negative delta

  • @bkrazor3
    @bkrazor3 3 роки тому

    Can you send us the article of Paul Luis who says setinterval is bad. I want to see what he uses instead.
    We want to redo all of our timers in the app as it’s causing too much of a slowdown for other things

    • @jakearchibald
      @jakearchibald 3 роки тому +1

      If you need to run something every frame, use requestAnimationFrame. If it's a low-frequency animation, use the solution in this video. If you're using timers for other things, consider using something else developer.chrome.com/blog/timer-throttling-in-chrome-88/ 😀

    • @bkrazor3
      @bkrazor3 3 роки тому

      @@jakearchibald thank you so much. I’ll start looking into all of these!

  • @rajatgupta08
    @rajatgupta08 3 роки тому +1

    How did you got to know about drift??

    • @jakearchibald
      @jakearchibald 3 роки тому

      I think I first encountered it by implementing a timer and seeing it glitch. However, I now know about it in more detail by reading the spec.

    • @rajatgupta08
      @rajatgupta08 3 роки тому

      @@jakearchibald is there any way to check if particular website counter is drifting or not (through code) like if I want to check of any chess website.

    • @jakearchibald
      @jakearchibald 3 роки тому +1

      @@rajatgupta08 You could record performance.now() at the start, then compare it to performance.now() at the end and see if the timer is showing the right thing

  • @TimCaswell
    @TimCaswell 3 роки тому +1

    I ended up with a similar solution when I needed a way to schedule cron-like actions on a website (some run every second, some at 8pm every day, some every hour, etc)
    github.com/creationix/family-dash/blob/main/modules/schedule.js

  • @ELStalky
    @ELStalky 3 роки тому

    I do not quite understand how that is supposed to work consistently. Can't you still get too much drift from setTimeout?
    E.g. going from underlying time difference of 16.4999 to 17.5001, yielding a jump in the UI from 16 to 18.
    I actually implemented a countdown just a few weeks ago. I think i settled for using a time difference while updating the UI a few times every second, but not every frame.
    So when the drift hits a boundary you get one interval that is slightly off but no numbers are skipped.

    • @jakearchibald
      @jakearchibald 3 роки тому

      It'd have to drift over 1000ms to get the wrong number, and the drift correction should stop it getting anywhere near that

  • @sidbits
    @sidbits 3 роки тому

    Just curious...what earphones are you guys using?
    ...and microphones

  • @halilbasmaci
    @halilbasmaci 3 роки тому +2

    Thanksssssssa

  • @victornpb
    @victornpb 3 роки тому

    I did a similar kind of optimization when I wrote a FPS calculation library, it tried to predict when the next update should happen and bails all the calculations prematurely to save CPU making it a simple conditional integer branch.
    But in my case the scheduling mechanism is up to the consumer.
    github.com/victornpb/micro-fps

  • @SimonBuchanNz
    @SimonBuchanNz 3 роки тому

    In "real" schedulers you generally have both a "run after/delay by" function and a "run at/delay until" function. Does JS / DOM need the latter? There's still a teeny inaccuracy between the now when you call setTimeout and when it actually executes, which might be important to someone, I guess.

    • @jakearchibald
      @jakearchibald 3 роки тому

      Feels like the web animation API should be the way to do the more accurate timing, right?

    • @SimonBuchanNz
      @SimonBuchanNz 3 роки тому

      @@jakearchibald call me a weirdo for thinking web animation should be for animations! More seriously I would be suspicious about it not running my code if it didn't feel like it, (background) etc., but I suppose that's all spec-able.

    • @jakearchibald
      @jakearchibald 3 роки тому

      @@SimonBuchanNz ahh yeah, if you want it to run in the background, that's different. Generally we're trying to cut down on pages running stuff in the background, and instead looking at features that eg show a notification at a particular time

    • @SimonBuchanNz
      @SimonBuchanNz 3 роки тому

      @@jakearchibald thinking of valid use cases is pretty tricky, to be fair: keeping a server synchronised, polling input, computing processing/usage statistics over time, but most of those are either not that time sensitive or should be parametrized by the time that's passed. I'm mostly just anxious about apis that imply a missing feature.

  • @TesterAnimal1
    @TesterAnimal1 2 роки тому

    Seems to me the spec is wrong and was designed very lazily.

  • @cintron3d
    @cintron3d 3 роки тому

    I really want to know if step easing in the css solution would have avoided the CPU usage issue

    • @jakearchibald
      @jakearchibald 3 роки тому +1

      We cover all of that at the end of the video. Only Safari optimises for step(), and it doesn't support animating content with CSS, so no 😀

    • @cintron3d
      @cintron3d 3 роки тому +1

      @@jakearchibald yeah, I had paused the video to write that but I did watch to the end and really enjoyed it. Many thanks for doing this research and sharing the results!

  • @aliulanowar7802
    @aliulanowar7802 3 роки тому

    thanks a lot for first Q answer => it's true

  • @TheRealCAPerry
    @TheRealCAPerry 3 роки тому

    I just need to know what the in-ear monitors you're both using are...

    • @jakearchibald
      @jakearchibald 3 роки тому

      Mine are Jabra 75t, Sumra's are Shures. IMO the Shures produce better sound & isolation, and it's what I used to use when commuting, but I find the Jabras easier to put in & take out, so they're better for calls.

  •  3 роки тому

    When did Chrome stop drifting?
    Or is it CPU architecture dependant?
    I ran into this trying to work on an embedded ARM system with Chromium and it started to drift really badly after a few weeks of running.
    Ended up using an external process for the events and just taking into account the delay in communication.

    • @jakearchibald
      @jakearchibald 3 роки тому +1

      Ohh it's possible things change after weeks of running. Like I said, a random blocking task will cause a major drift (in all browsers)

    • @SimonBuchanNz
      @SimonBuchanNz 3 роки тому

      You're going to get actual physical clock drifts at that time scale across separate hardware, it's why physical communication protocols have to have a clock signal. There's no software fix, except for something synchronizing them like NTP.

  • @JonathanGray89
    @JonathanGray89 3 роки тому

    I can't help but wonder if some of the code was inspired by a StackOverflow post that I participated in.

    • @JonathanGray89
      @JonathanGray89 3 роки тому

      /questions/37187504/javascript-second-counter

    • @jakearchibald
      @jakearchibald 3 роки тому +1

      @@JonathanGray89 nah, it wasn't based on anything particular from stackoverflow

    • @JonathanGray89
      @JonathanGray89 3 роки тому

      @@jakearchibald Ahh the second example is extremely close to my answer there... Thanks for replying, and awesome video btw!

  • @pratheepanumat6384
    @pratheepanumat6384 3 роки тому

    สวัสดีครับ

  • @winterheat
    @winterheat 3 роки тому

    The first method, even if the person starts the count (say go for exercise), comes back, and checks how long he has exercised for, if the computer did go into sleep mode, then it will not have counted the time when the computer was sleeping. The second method... so I think the concern is, since it is flooring the number, there can be a gap... (but 16 seconds? Even if it is off by 33ms, it take 30 seconds to go from floor(33.990), which is 33, to floor(35.023), which is 35 to show the gap (of missing 34)... so 16 seconds? meaning about 60ms slower each time?) So why not just make the interval 33 or 16 ms instead of 1000ms? If we are off by 0.033 seconds when we see the time, it is ok... but actually, when we floor the number, we can click start, and if we click "Stop" and it is 0.93s, we still see 0 and we are off by close to 1 second. So it is better to display 1 or 2 decimal places and know we can be off by that amount. Some time ago I checked, 33 ms was about the least amount of time between the handler being invoked in older browsers (IE8?), but now I do a `let start = Date.now(); void setTimeout(() => console.log(Date.now() - start), 0);` in Google Chrome, and it either prints out 1 or 2 on the MacBook Air M1, so it is 1/1000 or 2/1000 of a second

    • @jakearchibald
      @jakearchibald 3 роки тому

      > So why not just make the interval 33 or 16 ms instead of 1000ms?
      Then you're using 30/60x the amount of CPU required. Basically the same reason requestAnimationFrame is a bad solution (which on a 60hz screen will be running every 16ms).

    • @winterheat
      @winterheat 3 роки тому

      @@jakearchibald ok, I got to read up on requestAnimationFrame() and the rest of your solution... often I thought other webpages are doing tons of stuff underneath including showing ads and eating up 300MB to even 1GB just for one page sometimes anyway

    • @winterheat
      @winterheat 3 роки тому

      @@jakearchibald I just saw the use case of UA-cam broadcast count down from 2:34 to 0:00... it wouldn't look good if it is jumps from 2:12 to 2:10 directly... I wonder what if it is a solution such as updating every 160ms, so about 6 times per second, not too heavy on the CPU. If it is 100ms, then some second may appear as 0.9s and some appear as 1.1s but I guess not a big deal

    • @jakearchibald
      @jakearchibald 3 роки тому

      @@winterheat why not use the solution I came up with?

    • @jakearchibald
      @jakearchibald 3 роки тому

      @@winterheat the ideal solution in this video is only a few lines

  • @mfbx9da4
    @mfbx9da4 3 роки тому

    How come Houdini didn’t come up in this chat?

    • @jakearchibald
      @jakearchibald 2 роки тому

      Why should it have? What difference does it make?

  • @oskrm
    @oskrm 3 роки тому +2

    I'm the billionth viewer

  • @wobble_cat
    @wobble_cat 3 роки тому

    I don't believe I've watched that

  • @seanormiston9860
    @seanormiston9860 3 роки тому

    Wow -- next level. Performance.now() and document.timeline.currentTime *seem* to refer to the same thing --- time since document loading -- but they are....slightly different. Different enough to be used distinctly (non-interchangeably) within your code. Jake describes document.timeline.currentTime as "like performance.now(), *but* [is] the time of the current *frame*." What is this distinction, exactly? I can't any reference to frames in MDN documentation for document.timelines ....

    • @jakearchibald
      @jakearchibald 3 роки тому +1

      performance.now() will give a different answer each time you call it, even in the same synchronous JS execution, but document.timeline.currentTime will only change when the animation timeline current time changes, which only changes every frame.
      Strap in:
      drafts.csswg.org/web-animations-1/#dom-animationtimeline-currenttime - the definition of currentTime
      drafts.csswg.org/web-animations-1/#ref-for-timeline-current-time%E2%91%A4 - where the current time of document timelines is defined
      drafts.csswg.org/web-animations-1/#update-animations-and-send-events - the current time of document timelines is updated when this algorithm is called
      html.spec.whatwg.org/multipage/webappapis.html#event-loop-processing-model - that algorithm is called in step 11.10 of the event loop. Step 11 is all to do with updating the display, which happens when we need to create a frame.