<?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: Yisar</title>
    <description>The latest articles on DEV Community by Yisar (@132).</description>
    <link>https://dev.to/132</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%2F219281%2Ff9401246-5aa5-41cd-abb5-fd2647475854.jpeg</url>
      <title>DEV Community: Yisar</title>
      <link>https://dev.to/132</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/132"/>
    <language>en</language>
    <item>
      <title>Chinese miniapp architecture</title>
      <dc:creator>Yisar</dc:creator>
      <pubDate>Thu, 08 Jun 2023 05:25:15 +0000</pubDate>
      <link>https://dev.to/132/chinese-miniapp-architecture-3mg</link>
      <guid>https://dev.to/132/chinese-miniapp-architecture-3mg</guid>
      <description>&lt;p&gt;Do you know that Chinese people have their own cross platform framework, called miniapp? As of now, there are approximately 7 million miniapps, and 1.4 billion Chinese people can avoid using browsers and search engines, but nobody can avoid using miniapps.&lt;/p&gt;

&lt;p&gt;I have introduced this architecture to few foreign companies and developers before. &lt;/p&gt;

&lt;p&gt;As far as I know, &lt;a class="mentioned-user" href="https://dev.to/elonmusk"&gt;@elonmusk&lt;/a&gt; is very envious of WeChat's payment, But he didn't know that without WeChat miniapps, all fetures would not be universal.&lt;/p&gt;

&lt;p&gt;I used to work at Trip.com, leading the development of Trip miniapp. Now that I have resigned, I no longer do front-end work, but I don't want to be forgotten, so I have openesourced this architecture.&lt;/p&gt;

&lt;p&gt;China is a vast internet world, its technology should not be closed source.&lt;/p&gt;

&lt;h3&gt;
  
  
  Screenshots
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zjUCnuuJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ob39ux5hm5v6g9bcrq35.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zjUCnuuJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ob39ux5hm5v6g9bcrq35.jpg" alt="Image description" width="800" height="1778"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Github
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/yisar/smallapp"&gt;https://github.com/yisar/smallapp&lt;/a&gt;&lt;/p&gt;

</description>
      <category>miniapp</category>
      <category>javascript</category>
      <category>fre</category>
    </item>
    <item>
      <title>Asta: New jointing and Resumable SSR framework.</title>
      <dc:creator>Yisar</dc:creator>
      <pubDate>Sat, 22 Oct 2022 04:15:46 +0000</pubDate>
      <link>https://dev.to/132/asta-new-jointing-and-resumable-ssr-framework-17m5</link>
      <guid>https://dev.to/132/asta-new-jointing-and-resumable-ssr-framework-17m5</guid>
      <description>&lt;p&gt;Hello everyone, I am Yisar, a Javascript developer from China.&lt;/p&gt;

&lt;p&gt;In China, there are few &lt;code&gt;web pages&lt;/code&gt;, but just three months ago, I joined a game company. We have foreign websites and some foreign users.&lt;/p&gt;

&lt;p&gt;I led our team to start the SSR transformation of our website, but finally failed because the QPS is too low.&lt;/p&gt;

&lt;p&gt;This is because the &lt;code&gt;SSR isomorphism&lt;/code&gt; requires the generation and traversal of vdom, and the server side cannot afford such computation.&lt;/p&gt;

&lt;p&gt;No matter vue or react, or even preact or svelte, they all face the same difficulties.&lt;/p&gt;

&lt;p&gt;Is there really no way？&lt;/p&gt;

&lt;h3&gt;
  
  
  Asta.js
&lt;/h3&gt;

&lt;p&gt;Finally, I decided to write a new framework to optimize the characteristics of SSR, with the goal of solving the performance bottleneck of SSR.&lt;/p&gt;

&lt;p&gt;It is meaningless to discuss performance beyond bottlenecks. If we want to optimize, we should start with performance bottlenecks&lt;/p&gt;

&lt;h4&gt;
  
  
  Server side bottlenecks, Jointing on Server
&lt;/h4&gt;

&lt;p&gt;The biggest performance bottleneck of SSR lies in the server side. The server is very fragile. The traditional homogeneous SSR framework requires the generation and traversal of vdom, which brings pressure on the CPU. If the experience is not enough, it is also easy to leak memory.&lt;/p&gt;

&lt;p&gt;To solve this problem, Asta has a jsx compiler, which no longer generates vdom, but now generates s functions for string splicing.&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="c1"&gt;// jsx input&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;view&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/i&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="sr"&gt;}&amp;lt;/&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="c1"&gt;// server output&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;view&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;openTag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;div&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;expression&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;openTag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;i&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;closeTag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;i&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;closeTag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;div&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It does not need babel, and perfectly retains the semantics of js.&lt;/p&gt;

&lt;p&gt;It is worth mentioning that this is also completely feasible at the data structure level. All tree structures can be expressed through linear structures.&lt;/p&gt;

&lt;p&gt;The second performance bottleneck on the server side is the component itself. The initialization, private state (usually publish and subscribe), and lifecycle of the component are huge performance overhead and difficult to be optimized by the compiler.&lt;/p&gt;

&lt;p&gt;To solve this problem, Asta uses Elm's state flow model. The component itself has no state, and all states flow from the global single state tree from top to bottom.&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="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;loader&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http://localhost:1234/data&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Header&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;title&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;header&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/header&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;title&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Header&lt;/span&gt; &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&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;Yes, components are also pure functions, which are only used to splice strings without any overhead.&lt;/p&gt;

&lt;h4&gt;
  
  
  Pressure test results.
&lt;/h4&gt;

&lt;p&gt;After these two optimizations, the performance of asta is super good. We pressure tested a simple application with an interface in the company, and the results are as follows.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--OfKT5ioZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5o0pxryq3z38nw6vfrg5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--OfKT5ioZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5o0pxryq3z38nw6vfrg5.png" alt="Image description" width="880" height="581"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Because Vue3 has the template compilation optimization of block tree, its QPS is higher than nextjs, but it still cannot avoid component overhead.&lt;/p&gt;

&lt;p&gt;Asta's QPS is amazing. It's even much higher than Markojs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Resumable on client
&lt;/h3&gt;

&lt;p&gt;We have solved the performance bottleneck on the server side. We begin to focus on the client side. The performance cost of traditional SSR lies in full hydration.&lt;/p&gt;

&lt;p&gt;A new concept named &lt;code&gt;Resumable&lt;/code&gt; comes from Qwik.js, its basic idea is not to hydrate, serialize the necessary information into html, and then use vdom and dom on the client side to diff to directly recover the information.&lt;/p&gt;

&lt;p&gt;Resumable&lt;/p&gt;

&lt;p&gt;It is very suitable for the mental model of asta, so I implemented it easily.&lt;/p&gt;

&lt;p&gt;In addition, in order to reduce the size of the client side js, people have also come up with other methods, such as selective hydration, islands, server components. However, the mental models are too corrupt, so we won't discuss them one by one.&lt;/p&gt;

&lt;p&gt;Resumable is better at 0 js and Google scoring.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--EZtZdtyC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n9rk128n9dowt66v6b9k.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--EZtZdtyC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n9rk128n9dowt66v6b9k.jpg" alt="Image description" width="618" height="587"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Summary
&lt;/h3&gt;

&lt;p&gt;To sum up, after double optimization, asta has no bottleneck in its performance. It is open source. The github address is here.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/yisar/asta"&gt;https://github.com/yisar/asta&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you are interested, you can run the demo to try, and you will understand.&lt;/p&gt;

&lt;p&gt;I am a Chinese, so I may not use English all the time, but I also welcome exchanges.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>2021 JavaScript framework</title>
      <dc:creator>Yisar</dc:creator>
      <pubDate>Mon, 23 Aug 2021 03:45:32 +0000</pubDate>
      <link>https://dev.to/132/2021-javascript-framework-2d0e</link>
      <guid>https://dev.to/132/2021-javascript-framework-2d0e</guid>
      <description>&lt;p&gt;2021 is very different from previous years. Many web frameworks have released their new versions. Let's discuss them.&lt;/p&gt;

&lt;h3&gt;
  
  
  Vdom-based
&lt;/h3&gt;

&lt;p&gt;For example, React, Vue and Preact all belong to this category.&lt;/p&gt;

&lt;p&gt;This is also the most mature framework. Their advantages are mature, stable and suitable for most scenarios.&lt;/p&gt;

&lt;p&gt;With SSR and partial hydration, react 18's fizz renderer is very interesting.&lt;/p&gt;

&lt;p&gt;In addition, such as concurrent mode, scheduling optimization has been discussed for many years.&lt;/p&gt;

&lt;p&gt;Fre is a little soldier in this camp. It is the smallest but the fastest.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/yisar/fre"&gt;https://github.com/yisar/fre&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Compilation instead of runtime
&lt;/h3&gt;

&lt;p&gt;Svelte, solidjs belongs to this category.&lt;/p&gt;

&lt;p&gt;I always think that the web does not need to be optimized to the extreme, but the code architecture needs to be pursued unilaterally.&lt;/p&gt;

&lt;p&gt;So I prefer Svelte a bit. Compilation and runtime should not coexist, which will make the framework more messy and mediocre.&lt;/p&gt;

&lt;p&gt;Solidjs and Vue3 do not do this well. They have compilation and want to runtime. They can't have both fish and bear's paw.&lt;/p&gt;

&lt;h3&gt;
  
  
  Html first
&lt;/h3&gt;

&lt;p&gt;History is reversing，recently, some frameworks want to return to HTML, away from vdom and away from compilation.&lt;/p&gt;

&lt;p&gt;Such as Qwikjs and Alpinejs. They are enhancing HTML, Sprinkling intead of Hydration.&lt;/p&gt;

&lt;p&gt;This does fill a part of the cake, but the performance will be lost. For example, alpine has always ranked last in the benchmark.&lt;/p&gt;

&lt;h3&gt;
  
  
  Summary
&lt;/h3&gt;

&lt;p&gt;I like all three ideas. How about you?&lt;/p&gt;

&lt;p&gt;Using one of them is entirely determined by my work.&lt;/p&gt;

</description>
      <category>react</category>
      <category>vue</category>
      <category>svelte</category>
      <category>solidjs</category>
    </item>
    <item>
      <title>I never need webpack or babel anymore</title>
      <dc:creator>Yisar</dc:creator>
      <pubDate>Wed, 28 Jul 2021 02:39:06 +0000</pubDate>
      <link>https://dev.to/132/i-never-need-webpack-or-babel-anymore-3o45</link>
      <guid>https://dev.to/132/i-never-need-webpack-or-babel-anymore-3o45</guid>
      <description>&lt;p&gt;In the past period of time, I was refactoring our company’s miniapp compiler, Its performance has increased by more than ten times.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use Esbuild
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Replace webpack or rollup
&lt;/h3&gt;

&lt;p&gt;What's interesting, using esbuild and webpack are almost the same.&lt;/p&gt;

&lt;h4&gt;
  
  
  webpack node api
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;webpack&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;webpack&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;webpack&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./src/index.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;__dirname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dist&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;[name].js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nx"&gt;run&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;stats&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&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;esbuild node api&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;esbuild&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;esbuild&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;esbuild&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;build&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;entryPoints&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cwd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;src&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;app.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)],&lt;/span&gt;
  &lt;span class="na"&gt;outdir&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cwd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dist&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="na"&gt;bundle&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;They are no different in use, but esbuild is much faster than webpack.&lt;/p&gt;

&lt;p&gt;In most places where you use webpack, you can use esbuild instead.&lt;/p&gt;

&lt;h3&gt;
  
  
  Replace jest
&lt;/h3&gt;

&lt;p&gt;In my open source framework fre, I use &lt;code&gt;playwright + zora + esbuild&lt;/code&gt; as the test toolkits, and its experience is very smooth.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/yisar/fre/tree/master/test"&gt;https://github.com/yisar/fre/tree/master/test&lt;/a&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="nx"&gt;before&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="nx"&gt;puppeteer&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;jest&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;

&lt;span class="nx"&gt;after&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="nx"&gt;playwright&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;zora&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;esbuild&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Replace terser
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/privatenumber/minification-benchmarks"&gt;https://github.com/privatenumber/minification-benchmarks&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Using esbuild as a compressor for large projects can improve a lot of performance.&lt;/p&gt;

&lt;h3&gt;
  
  
  Replace next.js
&lt;/h3&gt;

&lt;p&gt;We have a new alternative within our company, which uses esbuild throughout the toolchain, and the development experience is much better than next.js.&lt;/p&gt;

&lt;h3&gt;
  
  
  Disadvantages of esbuild
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;AST operation is not supported&lt;/li&gt;
&lt;li&gt;Generating d.ts is not supported&lt;/li&gt;
&lt;li&gt;No go API provided&lt;/li&gt;
&lt;li&gt;The generated runtime code is dirty&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After we use esbuild in depth, we find it has many disadvantages, so it is impossible to use esbuild alone.&lt;/p&gt;

&lt;p&gt;Some people use rollup, such as the vite team, but I don't think it's worth it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use Swc
&lt;/h2&gt;

&lt;p&gt;This is another tool written using rust, which can make up for some shortcomings of esbuild.&lt;/p&gt;

&lt;h3&gt;
  
  
  Replace babel
&lt;/h3&gt;

&lt;p&gt;A common practice is to modify AST in rust side, and then pass the results to node side through wasm.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/parcel-bundler/parcel/blob/v2/packages/transformers/js/core/src/hoist.rs"&gt;https://github.com/parcel-bundler/parcel/blob/v2/packages/transformers/js/core/src/hoist.rs&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For example, that's what parcel v2 does.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Most of the time, esbuild is enough. swc can be used when the AST needs to be modified, but anyway, I don't need webpack or babel anymore.&lt;/p&gt;

&lt;p&gt;More and more similar tools will appear in the front-end tool chain in the future. They are written in go or rust, and they are very fast and smooth.&lt;/p&gt;

&lt;p&gt;I love this change very much.&lt;/p&gt;

</description>
      <category>webpack</category>
      <category>babel</category>
    </item>
    <item>
      <title>Fre-2.1 has been pulished</title>
      <dc:creator>Yisar</dc:creator>
      <pubDate>Fri, 11 Jun 2021 06:10:36 +0000</pubDate>
      <link>https://dev.to/132/fre-2-1-and-react-18-have-been-pulished-what-s-the-difference-between-them-22o8</link>
      <guid>https://dev.to/132/fre-2-1-and-react-18-have-been-pulished-what-s-the-difference-between-them-22o8</guid>
      <description>&lt;p&gt;I announce that fre2 is officially released, which is a major breakthrough version. &lt;/p&gt;

&lt;h3&gt;
  
  
  Offscreen rendering
&lt;/h3&gt;

&lt;p&gt;The bigist breakthrough is offscreen rendering, a core algorithm refactor.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/yisar/fre/releases/tag/2.1.0-alpha" rel="noopener noreferrer"&gt;https://github.com/yisar/fre/releases/tag/2.1.0-alpha&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;before: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F9901lyz1u8jf3fdxjnnu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F9901lyz1u8jf3fdxjnnu.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;after:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fs4t64ak13u5epdhqmcal.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fs4t64ak13u5epdhqmcal.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Offscreen rendering is an algorithm level optimization, it traverses vdom in reverse order, from bottom to top, from right to left, to ensure that the front DOM pointer is in memory, and finally it is drawn to the screen at one time.&lt;/p&gt;

&lt;p&gt;With off screen rendering, fre has become the best performance frameworks in vdom world, not one of.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fx013ik3ur173xn41pu4q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fx013ik3ur173xn41pu4q.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Just as react 18 also released alpha version, fre 2.1 also tried to be compatible with them.&lt;/p&gt;

&lt;h3&gt;
  
  
  CreateRoot
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fre&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;+&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;createRoot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// here&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This API is more ergonomic, and for the callback, you can do this:&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;callback&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Hello&lt;/span&gt; &lt;span class="nx"&gt;World&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;createRoot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;renderered&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt; &lt;span class="sr"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  startTransiton
&lt;/h3&gt;

&lt;p&gt;This is an API for lowering priority, which is very useful, so I decide to build it in.&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 1 2&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;update&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;startTransition&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="nf"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;update&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;+&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It works can be understood as &lt;code&gt;setTimeout (cb, 0)&lt;/code&gt;, but the callback function is executed synchronously, and the update is delayed asynchronously.&lt;/p&gt;

&lt;h3&gt;
  
  
  auto-updates
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/yisar/fre/blob/master/demo/src/auto-batch.tsx" rel="noopener noreferrer"&gt;https://github.com/yisar/fre/blob/master/demo/src/auto-batch.tsx&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Fre has always been supportive.&lt;/p&gt;

&lt;h3&gt;
  
  
  Suspense SSR
&lt;/h3&gt;

&lt;p&gt;This is the only breakthrough of react 18. I like it very much, but fre doesn't support it now. &lt;/p&gt;

&lt;p&gt;I need to spend some time to study it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Summary
&lt;/h3&gt;

&lt;p&gt;Fre2 has also been released. If you are interested in the front-end framework, you can jump to GitHub.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/yisar/fre" rel="noopener noreferrer"&gt;https://github.com/yisar/fre&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It has all the advanced features of react 18, but only 400 lines of code, and its performance is much better than react.&lt;/p&gt;

</description>
      <category>reactnative</category>
      <category>react</category>
      <category>fre</category>
      <category>preact</category>
    </item>
    <item>
      <title>Fre Offscreen rendering: The fastest vdom algorithm</title>
      <dc:creator>Yisar</dc:creator>
      <pubDate>Tue, 08 Jun 2021 03:24:53 +0000</pubDate>
      <link>https://dev.to/132/fre-offscreen-rendering-the-fastest-vdom-algorithm-bfn</link>
      <guid>https://dev.to/132/fre-offscreen-rendering-the-fastest-vdom-algorithm-bfn</guid>
      <description>&lt;p&gt;In the past, I wrote a front-end framework named fre in school, which uses the data structure of fiber linked list. &lt;/p&gt;

&lt;p&gt;In fre v1, the biggest breakthrough is &lt;code&gt;Time slicing&lt;/code&gt;. It can greatly improve the response performance.&lt;/p&gt;

&lt;p&gt;Now that fre2 is released, I've made a breakthrough again. &lt;/p&gt;

&lt;p&gt;It is called &lt;code&gt;Offscreen rendering&lt;/code&gt;. It operates DOM in memory and draws them to the screen once at the last time.&lt;/p&gt;

&lt;p&gt;In the actual benchmark test, Fre is the fastest, it broke the rules of the game.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fl0avbvvhe6f1ykz8lrf5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fl0avbvvhe6f1ykz8lrf5.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the past, we always thought that frameworks with vdom could not be faster than vanilla JS, while svelte's idea could be close to the performance of vanilla JS.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/yisar/fre/blob/master/demo/src/benchmark.tsx" rel="noopener noreferrer"&gt;https://github.com/yisar/fre/blob/master/demo/src/benchmark.tsx&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Fre with off-screen rendering breaks this fact. I'm proud to say that fre is the fastest vdom-based framework, and it's only 400 lines, the smallest size.&lt;/p&gt;

&lt;p&gt;It is worth mentioning that this is a highly optimized data structure and core algorithm. &lt;/p&gt;

&lt;p&gt;And it does not conflict with time slicing and does not depend on the 'DocumentFragment' API.&lt;/p&gt;

&lt;p&gt;In fact, similar optimizations always exist in IOS or OpenGL. It's not easy for web to do this, so fre is the first framework to implement it.&lt;/p&gt;

&lt;p&gt;I don't want to introduce too many implementation details of off-screen rendering. If you are interested in this, you can reply to it or read the source code of fre.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/yisar/fre" rel="noopener noreferrer"&gt;https://github.com/yisar/fre&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I really hope to get your feedback, because I am a Chinese, usually in school or company, no one can discuss these with me, I can only study alone.&lt;/p&gt;

&lt;p&gt;Thank you very much!&lt;/p&gt;

</description>
      <category>react</category>
      <category>vue</category>
      <category>fre</category>
      <category>preact</category>
    </item>
    <item>
      <title>Use isInputPending API for better scheduler</title>
      <dc:creator>Yisar</dc:creator>
      <pubDate>Tue, 02 Feb 2021 03:00:34 +0000</pubDate>
      <link>https://dev.to/132/use-isinputpending-api-for-better-scheduler-4jm1</link>
      <guid>https://dev.to/132/use-isinputpending-api-for-better-scheduler-4jm1</guid>
      <description>&lt;p&gt;As you know, fre is an asynchronous rendering UI library that similar to react. The rendering process of components can be interrupted&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--E6RELOg5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/eukgex19swroryye32ux.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--E6RELOg5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/eukgex19swroryye32ux.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The priority scheduling of react first enumerates and classifies events, which is too much code.&lt;/p&gt;

&lt;p&gt;How can fre implement priority without enumerating event names?&lt;/p&gt;

&lt;h3&gt;
  
  
  isInputPending()
&lt;/h3&gt;

&lt;p&gt;Inspired by react fiber, Facebook has written a proposal that when the browser is in the input pending state, you can interrupt your JS loop&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="k"&gt;while&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;scheduling&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isInputPending&lt;/span&gt;&lt;span class="p"&gt;()){&lt;/span&gt;
  &lt;span class="nx"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;reconcileWork&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;open&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;tick&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We also can use this API to divide priorities, such as this:&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="nx"&gt;dom&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;input&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;isHighPriority&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;scheduling&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isInputPending&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;isHighPriority&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;It's done. We have a priority system with just one API.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/yisar/fre/pull/226"&gt;https://github.com/yisar/fre/pull/226&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At present, it has been shipped in fre, and we will do more based on it in the future.&lt;/p&gt;

&lt;p&gt;It's worth mentioning that fre now has three priorities&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;high priority =&amp;gt; input pending =&amp;gt; immediately&lt;/li&gt;
&lt;li&gt;common priority =&amp;gt; time slicing =&amp;gt; 16ms &lt;/li&gt;
&lt;li&gt;low priority =&amp;gt; component update =&amp;gt; It's been interrupted&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you are interested in asynchronous rendering or react internal implementation principles, welcome to fre's GitHub&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/yisar/fre"&gt;https://github.com/yisar/fre&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>fre</category>
      <category>chrome</category>
      <category>facebook</category>
    </item>
    <item>
      <title>Update granularity of Javascripts frameworks</title>
      <dc:creator>Yisar</dc:creator>
      <pubDate>Sun, 31 Jan 2021 11:38:19 +0000</pubDate>
      <link>https://dev.to/132/update-granularity-of-javascripts-frameworks-58kj</link>
      <guid>https://dev.to/132/update-granularity-of-javascripts-frameworks-58kj</guid>
      <description>&lt;p&gt;Do you know that the update granularity of different Javascript frameworks is different? Let's talk about it in detail.&lt;/p&gt;

&lt;h3&gt;
  
  
  Coarse grained
&lt;/h3&gt;

&lt;p&gt;Almost all the framework updates based on vdom are coarse-grained. The unit they update is component, and then the whole component will be re rendered for reconciliation.&lt;/p&gt;

&lt;p&gt;Such as react, fre……&lt;/p&gt;

&lt;p&gt;There are the advantages of vdom, but it will cause unnecessary updates. The react team says that the performance of JS runtime is negligible, so the coarse-grained update of vdom has always been a good way.&lt;/p&gt;

&lt;p&gt;I agree with this option, because if it is not for coarse-grained update, asynchronous rendering will not be easy, and the essence of concurrent mode is repeated parallel rendering.&lt;/p&gt;

&lt;h3&gt;
  
  
  Fine grained
&lt;/h3&gt;

&lt;p&gt;Some proxy based frameworks are fine-grained. Such as svelte, vue1. They hijack the keys of state and can update them accurately.&lt;/p&gt;

&lt;p&gt;This is a good idea most of the time, but when there is a long list, too many proxies will be generated, and the performance will be degraded.&lt;/p&gt;

&lt;h3&gt;
  
  
  Block grained
&lt;/h3&gt;

&lt;p&gt;This is a compromise, that is, when a block is encountered, the runtime is used for reconciliation.&lt;/p&gt;

&lt;p&gt;Such as vue3:&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;item in items&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;item.key&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;output like this:&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="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The for function is a runtime function that performs internal reconciliation.&lt;/p&gt;

&lt;h3&gt;
  
  
  trade off
&lt;/h3&gt;

&lt;p&gt;Three different granularity are good and bad, as a framework, the author should weigh the choice.&lt;/p&gt;

&lt;p&gt;Fre uses vdom, so its updates are coarse-grained, which is more conducive to asynchronous rendering.&lt;/p&gt;

&lt;p&gt;But I think that for frameworks like svelte, using block granularity is the best, because many algorithms are runtime optimizations.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/yisar/fre"&gt;https://github.com/yisar/fre&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, if you are interested in the new framework, take a look at fre.&lt;/p&gt;

</description>
      <category>react</category>
      <category>svelte</category>
      <category>vue</category>
      <category>fre</category>
    </item>
    <item>
      <title>Start using time slicing through fre.js</title>
      <dc:creator>Yisar</dc:creator>
      <pubDate>Sat, 09 Jan 2021 11:43:26 +0000</pubDate>
      <link>https://dev.to/132/start-using-time-slicing-through-fre-js-3gom</link>
      <guid>https://dev.to/132/start-using-time-slicing-through-fre-js-3gom</guid>
      <description>&lt;p&gt;Do you know time slicing? &lt;/p&gt;

&lt;p&gt;This is an amazing thing in react concurrent mode, which shows that the browser will not be blocked by component rendering.&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;h&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useEffect&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fre&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;UPDATE_EVERY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;BLOCK_FOR&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;NUM_COMPONENTS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;UPDATE_EVERY&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;values&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;NUM_COMPONENTS&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;values&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;wraper&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;Count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;values&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;SlowComponent&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="p"&gt;))}&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;SlowComponent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;performance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;performance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;start&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;BLOCK_FOR&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;li&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;slow&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/li&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;root&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;root&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;div&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`&amp;lt;style&amp;gt;
body {
  background: #010911;
  font-family: sans-serif;
}
h1 {
  color: rgb(0, 204, 10);
}
#animation {
  width: 380px;
  height: 380px;
  transform: translate(50%, 50%);
  margin: 20px auto;
}
.slow {
  background: #f60066;
  color: white;
  padding: 5px;
  display: inline-block;
  margin: 5px;
  font-size: 12px;
  border-radius: 50%;
}
.wraper{
  margin: 20px auto;
  width: 700px;
  text-align: center;
}
ul.solarsystem {
  position: relative;
  height: 400px;
  list-style: none;
  transition: all 0.09s ease-in;
  transform: translate(-480px, -336px);
}
ul.solarsystem li {
  text-indent: -9999px;
  display: block;
  position: absolute;
  border: 2px solid #394057;
}
ul.solarsystem li span {
  display: block;
  position: absolute;
  width: 10px;
  height: 10px;
  border-radius: 5px;
}
ul.solarsystem li.active.sun span,
ul.solarsystem li.active.earth .moon {
  border: none;
  box-shadow: none;
}
ul.solarsystem li.sun {
  width: 40px;
  height: 40px;
  border-radius: 20px;
  background: #fc3;
  background-image: gradient(linear,
      left bottom,
      left top,
      color-stop(0.22, rgb(204, 153, 0)),
      color-stop(1, rgb(255, 219, 112)));
  top: 302px;
  left: 462px;
  border: none;
  box-shadow: 0 0 50px #c90;
  z-index: 100;
  transition: all 0.2s ease-in;
}
ul.solarsystem li.sun span {
  width: 60px;
  height: 60px;
  border-radius: 50%;
}
ul.solarsystem li.mercury {
  width: 100px;
  height: 100px;
  border-radius: 52px;
  top: 270px;
  left: 430px;
  z-index: 99;
}
ul.solarsystem li.mercury span {
  background: #b6bac5;
  top: 10px;
  left: 10px;
}
ul.solarsystem li.venus {
  width: 160px;
  height: 160px;
  border-radius: 82px;
  top: 240px;
  left: 400px;
  z-index: 98;
}
ul.solarsystem li.venus span {
  background: #bf8639;
  top: 118px;
  left: 5px;
}
ul.solarsystem li.earth {
  width: 220px;
  height: 220px;
  border-radius: 112px;
  top: 210px;
  left: 370px;
  z-index: 97;
}
ul.solarsystem li.earth span {
  background: #06c;
  top: 56px;
  left: 5px;
}
ul.solarsystem li.earth span.moon {
  width: 4px;
  height: 4px;
  border-radius: 2px;
  background: #ccc;
  top: 12px;
  left: 12px;
}
ul.solarsystem li.mars {
  width: 280px;
  height: 280px;
  border-radius: 142px;
  top: 180px;
  left: 340px;
  z-index: 96;
}
ul.solarsystem li.mars span {
  background: #aa4200;
  top: 0px;
  left: 175px;
}
ul.solarsystem li.asteroids_meteorids {
  top: 155px;
  left: 315px;
  z-index: 1;
  width: 330px;
  height: 330px;
  border-radius: 165px;
  border: none;
}
ul.solarsystem li.jupiter {
  width: 340px;
  height: 340px;
  border-radius: 172px;
  top: 150px;
  left: 310px;
  z-index: 95;
}
ul.solarsystem li.jupiter span {
  background: #e0ae6f;
  top: 67px;
  left: 24px;
}
ul.solarsystem li,
ul.solarsystem li.earth span {
  animation-iteration-count: infinite;
  animation-timing-function: linear;
  animation-name: orbit;
}
ul.solarsystem li.mercury {
  animation-duration: 5s;
}
ul.solarsystem li.venus {
  animation-name: retrograde;
  animation-duration: 8s;
}
ul.solarsystem li.earth {
  animation-duration: 12s;
}
ul.solarsystem li.earth span {
  animation-duration: 2s;
}
ul.solarsystem li.mars {
  animation-duration: 20s;
}
ul.solarsystem li.asteroids_meteorids {
  animation-duration: 50s;
}
ul.solarsystem li.jupiter {
  animation-duration: 30s;
}
@keyframes orbit {
  from {
    transform: rotate(0deg);
    color: white;
    font-size: 200%;
  }
  to {
    transform: rotate(360deg);
    color: black;
    font-size: 50%;
  }
}
@keyframes retrograde {
  from {
    transform: rotate(0deg);
    color: white;
    font-size: 200%;
  }
  to {
    transform: rotate(-360deg);
    color: black;
    font-size: 50%;
  }
}
&amp;lt;/style&amp;gt;
&amp;lt;div id="animation"&amp;gt;
&amp;lt;ul class="solarsystem"&amp;gt;
  &amp;lt;li class="sun"&amp;gt;&amp;lt;span&amp;gt;Sun&amp;lt;/span&amp;gt;&amp;lt;/li&amp;gt;
  &amp;lt;li class="mercury"&amp;gt;&amp;lt;span&amp;gt;Mercury&amp;lt;/span&amp;gt;&amp;lt;/li&amp;gt;
  &amp;lt;li class="venus"&amp;gt;&amp;lt;span&amp;gt;Venus&amp;lt;/span&amp;gt;&amp;lt;/li&amp;gt;
  &amp;lt;li class="earth"&amp;gt;&amp;lt;span&amp;gt;Earth&amp;lt;span class="moon"&amp;gt;Moon&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;
  &amp;lt;/li&amp;gt;
  &amp;lt;li class="mars"&amp;gt;&amp;lt;span&amp;gt;Mars&amp;lt;/span&amp;gt;&amp;lt;/li&amp;gt;
  &amp;lt;li class="asteroids_meteorids"&amp;gt;&amp;lt;span&amp;gt;Asteroids&amp;lt;/span&amp;gt;&amp;lt;/li&amp;gt;
  &amp;lt;li class="jupiter"&amp;gt;&amp;lt;span&amp;gt;Jupiter&amp;lt;/span&amp;gt;&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;
&amp;lt;/div&amp;gt;`&lt;/span&gt;

&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;insertBefore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;root&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;root&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this demo, CSS animation is running all the time. If you use the synchronous framework such as preact or vue, you will feel obvious stuck jank.&lt;/p&gt;

&lt;p&gt;But if you use fre or react, you can keep a consistent response, which is very important.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why?
&lt;/h3&gt;

&lt;p&gt;As we all know, microtask clears the queue before the browser's layout, while Vue and preact update their components in microtask.&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="c1"&gt;// vue&lt;/span&gt;
&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;updateComponent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// atter a b updated&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;They use the fetures of microtask to achieve batch updates, but also block the browser because of the feature of microtask.&lt;/p&gt;

&lt;p&gt;In fre (or react), rendering is asynchronous, which makes use of the feature that macro tasks don't block the browser to do time slicing.&lt;/p&gt;

&lt;p&gt;Fre fiber implements a lightweight rendering engine, which uses vdom to generate linked list, interrupts and continues in the traversal of linked list, giving the browser the chance to repaint.&lt;/p&gt;

&lt;h3&gt;
  
  
  Useful?
&lt;/h3&gt;

&lt;p&gt;We heard a voice that the preact and vue teams don't like time slicing. They think there are very few scenes of time slicing.&lt;/p&gt;

&lt;p&gt;But believe me, time slicing is very useful. In addition to animation, it can also do visualization related work.&lt;/p&gt;

&lt;p&gt;In addition, do you know the situation of react native, a non web platform? It doesn't have as good performance and memory as web. Without time slicing, animation will be difficult.&lt;/p&gt;

&lt;h3&gt;
  
  
  Others
&lt;/h3&gt;

&lt;p&gt;In addition to the value of time slice, its research significance is greater. Fiber rendering engine is a new exploration, there are many things to do, I need partners.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/yisar/fre"&gt;https://github.com/yisar/fre&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you have a good idea, please let me know.&lt;/p&gt;

</description>
      <category>react</category>
      <category>vue</category>
      <category>preact</category>
      <category>fre</category>
    </item>
    <item>
      <title>Fre: another concurrent UI library</title>
      <dc:creator>Yisar</dc:creator>
      <pubDate>Fri, 08 Jan 2021 06:10:33 +0000</pubDate>
      <link>https://dev.to/132/fre-another-concurrent-ui-library-1jph</link>
      <guid>https://dev.to/132/fre-another-concurrent-ui-library-1jph</guid>
      <description>&lt;p&gt;Hello everyone, my name is yisar, a front-end enginer in China.&lt;/p&gt;

&lt;p&gt;This is my first visit to media, and I want to share my framework with you.&lt;/p&gt;

&lt;p&gt;React is very popular, especially after react 16. The most amazing thing is concurrent mode, which is not available in other frameworks.&lt;/p&gt;

&lt;p&gt;Fre is the second framework to implement concurrent mode in addition to react. This implementation is different from the other vdom reconciliation algorithm. Its rendering is asynchronous, and many use cases are built on the premise of asynchronous rendering.&lt;/p&gt;

&lt;p&gt;Fre is similar to react in many ways, such as fiber architecture using linked list, hooks API and functional component…&lt;/p&gt;

&lt;p&gt;But at the same time, they are different. Fre has a better reconciliation algorithm. The most important thing is that fre only has 400 lines of code, the bundle size is just 1KB!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fqlwvh74jddfe3qviqab9.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fqlwvh74jddfe3qviqab9.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In most use cases, the performance of fre is close to that of vue3 and better than that of react.&lt;/p&gt;

&lt;p&gt;At the same time, 1KB of code means that you can better understand the source code of fre, and even learn react with the help from fre.&lt;/p&gt;

&lt;p&gt;It is worth mentioning that preact is as small as fre, but preact is completely synchronous. It does not support concurrent mode and keeps the opposite roadmap with react.&lt;/p&gt;

&lt;p&gt;If you are looking for an alternative framework of 1KB react, fre is more suitable for you.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F80uqd52t4470e0jn79ha.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F80uqd52t4470e0jn79ha.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you’re interested in concurrent mode, take a look at fre and you’ll get a ruby.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/yisar/fre" rel="noopener noreferrer"&gt;https://github.com/yisar/fre&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I really need partners, because fre has a lot to improve, let’s build together.&lt;/p&gt;

</description>
      <category>react</category>
      <category>vue</category>
      <category>preact</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
