<?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: Dmitry Shatokhin</title>
    <description>The latest articles on DEV Community by Dmitry Shatokhin (@dmtrshat).</description>
    <link>https://dev.to/dmtrshat</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%2F362987%2F2536e8ff-7687-4f06-a139-9b2a1a0d3e88.png</url>
      <title>DEV Community: Dmitry Shatokhin</title>
      <link>https://dev.to/dmtrshat</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/dmtrshat"/>
    <language>en</language>
    <item>
      <title>When changes are too expensive: JavaScript and data change performance.</title>
      <dc:creator>Dmitry Shatokhin</dc:creator>
      <pubDate>Mon, 02 Oct 2023 02:35:27 +0000</pubDate>
      <link>https://dev.to/dmtrshat/when-changes-are-too-expensive-javascript-and-data-change-performance-2dl4</link>
      <guid>https://dev.to/dmtrshat/when-changes-are-too-expensive-javascript-and-data-change-performance-2dl4</guid>
      <description>&lt;p&gt;Approaches to data processing and manipulation remain one of the key aspects of software development.&lt;br&gt;
&lt;em&gt;Immunability&lt;/em&gt;, &lt;em&gt;reactivity&lt;/em&gt;, and &lt;em&gt;mutability&lt;/em&gt; are key strategies in data state management, and choosing between them can significantly affect application performance.,&lt;/p&gt;

&lt;p&gt;In JavaScript, the importance of choosing an approach to data processing is closely related to the features of this language and the scope of its application. JavaScript is primarily used to develop the client side of web applications, where performance is a key factor. The user experience directly depends on how quickly and efficiently the application processes and displays data.&lt;/p&gt;

&lt;p&gt;Immunability in JavaScript can be quite expensive. Every time the state changes, a new object is created, which leads to increased memory usage and load on the garbage collector. In a language with dynamic typing and automatic memory management, such operations can affect performance significantly more than, for example, in languages with static typing and manual memory management.&lt;/p&gt;

&lt;p&gt;In front-end JavaScript, the problem of immunability is getting worse. The user interface often requires a lot of state updates, which in the case of immutability can lead to the creation of a large number of objects and, accordingly, to an increased load on the processor and memory. Such resource costs in the context of a browser, where available resources are usually limited, can lead to lower performance and a worse user experience.&lt;/p&gt;

&lt;p&gt;Nevertheless, despite its &lt;em&gt;"cost"&lt;/em&gt;, immutability continues to be popular in the JavaScript world. One example is the &lt;strong&gt;Redux&lt;/strong&gt; state management library, where immunability is used to ensure predictability and simplify tracking of state changes. Immunability can facilitate the development process by providing clear and unambiguous rules for changing the state, which can be very valuable in complex applications with a large number of interdependencies.&lt;/p&gt;

&lt;p&gt;And what about the mutable approach? For example - &lt;strong&gt;MobX&lt;/strong&gt;. This library is regarded by many as an analogue of Redux, but from the camp of a mutable approach. However, you can often hear that Redux has more performance than &lt;strong&gt;MobX&lt;/strong&gt;, which contradicts what we talked about. After all, in a mutable approach, we simply change the value in memory.&lt;/p&gt;

&lt;p&gt;For example, I wrote 2 versions of a simple &lt;strong&gt;React&lt;/strong&gt; application. One using &lt;strong&gt;Redux&lt;/strong&gt;, the other with &lt;strong&gt;MobX&lt;/strong&gt;. In all other respects, they are completely identical. The application is a background counter that is updated 1 time per second. A button that changes color by hover. And a simulation of sending N files to the server. When sending information changes, it should be updated in the interface. Sending occurs asynchronously and starts at different times for everyone, with random file size. This application lacks a complex interface and so on, but it demonstrates well the user's need to use the application while something is being done in the background (I will provide access to each application at the end of the article).&lt;/p&gt;

&lt;p&gt;Here is the result when sending &lt;strong&gt;50&lt;/strong&gt; files.&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%2Fces6gf802zgdwvy1i4i7.gif" 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%2Fces6gf802zgdwvy1i4i7.gif" alt="upload 50 files with redux" width="800" height="400"&gt;&lt;/a&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%2Fh7icim6ueziuj7z964m2.gif" 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%2Fh7icim6ueziuj7z964m2.gif" alt="upload 50 files with mobx" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are no differences in performance here. The main counter changes 1 time per second. The color change and text highlighting are triggered. Updating information is not lagging.&lt;/p&gt;

&lt;p&gt;When sending &lt;strong&gt;100&lt;/strong&gt; files, the lags are already noticeable.&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%2Fyy35scrlodpq7ufgahpw.gif" 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%2Fyy35scrlodpq7ufgahpw.gif" alt="upload 100 files with redux" width="600" height="1536"&gt;&lt;/a&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%2Fisq6gv78uww91809l6ek.gif" 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%2Fisq6gv78uww91809l6ek.gif" alt="upload 100 files with mobx" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When sending &lt;strong&gt;500&lt;/strong&gt; files, the application can no longer be used, and it makes no sense to test with a larger number of files.&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%2Fo6vskzlag6rz716zgyoi.gif" 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%2Fo6vskzlag6rz716zgyoi.gif" alt="upload 500 files with redux" width="600" height="1536"&gt;&lt;/a&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%2Fkuz5dthhndxuu85ptuq6.gif" 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%2Fkuz5dthhndxuu85ptuq6.gif" alt="upload 500 files with mobx" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you look to measure the execution time of the update function, it turns out that &lt;strong&gt;Redux&lt;/strong&gt; is really faster than &lt;strong&gt;MobX&lt;/strong&gt;. But with the increase in the number of files, this difference is greatly reduced.&lt;/p&gt;

&lt;p&gt;It turns out that mutability is no faster than immunability? What is the point of realizing that an application with &lt;strong&gt;MobX&lt;/strong&gt; works faster than the same application with &lt;strong&gt;Redux&lt;/strong&gt;, if both of them cannot be used?&lt;br&gt;
In fact, &lt;strong&gt;MobX&lt;/strong&gt; has tried to combine reactivity and mutability and performs too many calculations for this. In &lt;strong&gt;MobX&lt;/strong&gt;, a state change can cause side effects in other parts of the application through mechanisms such as observables and reactions. This means that when a state changes (mutates), all parts of the system that depend on this state automatically react to these changes. In addition, the &lt;code&gt;observer&lt;/code&gt; function imposes additional costs and in console or server JavaScript - &lt;strong&gt;MobX&lt;/strong&gt; will be more productive than in the frontend. &lt;/p&gt;

&lt;p&gt;Then how to make it better? How to make sure that our application does not lag, and we can send 500 files without harm?&lt;/p&gt;

&lt;p&gt;Let's take into account the development environment, in our case, &lt;strong&gt;JavaScript&lt;/strong&gt;. &lt;em&gt;Many argue for immutability, and they have valid points. However, it is foolish to disregard the impact it has on performance in JavaScript. Therefore, it may not be the optimal solution to the problem.&lt;/em&gt; &lt;br&gt;
And the problem is a &lt;strong&gt;safe state&lt;/strong&gt; with a &lt;strong&gt;clear data flow&lt;/strong&gt;. &lt;br&gt;
&lt;strong&gt;Mutability&lt;/strong&gt; - does not guarantee that some value in the code will be accidentally redefined, etc. And it's true. But JavaScript is a language that actively uses mutability within itself. It turns out there is a way to track changes in entities. This method is a &lt;code&gt;Proxy&lt;/code&gt;. &lt;code&gt;Proxy&lt;/code&gt; is used to define user behaviors on objects and allows you to create various types of traps for objects. But &lt;strong&gt;MobX&lt;/strong&gt; uses a &lt;code&gt;Proxy&lt;/code&gt;! Yes, but with reservations. Let's just say &lt;code&gt;Proxy&lt;/code&gt; is used there more for other things than for state control.&lt;br&gt;
Libraries for state management are often regarded as a place where you need to shove all the business logic. From this, the vector of the library's purpose shifts from the original one - state management.&lt;/p&gt;

&lt;p&gt;Before proceeding to the details of what should be taken into account in the state management library in the first place, let's look at another example of an application we know, but with a different library. &lt;strong&gt;Statemanjs&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;50&lt;/strong&gt; files.&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%2Fz5fsbb8ivh4bntns1fch.gif" 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%2Fz5fsbb8ivh4bntns1fch.gif" alt="upload 50 files with statemanjs" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;100&lt;/strong&gt; files.&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%2Fl62weidsh64n22o93nke.gif" 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%2Fl62weidsh64n22o93nke.gif" alt="upload 100 files with statemanjs" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;500&lt;/strong&gt; files.&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%2Fhd6ygywawal07n1iyj6k.gif" 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%2Fhd6ygywawal07n1iyj6k.gif" alt="upload 500 files with statemanjs" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Even &lt;strong&gt;1000&lt;/strong&gt; files without lags.&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%2Fzvlts7g7n1xf4139ek79.gif" 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%2Fzvlts7g7n1xf4139ek79.gif" alt="upload 1000 files with statemanjs" width="600" height="1536"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And only when sending &lt;strong&gt;5000&lt;/strong&gt; files there are lags, and then because of React. Nevertheless, even with lags, the application can still be used, unlike Redux and &lt;strong&gt;MobX&lt;/strong&gt; when sending &lt;strong&gt;500&lt;/strong&gt; files.&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%2Ft26vfywvm8d61vzebk3q.gif" 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%2Ft26vfywvm8d61vzebk3q.gif" alt="upload 5000 files with statemanjs" width="600" height="1536"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Is this some kind of lite version of &lt;strong&gt;MobX&lt;/strong&gt;? So it's even less secure and functional?&lt;br&gt;
This is not a lite version of MobX and &lt;em&gt;with MobX, statemanjs - binds only &lt;code&gt;Proxy&lt;/code&gt;&lt;/em&gt;. But &lt;code&gt;Proxy&lt;/code&gt; is used here in a radically different way. More native to the language itself. Providing monitoring and security of the condition. &lt;br&gt;
&lt;strong&gt;Statemanjs&lt;/strong&gt; uses the concept of references for reading, and you can change the state only with built-in methods. This makes it predictable, secure and, as we have seen, faster. &lt;br&gt;
I will not talk in detail about &lt;strong&gt;statemanjs&lt;/strong&gt;. You can read the official documentation - &lt;a href="https://github.com/persevie/statemanjs" rel="noopener noreferrer"&gt;Link&lt;/a&gt;, there are also benchmarks and comparison with other state management libraries. In this article, I wanted to draw your attention to how important it is to understand the design of the development environment. Data structures and data modification methods. &lt;/p&gt;

&lt;p&gt;Thank you all and have a good coding!&lt;/p&gt;




&lt;p&gt;&lt;a href="https://codesandbox.io/s/redux-gj6965" rel="noopener noreferrer"&gt;redux codesanbox&lt;/a&gt;&lt;br&gt;
&lt;a href="https://codesandbox.io/s/mobx-lghz2s" rel="noopener noreferrer"&gt;mobx codesanbox&lt;/a&gt;&lt;br&gt;
&lt;a href="https://codesandbox.io/s/statemanjs-xzh3g7" rel="noopener noreferrer"&gt;statemanjs codesanbox&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>programming</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Efficient State Management in JavaScript Apps with Statemanjs</title>
      <dc:creator>Dmitry Shatokhin</dc:creator>
      <pubDate>Thu, 12 Jan 2023 01:04:48 +0000</pubDate>
      <link>https://dev.to/dmtrshat/efficient-state-management-in-javascript-apps-with-statemanjs-3oml</link>
      <guid>https://dev.to/dmtrshat/efficient-state-management-in-javascript-apps-with-statemanjs-3oml</guid>
      <description>&lt;p&gt;When developing JavaScript applications, it is important to consider its limitations such as the lack of thread support, single-threaded execution model, limited support for large numbers and high-precision arithmetic etc. These limitations can narrow the scope of the language, but it remains the premier language in modern web development. As web applications become more complex, developers may encounter performance issues. There are various ways to optimize a web application, but one aspect to consider is state management.&lt;/p&gt;

&lt;p&gt;State management is a critical aspect of building modern JavaScript applications. It allows developers to manage and manipulate the data that drives their applications, and helps ensure that the application is reliable, scalable, and maintainable. There are many state management libraries available, each with its own set of features, trade-offs, and limitations. In this article, we will focus on Statemanjs, a framework-agnostic state management library for JavaScript and Node.js applications. We will explore the key features and benefits of Statemanjs, and I explain why it is the best choice for state management in JavaScript applications.&lt;br&gt;
But first, let's see which approaches of state management we have.&lt;/p&gt;
&lt;h2&gt;
  
  
  Approaches to state management:
&lt;/h2&gt;

&lt;p&gt;There are several approaches to state management in JavaScript - immutable, reactive, and mutable. Each with its own set of benefits and limitations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Immutable approach:&lt;/strong&gt; The immutable approach involves creating new copies of the state whenever it is updated, rather than modifying the state directly. This can provide a higher level of security and reliability, as it prevents accidental or unauthorized changes to the state. However, the immutable approach can be inefficient in JavaScript due to the single-threaded execution model and event loop.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reactive approach:&lt;/strong&gt; The reactive approach involves defining dependencies between state updates and automatically re-executing updates when the dependencies change. The reactive approach may be slower in other cases, and it can be more complex to learn and use than other approaches.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mutable approach:&lt;/strong&gt; The mutable approach involves updating the state directly, rather than creating new state copies or tracking dependencies. This can be faster and more efficient than the immutable or reactive approaches, and it can be simpler to understand and implement. However, the mutable approach may provide a lower level of security and reliability, as it allows developers to modify the state directly.&lt;/p&gt;
&lt;h2&gt;
  
  
  Quick Overview:
&lt;/h2&gt;

&lt;p&gt;Statemanjs is a framework-agnostic state management library for JavaScript and Node.js applications. It is written in TypeScript, which provides excellent support out of the box, and it has a tiny size, less than 80 KB (unpacked).&lt;/p&gt;

&lt;p&gt;Statemanjs uses a mutable approach to state management with read-only state links, and strict API for interacting with state. Let's dive deeper.&lt;/p&gt;
&lt;h2&gt;
  
  
  Performance:
&lt;/h2&gt;

&lt;p&gt;One of the main benefits of Statemanjs is its superior performance compared to other state management libraries. Statemanjs uses a mutable approach to state management, which updates the state directly and avoids the overhead of creating new state copies or tracking dependencies. This can make Statemanjs faster and more efficient than libraries that use immutable or reactive approaches, such as Redux or MobX.&lt;/p&gt;

&lt;p&gt;To benchmark the performance of these libraries, we used a test case that involves adding n elements to an array a certain number of times - x. The element is an object &lt;code&gt;{foo: "bar", baz: "qux"}&lt;/code&gt;. Between iterations, the storage (i.e., the array) is reset to an empty array.&lt;br&gt;
For example: if &lt;em&gt;n = 5&lt;/em&gt; and &lt;em&gt;x = 2&lt;/em&gt;, that means to add 5 elements 2 times (iteration).&lt;br&gt;
The average value for iterations is calculated and written as the result.&lt;/p&gt;

&lt;p&gt;In this benchmark, Statemanjs consistently outperforms both Redux and MobX. For example, with &lt;em&gt;n = 100000&lt;/em&gt; and &lt;em&gt;x = 10&lt;/em&gt;, the results are:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
  &lt;tr&gt;
    &lt;th&gt;Lib&lt;/th&gt;
    &lt;th&gt;Res (ms)&lt;/th&gt;
  &lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
    &lt;tr&gt;
        &lt;td&gt;Redux&lt;/td&gt;
        &lt;td&gt;2354867.223542001&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;MobX&lt;/td&gt;
        &lt;td&gt;4473.258667119965&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;Statemanjs&lt;/td&gt;
        &lt;td&gt;279.83934087000785&lt;/td&gt;
    &lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;As you can see, Statemanjs is more than &lt;strong&gt;8,000&lt;/strong&gt; times faster than Redux and nearly &lt;strong&gt;16&lt;/strong&gt; times faster than MobX in this benchmark. With larger numbers of elements or more complex update logic, the performance difference between Statemanjs and other libraries becomes even more pronounced.&lt;/p&gt;

&lt;p&gt;For example, with n = 50000000 (50 million elements) and &lt;em&gt;x = 1&lt;/em&gt; (1 iteration), both Redux and MobX fail to complete the benchmark after more than 6 hours of execution, while Statemanjs completes the benchmark in just 14499.883542001247ms (14.5 seconds).&lt;/p&gt;
&lt;h2&gt;
  
  
  Simplicity:
&lt;/h2&gt;

&lt;p&gt;In addition to its superior performance, Statemanjs is also simpler to understand and use than other state management libraries. It has a clear and strict API, with just seven methods for interacting with the state: &lt;code&gt;set&lt;/code&gt;, &lt;code&gt;get&lt;/code&gt;, &lt;code&gt;subscribe&lt;/code&gt;, &lt;code&gt;unsubscribeAll&lt;/code&gt;, &lt;code&gt;getActiveSubscribersCount&lt;/code&gt;, &lt;code&gt;unwrap&lt;/code&gt; and &lt;code&gt;update&lt;/code&gt;. These methods allow developers to set and retrieve the state, subscribe to state changes, and update the state in a controlled and reliable manner. Statemanjs also offers read-only state links, which provide restricted access to the state and prevent accidental or unauthorized changes.&lt;/p&gt;

&lt;p&gt;This simple and straightforward API can make it easier for developers to learn and use Statemanjs, especially if they are new to state management or have limited experience with other libraries. It also allows developers to focus on the core logic of their applications, rather than spending time learning complex APIs or writing boilerplate code.&lt;/p&gt;
&lt;h2&gt;
  
  
  Scalability:
&lt;/h2&gt;

&lt;p&gt;Statemanjs is highly scalable and suitable for both small and large projects. It can handle a wide range of state types, from primitives to complex and multidimensional objects, and it is easy to use with any front-end framework, including React, Vue, and Svelte. Statemanjs also has a small package size, with no dependencies and a footprint of less than 80 KB (unpacked), which makes it easy to include in any project without bloating the application.&lt;/p&gt;

&lt;p&gt;In addition to its scalability, Statemanjs also has excellent support for TypeScript out of the box. This can make it easier for developers to write and maintain type-safe code, and can help reduce the risk of errors and bugs in their applications.&lt;/p&gt;
&lt;h2&gt;
  
  
  Reliability:
&lt;/h2&gt;

&lt;p&gt;Statemanjs also offers a high level of security and reliability compared to other state management libraries. Its strict API and read-only state links prevent accidental or unauthorized changes to the state, and its mutable approach ensures that state updates are fast and efficient. These features can help developers build more reliable and maintainable applications, and can reduce the risk of errors and bugs in their code.&lt;/p&gt;

&lt;p&gt;By default, the state references are read-only, and you can only change the state using API methods.&lt;/p&gt;
&lt;h2&gt;
  
  
  Simple demo
&lt;/h2&gt;

&lt;p&gt;This is the demo with TypeScript:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&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;createState&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="s2"&gt;@persevie/statemanjs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;TransferElement&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;speed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;info&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;error&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// Create a new state with initial value { speed: 0, info: "" }&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;transferState&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createState&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;TransferElement&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;speed&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="na"&gt;info&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Subscribe to state changes and log the updated state&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;unsubscribe&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;transferState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;state&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&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;State updated:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Update the state to { speed: 50, info: "Transfer in progress" }&lt;/span&gt;
&lt;span class="nx"&gt;transferState&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="nx"&gt;state&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;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;speed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;info&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Transfer in progress&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="c1"&gt;// Get the current state&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;currentState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;transferState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&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="nx"&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;Current state:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;currentState&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Unsubscribe from state updates&lt;/span&gt;
&lt;span class="nx"&gt;unsubscribe&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// Subscribe to state changes, but only log the updated state if the error&lt;/span&gt;
&lt;span class="nx"&gt;transferState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&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;An error occurred:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&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="na"&gt;notifyCondition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&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;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="kc"&gt;undefined&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="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Set (create new object and replace old) the state to { speed: 0, info: "Ooops...", error: "Internet connection" }&lt;/span&gt;
&lt;span class="nx"&gt;transferState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;set&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;speed&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="nl"&gt;info&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Ooops...&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Internet&lt;/span&gt; &lt;span class="nx"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;,&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="nx"&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;Active subscribers count:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;transferState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getActiveSubscribersCount&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

&lt;span class="c1"&gt;// Remove all subscribers&lt;/span&gt;
&lt;span class="nx"&gt;transferState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;unsubscribeAll&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="nx"&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;Active subscribers count after unsubscribe:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;transferState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getActiveSubscribersCount&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

&lt;span class="c1"&gt;// Output:&lt;/span&gt;
&lt;span class="c1"&gt;// "State updated: { speed: 50, info: "Transfer in progress" }"&lt;/span&gt;
&lt;span class="c1"&gt;// "Current state: { speed: 50, info: "Transfer in progress" }"&lt;/span&gt;
&lt;span class="c1"&gt;// "An error occurred: "Internet connection""&lt;/span&gt;
&lt;span class="c1"&gt;// "Active subscribers count: 1"&lt;/span&gt;
&lt;span class="c1"&gt;// "Active subscribers count after unsubscribe: 0"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;In conclusion, Statemanjs is an excellent choice for state management in JavaScript applications. Its superior performance, simplicity, scalability, and reliability make it a standout among other state management libraries, and it is well-suited for a wide range of projects and frameworks. If you are looking for a powerful and efficient state management library for your JavaScript application, &lt;strong&gt;Statemanjs is a top choice&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/persevie/statemanjs"&gt;Statemanjs GitHub link&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/persevie/statemanjs-react"&gt;Statemanjs-react GitHub link&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/persevie/statemanjs-vue"&gt;Statemanjs-vue GitHub link&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/persevie/statemanjs-solid"&gt;Statemanjs-solid GitHub link&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>tutorial</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Browser, DOM, JavaScript. Everything you need to know to build effective web-apps. Part one - Browser.</title>
      <dc:creator>Dmitry Shatokhin</dc:creator>
      <pubDate>Sun, 14 Jun 2020 15:15:42 +0000</pubDate>
      <link>https://dev.to/dmtrshat/browser-dom-javascript-everything-you-need-to-know-to-build-effective-web-apps-part-one-browser-b18</link>
      <guid>https://dev.to/dmtrshat/browser-dom-javascript-everything-you-need-to-know-to-build-effective-web-apps-part-one-browser-b18</guid>
      <description>&lt;p&gt;Initially I planned to write only about DOM and even wrote the first article. But I came to the conclusion that in order to fully understand some of the concepts, I need to touch a little bit on how the browser works. Then I decided - Why "a little"? Maybe no? That's what I've decided. &lt;br&gt;
Now my article about DOM is this second article in the series. It's just like in Star Wars :) &lt;br&gt;
In this article I will consider those basic things of browser work, which are most important for web developers.&lt;/p&gt;

&lt;h1&gt;
  
  
  How it all started
&lt;/h1&gt;

&lt;p&gt;I'm not going to go into that, but to understand the context, I'll tell you a little bit about it. In the mid-90s, there were so-called "browser wars". Each company, in addition to its HTML, had its own versions of &lt;code&gt;DOM&lt;/code&gt; and &lt;code&gt;browser engines&lt;/code&gt; until W3C obliged all companies to standardize technology. A common standard has not yet been achieved, which is why we have to create cross-browser versions of web applications.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;REMARK&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
Browser engine != Browser.&lt;br&gt;
Often, the browser engine is equated with the browser. But that's not really true. All the engine does is parset and display the content. The browser, on the other hand, performs much more, more complex tasks. However, it is the different engine that makes us support all sites.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;Browser architecture scheme&lt;/em&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vHBvq-sV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/049goikplpvozmm5gjxn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vHBvq-sV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/049goikplpvozmm5gjxn.png" alt="Image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Okay, how does it all work?
&lt;/h1&gt;

&lt;p&gt;While it's running, the browser runs several processes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hEhWzGjG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://developers.google.com/web/updates/images/inside-browser/part1/browser-arch.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hEhWzGjG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://developers.google.com/web/updates/images/inside-browser/part1/browser-arch.png" alt="Image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;REMARK&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
The computer program itself is just a passive sequence of instructions. While the process is the direct execution of these instructions. The process can generate other processes as well as threads that share the resources of the parent process.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Since in this article we consider the browser in the context of web development, we are interested only in one process - &lt;strong&gt;&lt;code&gt;rendering process&lt;/code&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;IDEA&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
Maybe in the future, I'll take a closer look at the browser work.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For each tab, the browser launches this process. Moreover, modern browsers also run the &lt;code&gt;rendering process&lt;/code&gt; for each &lt;code&gt;iframe&lt;/code&gt;. This is done in order to isolate each tab and &lt;code&gt;iframe&lt;/code&gt;. And if any child process fails, kill it, not the main process. It's called &lt;code&gt;site isolation&lt;/code&gt;.&lt;br&gt;
The &lt;code&gt;rendering process&lt;/code&gt; runs threads. We will only consider the main thread. Almost all the work in the &lt;code&gt;rendering process&lt;/code&gt; is done by browser engines.&lt;br&gt;
The main engines at the moment are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Blink.&lt;/li&gt;
&lt;li&gt;Gecko&lt;/li&gt;
&lt;li&gt;WebKit&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;REMARK&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
During development, you should also consider &lt;code&gt;EdgeHTML&lt;/code&gt;, but soon &lt;code&gt;Microsoft&lt;/code&gt; will completely abandon it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now let's take a look at what happens when drawing a page.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;this is a simplified model&lt;/em&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kFJQesc4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/u9gfvpajckuukx9jujm3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kFJQesc4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/u9gfvpajckuukx9jujm3.png" alt="Image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;First of all, resources (&lt;code&gt;HTML&lt;/code&gt; and &lt;code&gt;CSS&lt;/code&gt;) are parsed and converted to object trees. They are combined and another tree is constructed based on them - the &lt;code&gt;render tree&lt;/code&gt;. This tree contains only those elements that will be drawn on the screen.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;REMARK&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
An element with the style &lt;code&gt;display: none&lt;/code&gt; - will not be contained in this tree. Because the element does not have its own visual representation.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;After that, a walk through this tree to calculate their size and location on the screen. This process is called &lt;code&gt;layout&lt;/code&gt; (or &lt;code&gt;flow&lt;/code&gt; in Firefox).&lt;/p&gt;

&lt;p&gt;Then, all calculated elements are drawn onto the screen.&lt;/p&gt;

&lt;p&gt;Let us dwell on each point.&lt;/p&gt;

&lt;h1&gt;
  
  
  HTML parsing.
&lt;/h1&gt;

&lt;p&gt;Many parsers are based on &lt;code&gt;context free grammar&lt;/code&gt;, which allows them to work very efficiently. But the main problem with parsing &lt;code&gt;HTML&lt;/code&gt; is that it cannot be defined using&lt;code&gt;context free grammar&lt;/code&gt;. This is because the browser needs to keep track of how &lt;code&gt;HTML&lt;/code&gt; is written. If the tag is not closed somewhere, then the browser will close it and so on. Even if you do not make mistakes, this feature slows down parsing very much.&lt;/p&gt;

&lt;p&gt;Another important feature of &lt;code&gt;HTML&lt;/code&gt; parsing is how it reacts when it encounters the &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt;tag. Parsing stops until the script is executed and only after that continues to work. This is why you should place scripts before the &lt;code&gt;&amp;lt;/body&amp;gt;&lt;/code&gt; tag or use &lt;code&gt;async&lt;/code&gt; and &lt;code&gt;defer&lt;/code&gt;. &lt;code&gt;async&lt;/code&gt; and&lt;code&gt;defer&lt;/code&gt; - allow loading scripts in parallel with parsing.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;REMARK&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;defer&lt;/code&gt; differs in that it guarantees the execution order.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It should be noted that if there are very large scripts, the browser starts to allocate separate streams and tries to optimize the download.&lt;/p&gt;

&lt;p&gt;A similar situation occurs when the parser encounters &lt;code&gt;CSS&lt;/code&gt;. Style loading blocks parsing.&lt;/p&gt;

&lt;h1&gt;
  
  
  CSS parsing.
&lt;/h1&gt;

&lt;p&gt;CSS parsing is free of such problems as when parsing HTML and, in principle, is no different.&lt;/p&gt;

&lt;h1&gt;
  
  
  Attachment
&lt;/h1&gt;

&lt;p&gt;At this point, the render tree` begins to be constructed.&lt;/p&gt;

&lt;h1&gt;
  
  
  Layout (Flow)
&lt;/h1&gt;

&lt;p&gt;After the &lt;code&gt;render tree&lt;/code&gt; is formed, the position and geometric dimensions of the elements of this tree are calculated.&lt;/p&gt;

&lt;p&gt;The speed of &lt;code&gt;layout&lt;/code&gt; directly depends on the quality of the&lt;code&gt; CSS&lt;/code&gt; you wrote.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What does it mean?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This means that each &lt;code&gt;CSS&lt;/code&gt; rule needs to be applied to a separate &lt;code&gt;DOM&lt;/code&gt; node. This is achieved by recursively traversing the &lt;code&gt;HTML&lt;/code&gt; tree, another tree - the &lt;code&gt;CSS&lt;/code&gt; tree. And the more difficult it is to write &lt;code&gt;CSS&lt;/code&gt;, the longer it will take.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;CSS&lt;/code&gt; - selectors are not equal in performance.&lt;br&gt;
The most productive are: &lt;code&gt;#(id)&lt;/code&gt;, &lt;code&gt;.(Class)&lt;/code&gt; Slightly less productive - &lt;code&gt;type(for ex. - h1)&lt;/code&gt;&lt;br&gt;
Combinations of attributes are not productive, and the most not productive are &lt;code&gt;pseudo elements&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;REMARK&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
There are various &lt;code&gt;css methodologies&lt;/code&gt; which are based on productive selectors.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Painting
&lt;/h1&gt;

&lt;p&gt;Here the image is constructed and sent to the &lt;code&gt;GPU&lt;/code&gt; to draw it onto the screen.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;that's how the &lt;code&gt;layout&lt;/code&gt; process goes&lt;/em&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sVrugTxH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/yzwm08a4mk01eee8trku.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sVrugTxH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/yzwm08a4mk01eee8trku.gif" alt="Gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;REMARK&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://www.youtube.com/watch?v=ZTnIxIA5KGw"&gt;source&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In browsers, in devtools you can enable a mode that will show the rendering of elements.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;We examined the main points of the browser. In some of the following articles, we will touch upon a few more interesting points.&lt;/p&gt;




&lt;h1&gt;
  
  
  Afterword.
&lt;/h1&gt;

&lt;p&gt;Thank you very much for your attention. I hope it was useful for you 🙏&lt;br&gt;
Follow me, it makes me write new articles 😌&lt;br&gt;
I'd be happy for your feedback.&lt;br&gt;
C u! 😉&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.buymeacoffee.com/lKsISqg"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TtGiCgSp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.buymeacoffee.com/buttons/default-green.png" alt="Buy Me A Coffee"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>browser</category>
      <category>dom</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Browser, DOM, JavaScript. Everything you need to know to build effective web-apps. Part two - DOM.</title>
      <dc:creator>Dmitry Shatokhin</dc:creator>
      <pubDate>Fri, 05 Jun 2020 22:03:09 +0000</pubDate>
      <link>https://dev.to/dmtrshat/dom-what-is-it-and-how-does-it-work-2j23</link>
      <guid>https://dev.to/dmtrshat/dom-what-is-it-and-how-does-it-work-2j23</guid>
      <description>&lt;p&gt;Hi 👋&lt;br&gt;
This article will talk about the &lt;strong&gt;&lt;code&gt;DOM&lt;/code&gt;&lt;/strong&gt;. This is the second article in the series.&lt;/p&gt;
&lt;h1&gt;
  
  
  DOM tree.
&lt;/h1&gt;

&lt;p&gt;DOM(&lt;strong&gt;D&lt;/strong&gt;ocument &lt;strong&gt;O&lt;/strong&gt;bject &lt;strong&gt;M&lt;/strong&gt;odel) is a software &lt;strong&gt;interface&lt;/strong&gt; for HTML, XML and SVG documents. It provides a structured view of the document(tree) as a &lt;strong&gt;group of nodes and objects&lt;/strong&gt; that have properties and methods, and defines the way in which the structure can be accessed by the program. &lt;br&gt;
DOM binds web pages to scripts or programming languages.&lt;/p&gt;

&lt;p&gt;The basis of an HTML document is tags.&lt;br&gt;
According to the DOM, an HTML tag is an object and nested tags are its "children".&lt;br&gt;
All objects are available with JavaScript, we can use them to modify the page.&lt;br&gt;
For example, &lt;code&gt;document.body&lt;/code&gt; is an object for the &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt; tag.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;REMARK&lt;/em&gt;&lt;/strong&gt; &lt;br&gt;
JavaScript is not part of DOM, even though it(JS) is most commonly used.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1&gt;
  
  
  DOM example.
&lt;/h1&gt;

&lt;p&gt;This is a typical HTML page:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE HTML&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;About DOM&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
  DOM...
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And this is a view of an HTML document as a tag tree:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;html
    head
        #text
        title
             #text "About DOM"
        #text
    #text
    body
        #text "DOM..."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Tags are node elements(elements). They form the structure of the tree: &lt;code&gt;&amp;lt;html&amp;gt;&lt;/code&gt; is the root node, &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt; its child nodes, etc.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Text&lt;/strong&gt; inside the elements forms &lt;strong&gt;text nodes&lt;/strong&gt; named &lt;code&gt;#text&lt;/code&gt;. The text node contains only a string of text. It cannot have descendants (it is always at the lowest level).&lt;br&gt;
Spaces and line breaks are also symbols. Like letters and numbers, they form text nodes and become part of the DOM tree. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;REMARK&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Spaces and line breaks before the &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; tag are ignored;&lt;/li&gt;
&lt;li&gt;There are no characters after &lt;code&gt;&amp;lt;/body&amp;gt;&lt;/code&gt; tag. Anything written after this tag is moved to the end of the &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt; tag according to the DOM specification;&lt;/li&gt;
&lt;li&gt;Everything written before &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; tag is moved inside &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Everything written in HTML is also in the DOM tree, even comments&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Remark&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
Comments is also a DOM tree node.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In this example, there are no text nodes created by spaces and line breaks:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE HTML&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;&lt;/span&gt;About DOM&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;&lt;/span&gt;DOM...&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;REMARK&lt;/em&gt;&lt;/strong&gt; &lt;br&gt;
One of the reasons why minimized(single-line) code works faster.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Building a DOM.
&lt;/h1&gt;

&lt;p&gt;When building a DOM, the &lt;strong&gt;browser automatically fixes incorrectly written HTML&lt;/strong&gt;. For example, if a file contains only the word &lt;code&gt;world&lt;/code&gt;, the browser will add all the necessary tags. The DOM will look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;html
    head
    body
        #text "world"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;REMARK&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
For short, I don't take text nodes from spaces and line breaks into account.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;REMARK&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
Also the browser closes all unclosed tags. But I strongly recommend closing them.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Other nodes.
&lt;/h1&gt;

&lt;p&gt;There are 12 DOM nodes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://dom.spec.whatwg.org/#dom-node-element_node" rel="noopener noreferrer"&gt;ELEMENT_NODE&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dom.spec.whatwg.org/#dom-node-attribute_node" rel="noopener noreferrer"&gt;ATTRIBUTE_NODE&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dom.spec.whatwg.org/#dom-node-text_node" rel="noopener noreferrer"&gt;TEXT_NODE&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dom.spec.whatwg.org/#dom-node-cdata_section_node" rel="noopener noreferrer"&gt;CDATA_SECTION_NODE&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;ENTITY_REFERENCE_NODE&lt;/li&gt;
&lt;li&gt;ENTITY_NODE&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dom.spec.whatwg.org/#dom-node-processing_instruction_node" rel="noopener noreferrer"&gt;PROCESSING_INSTRUCTION_NODE&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dom.spec.whatwg.org/#dom-node-comment_node" rel="noopener noreferrer"&gt;COMMENT_NODE&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dom.spec.whatwg.org/#dom-node-document_node" rel="noopener noreferrer"&gt;DOCUMENT_NODE&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dom.spec.whatwg.org/#dom-node-document_type_node" rel="noopener noreferrer"&gt;DOCUMENT_TYPE_NODE&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dom.spec.whatwg.org/#dom-node-document_fragment_node" rel="noopener noreferrer"&gt;DOCUMENT_FRAGMENT_NODE&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;NOTATION_NODE&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;But most often only 4 of them are used: &lt;code&gt;document&lt;/code&gt;, &lt;code&gt;elements&lt;/code&gt;, &lt;code&gt;text nodes&lt;/code&gt;, &lt;code&gt;comments&lt;/code&gt;.&lt;/p&gt;




&lt;p&gt;&lt;a href="http://software.hixie.ch/utilities/js/live-dom-viewer/#" rel="noopener noreferrer"&gt;Here&lt;/a&gt; - you can see the DOM model in real time.&lt;/p&gt;

&lt;p&gt;In the next article I will talk about shadow and virtual DOM. Don't miss it! &lt;/p&gt;

&lt;h1&gt;
  
  
  Afterword.
&lt;/h1&gt;

&lt;p&gt;Thank you very much for your attention. I hope it was useful for you 🙏&lt;br&gt;
Follow me, it makes me write new articles 😌&lt;br&gt;
I'd be happy for your feedback.&lt;br&gt;
C u! 😉&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.buymeacoffee.com/lKsISqg" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.buymeacoffee.com%2Fbuttons%2Fdefault-green.png" alt="Buy Me A Coffee"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>html</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>dom</category>
    </item>
    <item>
      <title>A small collection of useful React hooks.</title>
      <dc:creator>Dmitry Shatokhin</dc:creator>
      <pubDate>Fri, 29 May 2020 20:50:28 +0000</pubDate>
      <link>https://dev.to/dmtrshat/a-small-collection-of-useful-react-hooks-5ha2</link>
      <guid>https://dev.to/dmtrshat/a-small-collection-of-useful-react-hooks-5ha2</guid>
      <description>&lt;p&gt;I often have to find different implementations of the same things in projects. I singled out for myself the most common and leave links to ready-made solutions.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;REMARK&lt;/em&gt;&lt;/strong&gt; &lt;br&gt;
This is not a typical article. Now I support the project on React and have encountered this. So I decided to share&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  useFetch
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.npmjs.com/package/react-fetch-hook" rel="noopener noreferrer"&gt;useFetch&lt;/a&gt;&lt;/strong&gt; - Fetch API in the implementation of the hook.&lt;/p&gt;

&lt;h2&gt;
  
  
  useApi
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.npmjs.com/package/react-use-api" rel="noopener noreferrer"&gt;useApi&lt;/a&gt;&lt;/strong&gt; - Same as useFetch, only made with axios.&lt;/p&gt;

&lt;h2&gt;
  
  
  useWindowScrollPosition
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.npmjs.com/package/@rehooks/window-scroll-position" rel="noopener noreferrer"&gt;useWindowScrollPosition&lt;/a&gt;&lt;/strong&gt; - Helps to track the position of the cursor.&lt;/p&gt;

&lt;h2&gt;
  
  
  useLocalStorage
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.npmjs.com/package/@rehooks/local-storage" rel="noopener noreferrer"&gt;useLocalStorage&lt;/a&gt;&lt;/strong&gt; - Various operations with local storage.&lt;/p&gt;

&lt;h2&gt;
  
  
  useDocumentTitle
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.npmjs.com/package/@rehooks/document-title" rel="noopener noreferrer"&gt;useDocumentTitle&lt;/a&gt;&lt;/strong&gt; - Allows you to set the title of the document.&lt;/p&gt;

&lt;h2&gt;
  
  
  useOnlineStatus
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.npmjs.com/package/@rehooks/online-status" rel="noopener noreferrer"&gt;useOnlineStatus&lt;/a&gt;&lt;/strong&gt; - Check the status of the network.&lt;/p&gt;

&lt;h2&gt;
  
  
  useClippy
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.npmjs.com/package/use-clippy" rel="noopener noreferrer"&gt;useClippy&lt;/a&gt;&lt;/strong&gt; - Adding to the clipboard.&lt;/p&gt;

&lt;h2&gt;
  
  
  useScript
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.npmjs.com/package/react-script-hook" rel="noopener noreferrer"&gt;useScript&lt;/a&gt;&lt;/strong&gt; - Allows you to dynamically download external scripts.&lt;/p&gt;




&lt;h1&gt;
  
  
  Afterword.
&lt;/h1&gt;

&lt;p&gt;Thank you very much for your attention. I hope it was useful for you 🙏&lt;br&gt;
Follow me, it makes me write new articles 😌&lt;br&gt;
I'd be happy for your feedback.&lt;br&gt;
C u! 😉&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.buymeacoffee.com/lKsISqg" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.buymeacoffee.com%2Fbuttons%2Fdefault-green.png" alt="Buy Me A Coffee"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>hooks</category>
      <category>webdev</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
