<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Paul Irish on Medium]]></title>
        <description><![CDATA[Stories by Paul Irish on Medium]]></description>
        <link>https://medium.com/@paul_irish?source=rss-6d5456230083------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/0*5THJRVpXB13AuOdS.jpeg</url>
            <title>Stories by Paul Irish on Medium</title>
            <link>https://medium.com/@paul_irish?source=rss-6d5456230083------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sat, 14 Nov 2026 05:22:08 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@paul_irish/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[requestAnimationFrame Scheduling For Nerds]]></title>
            <link>https://medium.com/@paul_irish/requestanimationframe-scheduling-for-nerds-9c57f7438ef4?source=rss-6d5456230083------2</link>
            <guid isPermaLink="false">https://medium.com/p/9c57f7438ef4</guid>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[android]]></category>
            <dc:creator><![CDATA[Paul Irish]]></dc:creator>
            <pubDate>Thu, 07 Jul 2016 20:27:36 GMT</pubDate>
            <atom:updated>2018-02-15T02:35:55.834Z</atom:updated>
            <cc:license>http://creativecommons.org/publicdomain/zero/1.0/</cc:license>
            <content:encoded><![CDATA[<p>A few people were curious about the scheduling of requestAnimationFrame callbacks, so here’s the tl;dr:</p><h4>All rAF callbacks always run in the same or next frame of work</h4><p>Any rAFs queued <strong>in your event handlers</strong> will be executed in the ​<strong><em>same frame</em></strong>​.<br>Any rAFs queued <strong>in a rAF</strong> will be executed in the <strong><em>next frame</em></strong><em>​</em>. <em>(Same for any queued within IntersectionObserver or ResizeObserver </em><a href="https://twitter.com/jaffathecake/status/912695164912701441"><em>callbacks</em></a><em>.)</em></p><p>All rAFs that are queued <em>will</em> be executed in the intended frame.</p><h4>Every rAF you request <strong>will</strong> run</h4><p>rAFs aren’t throttled for you if they take too long to execute.</p><p>Let’s say there’s 5 callbacks queued up, and they’ll each take ~100 ms. The browser <em>will not </em>distribute them amongst many frames. It’ll try to run them all in the intended frame, even if it takes 500 ms. That means a pretty significant jank.</p><p><em>You may be asking, “why would there be FIVE animationFrame callbacks requested from within a single frame?” It can accidentally happen if you do 2 very reasonable things. 1) You request a new callback at the end of a rAF. 2) You request rAF callbacks from a input handlers. As a result, you’ve doubled/tripled your work each frame. Youch.</em></p><p><strong>It’s up to you to coalesce rAFs on your own. </strong>So: if there’s a chance of multiple of the “same” callbacks firing within the same frame, then you must manage the scheduling/coalescing.</p><p>That said, Chrome (at least) will try to help some. If rAFs are hogging the main thread, the browser will start to throttle input events so that, hopefully, the contention will clear up.</p><p><em>And now this.. T</em>wo diagrams that help illustrate the lifecycle of events in a frame:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ad-k5hYKQnRQJF8tv8BIqg.png" /><figcaption>Life of a frame (main thread edition)</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/824/1*atEwskfs0gtIryRrgnAPkw.png" /><figcaption>Event dispatching within a frame (multi-process edition)</figcaption></figure><p>(Update Feb 2018. Jake Archibald recently gave a talk on the event loop which will almost definitely tickle your fancy:)</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fplayer.vimeo.com%2Fvideo%2F254947206%3Fapp_id%3D122963&amp;dntp=1&amp;url=https%3A%2F%2Fvimeo.com%2F254947206&amp;image=https%3A%2F%2Fi.vimeocdn.com%2Fvideo%2F682298249_1280.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=vimeo" width="1280" height="720" frameborder="0" scrolling="no"><a href="https://medium.com/media/9c4bd61d6a214284d35bba7b8180d9b0/href">https://medium.com/media/9c4bd61d6a214284d35bba7b8180d9b0/href</a></iframe><p>And for more implementation details, Sami’s <a href="https://www.youtube.com/watch?v=nfEeTPntW5E">Blink Scheduler talk</a> from BlinkOn 3 is worth a watch, and you can poke around the <em>Scheduler Overhaul</em> resources in <a href="https://github.com/ds-hwang/wiki/wiki/Chromium-docs#work-in-progress">ds-hwang‘s Chromium-docs</a>.</p><h4>Addendum about the rAF timestamp</h4><p>(added Feb 2018)</p><p>Many folks express confusion about the timestamp included as the first argument of the rAF callback. And for good reason.</p><p>The timestamp represents <strong>the beginning of the main thread frame that we’re currently in</strong>. This means that multiple different rAF callbacks can get back the exact same timestamp:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*RJX6QfDtf7Dl2OL8Ai0Clw.png" /><figcaption>Note the repeated-count badges on the left of the logs…</figcaption></figure><p>If that’s not very useful to you (you’re not alone), then feel free to grab <em>performance.now()</em> at the start of the callback and use that for your purposes.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=9c57f7438ef4" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Debugging Node.js with Chrome DevTools]]></title>
            <link>https://medium.com/@paul_irish/debugging-node-js-nightlies-with-chrome-devtools-7c4a1b95ae27?source=rss-6d5456230083------2</link>
            <guid isPermaLink="false">https://medium.com/p/7c4a1b95ae27</guid>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[chrome-dev-tools]]></category>
            <category><![CDATA[nodejs]]></category>
            <category><![CDATA[debugging]]></category>
            <dc:creator><![CDATA[Paul Irish]]></dc:creator>
            <pubDate>Fri, 24 Jun 2016 15:02:29 GMT</pubDate>
            <atom:updated>2022-11-14T20:21:14.161Z</atom:updated>
            <cc:license>http://creativecommons.org/licenses/by/4.0/</cc:license>
            <content:encoded><![CDATA[<p>Support for Node.js debuggability <a href="https://github.com/nodejs/node/pull/6792">landed</a> in Node.js in 2016. Here’s how to get up and running. <em>(Post updated Jan 2018)</em></p><p><strong>1. Download and install the </strong><a href="https://nodejs.org/en/download/current/"><strong>current version of node</strong></a><strong>. </strong>(v6.3.0+ required)</p><p><strong>2. Run node with the </strong><strong>--inspect-brk flag:</strong></p><pre># Break on the first statement of the script</pre><pre>▸ <strong>node --inspect-brk index.js</strong></pre><p><em>Next, you used to open the big </em><em>chrome-devtools:// URL it spits out, </em><strong><em>but don’t</em></strong><em>. Now there’s a better way…</em></p><p><strong>3. Open </strong><strong>about:inspect in Chrome</strong></p><p>It’ll redirect you to chrome://inspect quickly and you’ll see something like:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/663/1*x4VXx50dLdD_HbqE6hpIRw.png" /><figcaption>chrome://inspect screenshot</figcaption></figure><p><strong>4. Click the <em>Open dedicated DevTools for Node</em> link.</strong></p><p>You’ll get a popup window for debugging your node session.</p><p>But better than that, when you kill and restart node, <strong>the window will automatically reconnect</strong> to it. 🔁🔁💥</p><p>(Btw: the <strong><em>inspect</em> </strong>link beneath the specific target will only apply for that session of node and won’t reconnect.)</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/881/1*iHurZ1VUsM54zGjZJHqexQ.png" /></figure><p>In DevTools, now connected to Node, you’ll have all the Chrome DevTools features you’re used to:</p><ul><li>Complete breakpoint debugging, stepping w/ blackboxing</li><li>Source maps for transpiled code</li><li>LiveEdit: JavaScript hot-swap evaluation w/ V8</li><li>Console evaluation with ES6 feature/object support and <a href="https://docs.google.com/document/d/1FTascZXT9cxfetuPRT2eXPQKXui4nWFivUnS_335T3U/view">custom object formatting</a></li><li>Sampling JavaScript profiler w/ flamechart</li><li>Heap snapshot inspection, heap allocation timeline, allocation profiling</li><li>Asynchronous stacks for native promises</li></ul><p>To see this in action, here’s my demo during the 2017 Node Summit:</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FXb_0awoShR8%3Fstart%3D257%26feature%3Doembed%26start%3D257&amp;url=http%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DXb_0awoShR8&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FXb_0awoShR8%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/7709d46c629d7723523fcd969503ed51/href">https://medium.com/media/7709d46c629d7723523fcd969503ed51/href</a></iframe><p>Lastly, there is now official documentation on debugging Node with the new protocol: <a href="https://nodejs.org/en/docs/inspector/">https://nodejs.org/en/docs/inspector/</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=7c4a1b95ae27" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>