<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Deian</title>
    <description>The latest articles on DEV Community by Deian (@tofuchicken).</description>
    <link>https://dev.to/tofuchicken</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4104552%2F6bfd3738-bde0-45d2-8b79-dc44c3ee36b2.png</url>
      <title>DEV Community: Deian</title>
      <link>https://dev.to/tofuchicken</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tofuchicken"/>
    <language>en</language>
    <item>
      <title>The 34 pixels that made PageSpeed think my static site was slow</title>
      <dc:creator>Deian</dc:creator>
      <pubDate>Thu, 03 Sep 2026 13:07:33 +0000</pubDate>
      <link>https://dev.to/tofuchicken/the-34-pixels-that-made-pagespeed-think-my-static-site-was-slow-37pp</link>
      <guid>https://dev.to/tofuchicken/the-34-pixels-that-made-pagespeed-think-my-static-site-was-slow-37pp</guid>
      <description>&lt;p&gt;Originally published at &lt;a href="https://deianisac.com/writing/pagespeed-speed-index/" rel="noopener noreferrer"&gt;deianisac.com&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;On deianisac.com, Speed Index stayed near four seconds after the page looked finished. Lighthouse scores a video of the load, not Largest Contentful Paint. 34 one-pixel flecks on Deian Isac's arrival canvas kept the first screen changing.&lt;/p&gt;

&lt;p&gt;That canvas now waits for a mouse move, tap, or key, not idle time. Clean Speed Index runs landed next to first paint. There is no Lighthouse user-agent check.&lt;/p&gt;

&lt;p&gt;My static site looked finished after about 1.1 seconds. PageSpeed sometimes said it took four.&lt;/p&gt;

&lt;p&gt;I looked for a huge hero, a JavaScript framework, and layout shift. It was 34 &lt;strong&gt;one-pixel flecks&lt;/strong&gt; on a canvas.&lt;/p&gt;

&lt;p&gt;This happened while I was rebuilding deianisac.com with Astro 7.2.10. The site ships static HTML, hand-written CSS, two small module scripts, and a few AVIF stills. I expected that to be boring to optimize.&lt;/p&gt;

&lt;p&gt;It wasn’t.&lt;/p&gt;

&lt;h2&gt;
  
  
  The page was already done
&lt;/h2&gt;

&lt;p&gt;The DebugBear &lt;strong&gt;filmstrip, not the score&lt;/strong&gt;, showed the page visually complete at 883 ms. First Contentful Paint and Largest Contentful Paint both landed at 846 ms. The full TTFB was 404 ms, with no layout shift.&lt;/p&gt;

&lt;p&gt;PageSpeed was less consistent. I saw Speed Index land at 1.1 s, 2.3 s, 4.1 s, then 3.9 s on the same deployed build.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://developer.chrome.com/docs/lighthouse/performance/speed-index/" rel="noopener noreferrer"&gt;Lighthouse calculates Speed Index from a video of the page loading&lt;/a&gt;. It compares the visual progression between frames. The browser can finish the largest element, satisfy LCP, and keep changing enough small pixels to drag out Speed Index.&lt;/p&gt;

&lt;p&gt;My network waterfall was mostly innocent. The screenshots were not.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 34 pixels
&lt;/h2&gt;

&lt;p&gt;The arrival scene has a full-screen canvas over a static coast image. It draws 24 short dashes on the water and 34 tiny flecks in the air, about 30 times a second.&lt;/p&gt;

&lt;p&gt;A person sees a little weather. Lighthouse sees a &lt;strong&gt;first screen that keeps changing&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;I had deferred the canvas until the browser was idle. That made the result unpredictable. If the main thread became idle early, the animation started inside the measurement window. If it became idle later, Speed Index finished before the first fleck appeared.&lt;/p&gt;

&lt;p&gt;Idle was the wrong trigger. The canvas now waits for &lt;strong&gt;real interaction&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;pointermove&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;onPointerMove&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;passive&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;pointerdown&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;start&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;passive&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;keydown&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;start&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is &lt;strong&gt;no Lighthouse user-agent check&lt;/strong&gt;. A mouse move starts it on desktop. A tap starts it on a phone. A key press covers keyboard use. Visitors who only read the first screen do not spend CPU on decorative weather, and &lt;code&gt;prefers-reduced-motion&lt;/code&gt; still skips it entirely.&lt;/p&gt;

&lt;p&gt;Once started, the flecks ease in from the left instead of snapping into view.&lt;/p&gt;

&lt;p&gt;That change pulled the clean Speed Index runs back beside first paint.&lt;/p&gt;

&lt;h2&gt;
  
  
  The images were still too big
&lt;/h2&gt;

&lt;p&gt;The canvas explained the four-second result. Phones were downloading 1,672-pixel stills for much smaller slots.&lt;/p&gt;

&lt;p&gt;I added 400, 800, 1,200, and native-width variants, with AVIF first and WebP as the next choice. Each `&lt;code&gt;now has a&lt;/code&gt;sizes` value that matches its layout, and the map stays lazy while the arrival image is eager and preloaded.&lt;/p&gt;

&lt;p&gt;I also compressed the 800-pixel arrival AVIF from 30.0 KiB to 19.4 KiB. That removed the image-delivery warning without producing an obvious visual loss. Going lower did.&lt;/p&gt;

&lt;p&gt;Changing the hero from synchronous to asynchronous decoding did not help. Across controlled runs, the median Speed Index moved by about 2 ms. That is noise, so I reverted it.&lt;/p&gt;

&lt;p&gt;The page got cheaper to load. Bytes were never &lt;strong&gt;the whole problem&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  A 244-byte placeholder
&lt;/h2&gt;

&lt;p&gt;After the image work, the frames showed one small blemish. The text appeared over a flat blue fallback, then the coast arrived 37 ms later.&lt;/p&gt;

&lt;p&gt;I looked at a &lt;a href="https://pinelab.studio/blog/implementing-low-quality-image-placeholders-lqip-in-astro/" rel="noopener noreferrer"&gt;ThumbHash approach for Astro&lt;/a&gt; and at &lt;a href="https://github.com/felixicaza/astro-lqip" rel="noopener noreferrer"&gt;astro-lqip&lt;/a&gt;. Fine if you have a folder of images. I had one hero.&lt;/p&gt;

&lt;p&gt;The smallest thing that worked was a 48-pixel WebP generated from the same hero. It is 244 bytes. I put its base64 data URL behind the real `` as a CSS background, so it adds no request and no browser script.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.arrival__picture&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--arrival-placeholder&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt; &lt;span class="m"&gt;52%&lt;/span&gt; &lt;span class="p"&gt;/&lt;/span&gt; &lt;span class="n"&gt;cover&lt;/span&gt; &lt;span class="nb"&gt;no-repeat&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A small local Lighthouse test produced this median across three simulated mobile runs:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Fallback&lt;/th&gt;
&lt;th&gt;Speed Index&lt;/th&gt;
&lt;th&gt;LCP&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Solid sky color&lt;/td&gt;
&lt;td&gt;922 ms&lt;/td&gt;
&lt;td&gt;1,503 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Inline 48 px WebP&lt;/td&gt;
&lt;td&gt;902 ms&lt;/td&gt;
&lt;td&gt;1,502 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Twenty milliseconds is small. It closes the visible gap for roughly 350 bytes of HTML, so I kept it. I did not add a dependency or a blur transition.&lt;/p&gt;

&lt;h2&gt;
  
  
  The optimization I threw away
&lt;/h2&gt;

&lt;p&gt;At one point I inlined some first-screen color, broadened font preloads to every page, and preloaded each inner-page hero. The dependency tree looked cleaner. The screenshots got worse, including one run that did not become visually complete until 8.56 s.&lt;/p&gt;

&lt;p&gt;I liked that cleaner tree. The pass did not improve repeated tests, so I reverted it. One ugly run is not evidence about request order or render-blocking CSS.&lt;/p&gt;

&lt;p&gt;An unscored warning is not a reason to rearrange a working critical path. My later tree was HTML, one small stylesheet, and two small module scripts. The stylesheet blocks first paint because stylesheets do that. The scripts did not.&lt;/p&gt;

&lt;h2&gt;
  
  
  The remaining bad run was real
&lt;/h2&gt;

&lt;p&gt;After the canvas and image changes, I ran production Lighthouse three times.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Run&lt;/th&gt;
&lt;th&gt;Score&lt;/th&gt;
&lt;th&gt;Speed Index&lt;/th&gt;
&lt;th&gt;Blocking time&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;100&lt;/td&gt;
&lt;td&gt;1.13 s&lt;/td&gt;
&lt;td&gt;25 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;100&lt;/td&gt;
&lt;td&gt;1.18 s&lt;/td&gt;
&lt;td&gt;19 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;68&lt;/td&gt;
&lt;td&gt;3.02 s&lt;/td&gt;
&lt;td&gt;1.36 s&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A managed &lt;strong&gt;Cloudflare challenge script&lt;/strong&gt; injected by the hosting layer spent 3.42 s on the main thread in that last run.&lt;/p&gt;

&lt;p&gt;My static host does not expose a switch for that script. I cannot compress an AVIF until third-party main-thread work disappears. The outlier is still part of the experience for a visitor who receives it, but it needs a hosting-layer fix, not another image tweak.&lt;/p&gt;

&lt;p&gt;A 68 is a bad score for a page that already looked finished. I stopped treating the integer score as the result. The frames, the trace, and the repeated runs tell me what changed. The badge does not.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next time
&lt;/h2&gt;

&lt;p&gt;I would open those frames first.&lt;/p&gt;

&lt;p&gt;If the first screen looks done while Speed Index keeps climbing, I would look for a canvas, font swap, transition, or anything else that continues to repaint. Then I would pause decorative work until interaction and test again.&lt;/p&gt;

&lt;p&gt;I would still do the boring file work. Responsive images, honest &lt;code&gt;sizes&lt;/code&gt;, preload only the actual LCP asset, keep below-the-fold art lazy.&lt;/p&gt;

&lt;p&gt;I would change &lt;strong&gt;one thing at a time&lt;/strong&gt; and keep the failed runs. They are usually more useful than the screenshot with 100 in the corner.&lt;/p&gt;

&lt;p&gt;Speed Index was not wrong. I thought I had asked when the page looked done. It was asking when &lt;strong&gt;the pixels stop changing&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Stop when &lt;strong&gt;the picture is done&lt;/strong&gt;.&lt;/p&gt;

</description>
      <category>performance</category>
      <category>astro</category>
      <category>webperf</category>
    </item>
    <item>
      <title>The browser used more CPU than the recorder</title>
      <dc:creator>Deian</dc:creator>
      <pubDate>Tue, 01 Sep 2026 16:00:00 +0000</pubDate>
      <link>https://dev.to/tofuchicken/the-browser-used-more-cpu-than-the-recorder-5ak7</link>
      <guid>https://dev.to/tofuchicken/the-browser-used-more-cpu-than-the-recorder-5ak7</guid>
      <description>&lt;p&gt;&lt;em&gt;&lt;strong&gt;I sampled &lt;a href="https://capkiku.com/" rel="noopener noreferrer"&gt;capkiku&lt;/a&gt; every second through a 65-minute call. 17% of one core, 85 MB of RAM, and Brave did the expensive work.&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Meeting recorders have a reputation for cooking the laptop. Fans, battery, a guest in the call, something uploading in the background.&lt;/p&gt;

&lt;p&gt;I don't run that. As an SEO agency owner (&lt;a href="https://gobofu.com/" rel="noopener noreferrer"&gt;goBOFU&lt;/a&gt;), I need my device to stay lean. There’s tons of stuff constantly running, including multiple sessions of Grok and Codex.&lt;/p&gt;

&lt;p&gt;Before building capkiku, I used Audio Highjack, only for it to completely bog down my Mac and make it almost crash, eating away 4GB of RAM. What for?&lt;/p&gt;

&lt;p&gt;Anyway, now I just hit &lt;code&gt;Record Audio&lt;/code&gt; in the menu bar and leave the recording running.&lt;/p&gt;

&lt;p&gt;For my most recent session, a 65-minute call with my client, it recorded two tracks, the client in Brave (Google Meet) plus my Tula mic, on capkiku 1.0.19, an M3 MacBook Air with 16 GB, macOS 26, sampled every second.&lt;/p&gt;

&lt;p&gt;The recorder sat at 17% of one core, median 17.5%. Almost every second of the hour lived between 15 and 20%. Brave as a whole, every helper process included, sat around 73% of one core and spiked past three.&lt;/p&gt;

&lt;p&gt;If the laptop got warm, that was the meeting.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fc0sdo23v03y2rw4zok88.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fc0sdo23v03y2rw4zok88.png" alt="CPU during a 65-minute call. capkiku holds 15–20% of one core. Brave spikes much higher." width="799" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What 65 minutes wrote
&lt;/h2&gt;

&lt;p&gt;The audio is 1 hour 5 minutes 42 seconds. The charts run closer to 67 minutes because that is the monitor window, from the files appearing to pressing the &lt;code&gt;Stop&lt;/code&gt; button. Others came out at 67.5 MiB and my own track at 72.0 MiB, both AAC at 48 kHz stereo. A 64 KB Markdown file sits next to them with an on-device transcript.&lt;/p&gt;

&lt;p&gt;That is about 2 MB per minute, written at 37 KB/s, in a straight line. It did not buffer the hour in RAM and dump it at the end.&lt;/p&gt;

&lt;p&gt;The app capkiku started around 97 MB idle, sat near 85 MB while recording, and peaked at 111 MB. RAM did not climb as the files grew. Idle used 16 threads, recording used 21, then it dropped back.&lt;/p&gt;

&lt;p&gt;CPU-time for the hour was 699 seconds, 540 user and 159 system, which integrates to 17.4% of one core.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8pku4yqt4tbvbs10w4dm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8pku4yqt4tbvbs10w4dm.png" alt="RAM stayed flat while 139 MB of audio landed on disk" width="799" height="369"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;My app doesn’t need an account, and it doesn’t upload the captures. The files landed in a folder I already use as a knowledge base, and I review them before I save. Only thing it doesn’t do is diarization.&lt;/p&gt;

&lt;p&gt;Of course, there are some network requests for updates, and on macOS 26 the speech model can initiate a download.&lt;/p&gt;

&lt;h2&gt;
  
  
  Stop, then the transcript
&lt;/h2&gt;

&lt;p&gt;I hit &lt;code&gt;Stop&lt;/code&gt;, and &lt;code&gt;Review Audio&lt;/code&gt; showed up in about 12 seconds. The capkiku process barely moved: a few 7–26% flickers, RAM from 110 MB to 137 MB, then idle.&lt;/p&gt;

&lt;p&gt;12 seconds is what you need for the on-device model to transcribe 65 minutes times two files, and the menu bar app did not look busy.&lt;/p&gt;

&lt;p&gt;So where did the work go?&lt;/p&gt;

&lt;p&gt;I ran Apple's SpeechAnalyzer again on the same two &lt;code&gt;.m4a&lt;/code&gt; files from a small CLI, and sampled &lt;code&gt;localspeechrecognition.xpc&lt;/code&gt;. LocalCapture stayed at 0%, and the XPC sat at about 1.2 cores and 150 MB across two processes.&lt;/p&gt;

&lt;p&gt;That is the transcribe tax, it is Apple's process, not a second copy of the recorder.&lt;/p&gt;

&lt;p&gt;The CLI replay took 82 seconds, not 12, and the first file logged a speech-model download. Don't mix those clocks. Use 12 seconds for what I waited after the call. Use the XPC chart for who burned the CPU.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fffhd7y0ujaig3ysz2op8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fffhd7y0ujaig3ysz2op8.png" alt="Transcription CPU sits in localspeechrecognition.xpc, not in capkiku" width="800" height="490"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I also ran &lt;code&gt;powermetrics&lt;/code&gt; with sudo on that replay. Apple says these watts are estimates, so don't compare your Mac with them. The sample covers the first ~60 seconds of the 82-second replay.&lt;/p&gt;

&lt;p&gt;Before transcribe, ANE sat at 0 W and combined CPU+GPU+ANE around 3 W. During transcribe, ANE was about 1 W and peaked at 3.1 W. CPU was about 10 W and peaked at 15 W. Combined was about 11 W and peaked at 18 W. Thermal went from Nominal to Moderate for a bit; &lt;code&gt;corespeechd&lt;/code&gt; did nothing useful in the samples.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhyroi3ddh9r9y0g7hsva.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhyroi3ddh9r9y0g7hsva.png" alt="Estimated SoC power. ANE around 1 W during transcribe. Combined CPU+GPU+ANE around 11 W." width="799" height="415"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I could not measure
&lt;/h2&gt;

&lt;p&gt;The processes &lt;code&gt;coreaudiod&lt;/code&gt;, &lt;code&gt;audiomxd&lt;/code&gt;, and &lt;code&gt;usbaudiod&lt;/code&gt; are SIP-blocked, so 17.5% is the capkiku process. The system audio tap may cost more inside Core Audio, and I don't have that number.&lt;/p&gt;

&lt;p&gt;I don't have watts for the live hour, only for the transcription replay. Apple Energy Impact on the XPC averaged about 887, which is a dimensionless score, not watts.&lt;/p&gt;

&lt;h2&gt;
  
  
  The encode is more than voice needs
&lt;/h2&gt;

&lt;p&gt;The writer targets 192 kbps stereo at 48 kHz, and voice does not need that. The mic file came out at 151 kbps of stereo speech, so mono and a lower bitrate on my own track would cut CPU and disk, and the other track can drop too. I’m not sure yet it’s worth optimizing that far.&lt;/p&gt;

&lt;p&gt;The good news is that the session didn’t leak memory.&lt;/p&gt;

&lt;h2&gt;
  
  
  The rule
&lt;/h2&gt;

&lt;p&gt;If your Mac is loud on a call, look at the browser first. That’s usually the bottleneck. But if you use also an app for transcription that brings it to its knees, there’s a better solution.&lt;/p&gt;

&lt;p&gt;A recorder like capkiku can sit at 17% of one core for an hour. It writes two files into a folder you own, then gets out of the way.&lt;/p&gt;

&lt;p&gt;Boring is good. Boring means it gets the job done fast and efficiently. Also, as a user said to me yesterday, the design is great—so not boring!&lt;/p&gt;

&lt;p&gt;capkiku is free, menu bar, macOS 14+, Apple Silicon. &lt;a href="https://capkiku.com" rel="noopener noreferrer"&gt;capkiku.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>swift</category>
      <category>showdev</category>
    </item>
  </channel>
</rss>
