<?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: xxxd</title>
    <description>The latest articles on DEV Community by xxxd (@xun_2cbcd4cac625126e).</description>
    <link>https://dev.to/xun_2cbcd4cac625126e</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F936651%2F0a83dc7f-35b5-4d47-a3d0-3819df53d117.png</url>
      <title>DEV Community: xxxd</title>
      <link>https://dev.to/xun_2cbcd4cac625126e</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/xun_2cbcd4cac625126e"/>
    <language>en</language>
    <item>
      <title>What is Babel? And SWC?</title>
      <dc:creator>xxxd</dc:creator>
      <pubDate>Mon, 24 Oct 2022 02:49:32 +0000</pubDate>
      <link>https://dev.to/playfulprogramming/what-is-babel-and-swc-49cp</link>
      <guid>https://dev.to/playfulprogramming/what-is-babel-and-swc-49cp</guid>
      <description>&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.amazonaws.com%2Fuploads%2Farticles%2Ffnm6w3e3jd7fnsr8rnc2.jpeg" 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.amazonaws.com%2Fuploads%2Farticles%2Ffnm6w3e3jd7fnsr8rnc2.jpeg" alt="The Tower of Babel" width="800" height="557"&gt;&lt;/a&gt;&lt;br&gt;
Image Source: &lt;a href="https://www.thetorah.com/article/language-is-baffling-the-story-of-the-tower-of-babel" rel="noopener noreferrer"&gt;Language Is Baffling - The Story of the Tower of Babel&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Babel. &lt;/p&gt;

&lt;p&gt;This word is loaded, full of culture and history, involving human and God. The millennia-old-story goes that the people of Babylon wanted to construct a tower to heaven, which infuriated God, who in turn dispersed people across different lands and made them speak different languages so they cannot understand and communicate with each other. The word Bab-El literally means Gate of Heaven (Bab: Gate; El: Heaven). (&lt;a href="https://www.britannica.com/topic/Tower-of-Babel" rel="noopener noreferrer"&gt;Tower of Babel&lt;/a&gt;). &lt;/p&gt;

&lt;p&gt;The word is also onomatopoeic (a word that sounds similar to the noise the word refers to). Same as babble, it imitates the manner a person rambles in confusion, which is what I might be doing throughout my following attempt to grasp Babel, then Rust, then SWC. &lt;/p&gt;

&lt;p&gt;Forgive me.&lt;/p&gt;
&lt;h2&gt;
  
  
  Babel - The JavaScript compiler
&lt;/h2&gt;

&lt;p&gt;To JavaScript developers, Babel means one thing only: a JavaScript compiler or transpiler (a tool that translates and compiles). And for a long time, it is the only compiler (to me anyway).&lt;/p&gt;

&lt;p&gt;So what does Babel do? Or what does any compiler / transpiler do? &lt;/p&gt;

&lt;p&gt;Babel transpiles modern, newer versions of JavaScript such as ES6 or TypeScript into old fashioned JavaScript understandable by older browsers. &lt;/p&gt;

&lt;p&gt;For example, The following code uses optional chaining operator and object destructure we have been taking for granted:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const stuff = {title: 'stuff', quality: 'frustrating'};
const {quality} = stuff?.quality
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After it goes through Babel, browsers will be fed with the following code instead:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const stuff = {
  title: 'stuff',
  quality: 'frustrating'
};
const {
  quality
} = stuff === null || stuff === void 0 ? void 0 : stuff.quality;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The compiled code runs in any environment. &lt;/p&gt;

&lt;p&gt;In another word, Babel has been the bridge that allows developers to explore newer and better things without worrying about breaking applications on older / slower-to-catch-up browsers. While the language of JavaScript continues to evolves, version by version, in leaps and bounds, Babel makes sure smooth translations of modern features such as ES6, React JSX extensions and so on can continue to function on older devices.&lt;/p&gt;

&lt;p&gt;You can always search &lt;a href="https://caniuse.com/" rel="noopener noreferrer"&gt;caniuse.com&lt;/a&gt; to see who supports what. For example, if you search for &lt;a href="https://caniuse.com/?search=Optional%20chaining%20operator" rel="noopener noreferrer"&gt;&lt;code&gt;Optional chaining operator&lt;/code&gt;&lt;/a&gt;, you will get the following Christmas-ish color coded table:&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.amazonaws.com%2Fuploads%2Farticles%2F63cmz9y4m9v7eaapfivr.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.amazonaws.com%2Fuploads%2Farticles%2F63cmz9y4m9v7eaapfivr.png" alt="Browser support of Optional chaining operator" width="800" height="252"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Babel usage statistics&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Babel has been and is still widely used and is an essential tool in web development.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;1,492,293 live websites using Babel and an additional 4,816,551 sites that used Babel historically and 622,292 websites in the United States.&lt;br&gt;
-- From &lt;a href="https://trends.builtwith.com/javascript/Babel#:~:text=Babel%20Competitors%20and%20Similar&amp;amp;text=Get%20a%20list%20of%206%2C329%2C548,to%20sites%20in%20this%20list" rel="noopener noreferrer"&gt;Trends.builtwith &lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Who created Babel?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Behind &lt;a href="https://en.wikipedia.org/wiki/Babel_(transcompiler)" rel="noopener noreferrer"&gt;Babel&lt;/a&gt; is the creator Sebastian McKenzie and the team now consists a small number of contributors. Babel also makes uses a polyfill library called &lt;a href="https://www.npmjs.com/package/core-js" rel="noopener noreferrer"&gt;core-js&lt;/a&gt;, which in turn uses a JavaScript parser, &lt;a href="https://github.com/acornjs/acorn" rel="noopener noreferrer"&gt;acorn&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Babel Process&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Shall we look a little deeper into the Babel process? &lt;/p&gt;

&lt;p&gt;For Babel, the code-to-code translation/compilation happens in three stages, each undertaken by a different tool. &lt;/p&gt;

&lt;p&gt;Sorry for even more cool terms. Aka Babel-talk. Aka jargons. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Parsing: A parser (&lt;a href="https://github.com/babel/babylon" rel="noopener noreferrer"&gt;Babylon&lt;/a&gt;. How fitting that Babel has a Babylon) reads the code and converts it to an &lt;a href="https://en.wikipedia.org/wiki/Abstract_syntax_tree" rel="noopener noreferrer"&gt;Abstract Syntax Tree (AST)&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;Traversal and Transformation: A &lt;a href="https://www.npmjs.com/package/babel-traverse" rel="noopener noreferrer"&gt;traverser Babel-Traverse&lt;/a&gt; traverses through the AST to analyse and transform the AST as needed&lt;/li&gt;
&lt;li&gt;Output: 
&lt;a href="https://www.npmjs.com/package/babel-generator" rel="noopener noreferrer"&gt;Babel generator&lt;/a&gt; outputs the final code from the transformed AST.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For more detailed and excellent explanation, please check out &lt;a href="https://www.sitepoint.com/understanding-asts-building-babel-plugin/" rel="noopener noreferrer"&gt;this article&lt;/a&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  Rust and SWC
&lt;/h2&gt;

&lt;p&gt;Babel has had its heyday and is still basking in its nearly ubiquitous glory. However, the wheels of technologies are always moving. &lt;/p&gt;

&lt;p&gt;In 2006, a new programming language called Rust was born out of a personal project. In 2014, it had its first stable release. After that, Rust has been proven to be irresistible to all major companies such as Google, Amazon, Facebook, Microsoft. According to &lt;a href="https://en.wikipedia.org/wiki/Rust_(programming_language),%20%20Rust%20is%20the%20" rel="noopener noreferrer"&gt;Wikipedia&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Rust's secret? More efficient, performant and memory safe. &lt;/p&gt;

&lt;p&gt;Rust is also proven to be versatile and powerful as a developer tool, as evidenced by the rise of SWC (Speedy Web Compiler), which has been quickly adopted by Next.js, which in turn replaces Babel as the compiler.&lt;/p&gt;

&lt;p&gt;SWC is fabulously, unbelievably, irresistibly fast.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;SWC is 20x faster than Babel on a single thread and 70x faster on four cores. - &lt;a href="https://swc.rs/" rel="noopener noreferrer"&gt;SWC.js&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The speed alone would make SWC a no-brainer to switch to. &lt;/p&gt;

&lt;p&gt;Next.js also lists &lt;a href="https://nextjs.org/docs/advanced-features/compiler#why-swc" rel="noopener noreferrer"&gt;other reasons&lt;/a&gt; such as extensibility, support for WASM (WebAssembly) and the amazing Rust community and ecosystem for the switch from Babel. &lt;/p&gt;

&lt;p&gt;The transition from Babel to SWC is a given and the timing  will be swift. &lt;/p&gt;

&lt;h2&gt;
  
  
  Play with SWC with the playground
&lt;/h2&gt;

&lt;p&gt;First, install SWC from npm.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// install swc core as well as its cli tool
npm install --save-dev @swc/core @swc/cli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then we can run the following commands to output the transformed code to a new file or a directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// output to a file
npx swc myfile.js -o output.js

// output all files in the src directory to the destination directory
npx swc src -d transpiledDir
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To see SWC live, the easiest way is to run the transformation in the &lt;a href="https://play.swc.rs/" rel="noopener noreferrer"&gt;swc official playground&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Taking our previous example you get the following code instantly (with the option of minify on):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var stuff={title:"stuff",quality:"frustrating"};var quality=(stuff===null||stuff===void 0?void 0:stuff.quality).quality;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  SWC in Next.js
&lt;/h2&gt;

&lt;p&gt;Next.js applications by default use SWC to transform and minify the JavaScript code for production. However, if the application has an existing Babel configuration (such as &lt;code&gt;babel.config.js&lt;/code&gt;) or are using unsupported features, it will fall back to use Babel. In such cases, you will get a little info snippet from Next.js as the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;info  - Disabled SWC as replacement for Babel because of custom Babel configuration "babel.config.js" https://nextjs.org/docs/messages/swc-disabled
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The SWC compiler used by Next.js support many features such as styled component, Jest, emotion. And Next.js continues to work on the SWC compiler to accept more plugins and incorporate many more features.&lt;/p&gt;

&lt;h2&gt;
  
  
  Not a conclusion
&lt;/h2&gt;

&lt;p&gt;I have to say, SWC is completely new to me. The learning goes on, as the race to better and faster things.&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>babel</category>
      <category>swc</category>
    </item>
    <item>
      <title>Script Loading, performance and Next Script</title>
      <dc:creator>xxxd</dc:creator>
      <pubDate>Sun, 16 Oct 2022 18:57:59 +0000</pubDate>
      <link>https://dev.to/playfulprogramming/script-loading-performance-and-next-script-20d7</link>
      <guid>https://dev.to/playfulprogramming/script-loading-performance-and-next-script-20d7</guid>
      <description>&lt;h2&gt;
  
  
  In the beginning ...
&lt;/h2&gt;

&lt;p&gt;In the beginning of web, there were no scripts; then there were minuscules of JavaScript aiming to give the web a bit of life, user interactions and dynamic flourishes, and what not; then JavaScript is everywhere, front and center, first and foremost.&lt;/p&gt;

&lt;p&gt;The beginning of JavaScript was simple as all beginnings are. We simple stick a piece of reference in the &lt;code&gt;head&lt;/code&gt; of a page html, as so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;script src="mysecretsource.js" /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or some inline sprinkle,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;script&amp;gt;
 alert('Hello world')
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then JavaScript gets very, very complicated. And the business of JavaScript loading and injection gets very messy and confusing very quickly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Current Affair of JavaScript Loading
&lt;/h2&gt;

&lt;p&gt;In the name of performance, in the fight to capture and retain users' attention in the age of scanty and fleeting attention, how-when-where-and-whether we load a piece of JavaScript becomes a battle of survival and thrival for some web applications. Because, let's face it, if your web page does not load and start functioning with three seconds, your users are likely click away, with that, whatever hopes you may have to sell.&lt;/p&gt;

&lt;p&gt;Performance becomes so critical that the lord of the web, Google, created a slew of performance tuning and monitoring tools. There are Google lighthouse, Webpage test, PageSpeed insights. Of the many metrics Google measures and uses to penalize some web sites for being bad (slow and janky) and elevate others for being good (fast and smooth), three of them are the most vital (so called &lt;a href="https://web.dev/vitals/" rel="noopener noreferrer"&gt;web vitals&lt;/a&gt;):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://web.dev/vitals/" rel="noopener noreferrer"&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.amazonaws.com%2Fuploads%2Farticles%2Fhsefrx8m0qw6zn91wc7q.jpg" alt="LCP web vital" width="390" height="300"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://web.dev/vitals/" rel="noopener noreferrer"&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.amazonaws.com%2Fuploads%2Farticles%2Fggltp6pkd86s1h6xzjib.jpg" alt="FID web vital" width="393" height="300"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://web.dev/vitals/" rel="noopener noreferrer"&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.amazonaws.com%2Fuploads%2Farticles%2Ft6ok89liyah5685ic1mi.jpg" alt="CLS web vital" width="378" height="300"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The business of how JavaScript we load directly impacts all three of the web vitals. It is so critical that Google chrome has come up with &lt;a href="https://addyosmani.com/blog/script-priorities/" rel="noopener noreferrer"&gt;a matrix of script loading and executing priorities&lt;/a&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; in &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt;: highly critical scripts such as those would affect DOM structure of the entire page&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;&amp;lt;link rel=preload&amp;gt;&lt;/code&gt; + &lt;code&gt;&amp;lt;script async&amp;gt;&lt;/code&gt; hack or
&lt;code&gt;&amp;lt;script type=module async&amp;gt;&lt;/code&gt;: medium/high priority scripts such as that generate critical content&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;&amp;lt;script async&amp;gt;&lt;/code&gt;: often used to indicate non-critical scripts&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;&amp;lt;script defer&amp;gt;&lt;/code&gt;: low priority scripts&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; at the end of &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt;: lowest priority  scripts that may be used occasionally
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;&amp;lt;link rel=prefetch&amp;gt;&lt;/code&gt; + &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt;: for scripts likely to to be helpful with a next-page navigation&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Here comes Next.js
&lt;/h2&gt;

&lt;p&gt;If you have been doing web development for a while, surely you have been washed over by the tides and fundamental shifts over SPA (single page application), MPA (Multiple page Application), SSR (Server side rendering), CSR (Client side rendering), SSR / CSR hybrid and this and that.&lt;/p&gt;

&lt;p&gt;Over the many competing frameworks and philosophies, Next.Js have come out triumphant. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Next.js is an open-source web development framework created by Vercel enabling React-based web applications with server-side rendering and generating static websites. React documentation mentions Next.js among "Recommended Toolchains" advising it to developers as a solution when "Building a server-rendered website with Node.js".&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Next.js has also been endorsed by Google and Vercel has been collaborating closely with Google. &lt;/p&gt;

&lt;p&gt;Surely the headache of deciding how and when to load a piece of JavaScript has also reached Next.js and Google itself, so much so that Next.js have come up with a set of script loading strategies, which also has had Google's blessing.&lt;/p&gt;

&lt;h2&gt;
  
  
  The four strategies of Next Script
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://nextjs.org/docs/basic-features/script" rel="noopener noreferrer"&gt;There are four strategies in using Next Script&lt;/a&gt;. Three really, &lt;code&gt;beforeInteractive&lt;/code&gt;, &lt;code&gt;afterInteractive&lt;/code&gt;, &lt;code&gt;lazyOnLoad&lt;/code&gt;. There is an experimental &lt;code&gt;worker&lt;/code&gt; strategy that utilizes &lt;a href="https://partytown.builder.io/" rel="noopener noreferrer"&gt;Partytown&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;beforeInteractive&lt;/code&gt;: injects scripts in the &lt;code&gt;head&lt;/code&gt; with &lt;code&gt;defer&lt;/code&gt;;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
 const beforeInteractiveScripts = (scriptLoader.beforeInteractive || [])
    .filter((script) =&amp;gt; script.src)
    .map((file: ScriptProps, index: number) =&amp;gt; {
      const { strategy, ...scriptProps } = file
      return (
        &amp;lt;script
          {...scriptProps}
          key={scriptProps.src || index}
          defer={scriptProps.defer ?? !disableOptimizedLoading}
          nonce={props.nonce}
          data-nscript="beforeInteractive"
          crossOrigin={props.crossOrigin || crossOrigin}
        /&amp;gt;
      )
    })
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://github.com/vercel/next.js/blob/canary/packages/next/pages/_document.tsx#L318-L332" rel="noopener noreferrer"&gt;Next.js Source Code for &lt;code&gt;beforeInteractive&lt;/code&gt; script handling&lt;br&gt;
&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;afterInteractive&lt;/code&gt;: adds the script to the bottom of &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt;;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;lazyOnload&lt;/code&gt;: similar to &lt;code&gt;afterInteractive&lt;/code&gt;, however it uses &lt;code&gt;requestIdleCallback&lt;/code&gt; to wait until the main thread becomes idle&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/vercel/next.js/blob/canary/packages/next/client/script.tsx#L226-L236" rel="noopener noreferrer"&gt;Next.js Source Code for &lt;code&gt;afterInteractive&lt;/code&gt;/&lt;code&gt;lazyOnLoad&lt;/code&gt; script handling&lt;br&gt;
&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; useEffect(() =&amp;gt; {
      // other code 
      if (strategy === 'afterInteractive') {
        loadScript(props)
      } else if (strategy === 'lazyOnload') {
        loadLazyScript(props)
      }

    }
  }, [props, strategy])

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

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  const { strategy = 'afterInteractive' } = props
  if (strategy === 'lazyOnload') {
    window.addEventListener('load', () =&amp;gt; {
      requestIdleCallback(() =&amp;gt; loadScript(props))
    })
  } else {
    loadScript(props)
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://github.com/vercel/next.js/blob/canary/packages/next/client/script.tsx#L226-L236" rel="noopener noreferrer"&gt;Next.js Source use &lt;code&gt;requestIdleCallback&lt;/code&gt; to lazy load script&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Next Script in practice
&lt;/h2&gt;

&lt;p&gt;Using Next Script is easy, deciding which strategy to use is hard. Harder than just sticking the script somewhere anyway.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;beforeInteractive&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;beforeInteractive&lt;/code&gt; should only be used when a script is absolutely critical to the web application as a whole. For example, device setting detection, framework at run time. &lt;/p&gt;

&lt;p&gt;Next.js states that:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This strategy only works inside &lt;code&gt;_document.js&lt;/code&gt; and is designed to load scripts that are needed by the entire site &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If for any reasons, you insist on using &lt;code&gt;beforeInteractive&lt;/code&gt; in a component, it will still work. It is just that the ordering and timing of this script might not be predictable.&lt;/p&gt;

&lt;p&gt;Sample Code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;Html&amp;gt;
  &amp;lt;Head /&amp;gt;
  &amp;lt;body&amp;gt;
    &amp;lt;Main /&amp;gt;
    &amp;lt;NextScript /&amp;gt;
    &amp;lt;Script
   src="https://cdn.jsdelivr.net/npm/bootstrap@4.3.1/dist/js/bootstrap.min.js"
      strategy="beforeInteractive"
    &amp;gt;&amp;lt;/Script&amp;gt;
  &amp;lt;/body&amp;gt;
  &amp;lt;/Html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Checking the html output, you can see the script being loaded in the &lt;code&gt;head&lt;/code&gt;, before other Next.js first-party script.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;script src="https://cdn.jsdelivr.net/npm/bootstrap@4.3.1/dist/js/bootstrap.min.js" defer="" data-nscript="beforeInteractive"&amp;gt;&amp;lt;/script&amp;gt;

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;afterInteractive&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Next Script by default uses &lt;code&gt;afterInteractive&lt;/code&gt; strategy. You can add the script in any component.&lt;/p&gt;

&lt;p&gt;Sample code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;Script src="https://www.google-analytics.com/analytics.js" /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Checking the html output, you can see the script being inserted at the bottom of the &lt;code&gt;body&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;script src="https://www.google-analytics.com/analytics.js" data-nscript="afterInteractive"&amp;gt;&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Third party scripts such as ads, google analytics should be good candidates for this strategy. &lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;lazyOnLoad&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;lazyOnLoad&lt;/code&gt; works the same way as scripts using &lt;code&gt;afterInteractive&lt;/code&gt;. However it will only be loaded during idle time. Next.js uses the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/requestIdleCallback" rel="noopener noreferrer"&gt;window.requestIdleCallback&lt;/a&gt; method to check if browser is idle.&lt;/p&gt;

&lt;p&gt;Third party scripts that have the lowest priorities should be loaded &lt;code&gt;lazyOnLoad&lt;/code&gt; strategy. For example, third party script for comments (if you do not care comments).&lt;/p&gt;

&lt;p&gt;Sample code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    &amp;lt;Script
                src="https://www.google-analytics.com/analytics.js"
                strategy="lazyOnload"
            /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now if you check the html output, you can see it is also gets added at the bottom of page, like the script using &lt;code&gt;afterInteractive&lt;/code&gt; strategy.&lt;/p&gt;

&lt;p&gt;If we fake some busy browser processing, we can clearly see how the &lt;code&gt;layzOnLoad&lt;/code&gt; strategy works. &lt;/p&gt;

&lt;p&gt;For example, on component mount, we add the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;useEffect(() =&amp;gt; {
        for (let i = 0; i &amp;lt;= 10000; i++) {
            if (i === 10000) console.log(i);
        }
    }, []);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then we added an &lt;code&gt;onLoad&lt;/code&gt; event handler in the script, we can see the &lt;code&gt;onLoad&lt;/code&gt; event wont fire until the above dummy code finishing processing.&lt;/p&gt;

&lt;p&gt;This can also be seen in the network waterfall capture:&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.amazonaws.com%2Fuploads%2Farticles%2F87gs7i13l917zoh8sx5v.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.amazonaws.com%2Fuploads%2Farticles%2F87gs7i13l917zoh8sx5v.png" alt="LazyOnLoad script network waterfall" width="792" height="560"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Measuring the web vitals
&lt;/h2&gt;

&lt;p&gt;So is Next Script better than that you pick and choose one of the priorities and inject scripts on your own? I feel it is hardly conclusive for the following reasons:&lt;/p&gt;

&lt;p&gt;1) In the end, Next Script uses the native &lt;code&gt;script&lt;/code&gt;, only with a bit syntactic sugar and some cache handling. The same mistakes made with the native &lt;code&gt;script&lt;/code&gt; might also be made with Next Script by picking the wrong strategy, and vice versa.&lt;/p&gt;

&lt;p&gt;2) I have created one dummy next.js pages and two static html pages. I have run tests on those pages through both &lt;a href="https://www.webpagetest.org/" rel="noopener noreferrer"&gt;webpage tests&lt;/a&gt; and &lt;a href="https://pagespeed.web.dev/" rel="noopener noreferrer"&gt;PageSpeed Insights&lt;/a&gt;. Unfortunately, the results are not conclusive. &lt;/p&gt;

&lt;p&gt;The set up of the two static html pages are:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://nextjs-playground-cyan-chi.vercel.app/static/test.html" rel="noopener noreferrer"&gt;Static html 1&lt;/a&gt;: GA script in the head, using &lt;code&gt;async&lt;/code&gt; (the way &lt;a href="https://www.nytimes.com/2022/10/14/science/sarcastic-fringehead-mouth-display.html" rel="noopener noreferrer"&gt;nytimes&lt;/a&gt; does), twitter script at the bottom of body&lt;/p&gt;

&lt;p&gt;&lt;a href="https://nextjs-playground-cyan-chi.vercel.app/static/test2.html" rel="noopener noreferrer"&gt;Static html 2&lt;/a&gt;: GA script in the middle of &lt;code&gt;body&lt;/code&gt;, twitter script at the bottom of body&lt;/p&gt;

&lt;p&gt;&lt;a href="https://nextjs-playground-cyan-chi.vercel.app/scripts-demo/performace/next-script" rel="noopener noreferrer"&gt;Next Script Page&lt;/a&gt;: use &lt;code&gt;afterInteractive&lt;/code&gt; for both the twitter script and ga script.&lt;/p&gt;

&lt;p&gt;Pagespeed test results (&lt;a href="https://pagespeed.web.dev/report?url=https%3A%2F%2Fnextjs-playground-cyan-chi.vercel.app%2Fstatic%2Ftest.html" rel="noopener noreferrer"&gt;static1&lt;/a&gt;, &lt;a href="https://pagespeed.web.dev/report?url=https%3A%2F%2Fnextjs-playground-cyan-chi.vercel.app%2Fstatic%2Ftest1.html" rel="noopener noreferrer"&gt;static2&lt;/a&gt;, &lt;a href="https://pagespeed.web.dev/report?url=https%3A%2F%2Fnextjs-playground-cyan-chi.vercel.app%2Fscripts-demo%2Fperformace%2Fnext-script" rel="noopener noreferrer"&gt;Next Script&lt;/a&gt;):&lt;/p&gt;

&lt;p&gt;Pagespeed insights indicates that Next Script fares better than both the static html pages.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Static 1 PSI score&lt;/strong&gt;&lt;br&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.amazonaws.com%2Fuploads%2Farticles%2Fz30s3ejeane71d477u2p.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.amazonaws.com%2Fuploads%2Farticles%2Fz30s3ejeane71d477u2p.png" alt="Static 1 PSI score" width="800" height="324"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Static 2 PSI score&lt;/strong&gt;&lt;br&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.amazonaws.com%2Fuploads%2Farticles%2Fv771oaezqd278jttya8q.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.amazonaws.com%2Fuploads%2Farticles%2Fv771oaezqd278jttya8q.png" alt="Static 2 PSI score" width="800" height="327"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Next Script PSI score&lt;/strong&gt;&lt;br&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.amazonaws.com%2Fuploads%2Farticles%2Fmpnx34m1f36z23rpnfen.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.amazonaws.com%2Fuploads%2Farticles%2Fmpnx34m1f36z23rpnfen.png" alt="Next Script PSI score" width="800" height="320"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Webpage test results (&lt;a href="https://www.webpagetest.org/result/221016_AiDcW0_78T/" rel="noopener noreferrer"&gt;static1&lt;/a&gt;, &lt;a href="https://www.webpagetest.org/result/221016_BiDcH8_78G/" rel="noopener noreferrer"&gt;static2&lt;/a&gt;, &lt;a href="https://www.webpagetest.org/result/221016_BiDc3B_78D/" rel="noopener noreferrer"&gt;Next Script&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;However, webpage test gives the results that indicate the  opposite:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Static 1 Webpage test metrics&lt;/strong&gt;&lt;br&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.amazonaws.com%2Fuploads%2Farticles%2Fuzzami7u8tvkwj3sw101.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.amazonaws.com%2Fuploads%2Farticles%2Fuzzami7u8tvkwj3sw101.png" alt="Webpage test metrics for static 1" width="800" height="217"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Static 2 Webpage test metrics&lt;/strong&gt;&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.amazonaws.com%2Fuploads%2Farticles%2F5o1a6qtfeo2q4wz8sbah.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.amazonaws.com%2Fuploads%2Farticles%2F5o1a6qtfeo2q4wz8sbah.png" alt="Webpage test metrics for static 2" width="800" height="213"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Next Script Webpage test metrics&lt;/strong&gt;&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.amazonaws.com%2Fuploads%2Farticles%2Fua1llm3z37dk6q0n6no3.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.amazonaws.com%2Fuploads%2Farticles%2Fua1llm3z37dk6q0n6no3.png" alt="Webpage test metrics for Next Script" width="800" height="221"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;JavaScript is complicated, loading of JavaScript is complicated, though the complexities is merited given it has powered the vast and intricate web. Next Script is a nice addition to rein in the complexity and made developers' job a little easier. &lt;/p&gt;

&lt;h2&gt;
  
  
  Source Code
&lt;/h2&gt;

&lt;p&gt;All code and some explanation can be found in my &lt;a href="https://nextjs-playground-cyan-chi.vercel.app/" rel="noopener noreferrer"&gt;next.js playground&lt;/a&gt; and &lt;a href="https://github.com/xd-hearst/nextjs-playground" rel="noopener noreferrer"&gt;this github repository&lt;/a&gt;. &lt;/p&gt;

</description>
      <category>javascript</category>
      <category>nextjs</category>
      <category>performance</category>
    </item>
  </channel>
</rss>
