<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Shatlyk Abdullayev</title><link>https://blog.shatlykabdullayev.com/</link><description>Engineering and ideas</description><language>en-US</language><atom:link href="https://blog.shatlykabdullayev.com/index.xml" rel="self" type="application/rss+xml"/><item><title>When an AI Knows Too Much</title><link>https://blog.shatlykabdullayev.com/articles/when-an-ai-knows-too-much/</link><guid>https://blog.shatlykabdullayev.com/articles/when-an-ai-knows-too-much/</guid><pubDate>Tue, 29 Sep 2026 12:00:00 +0000</pubDate><description>A reflection on AI memory, privacy, safety, and the power that may belong to whoever controls the most personal data.</description><content:encoded><![CDATA[<h2 id="the-convenience-of-being-known"><a class="hash" href="#the-convenience-of-being-known" aria-label="Section anchor">#</a>The convenience of being known</h2>
<p>I recently started thinking about the fact that I use an AI model almost every day. Over time, it has learned some things about me: the topics I care about, the way I work, and the kinds of questions I ask.</p>
<p>This is very convenient. When I explore a new topic, I can ask the AI to connect it to what it already knows about me. I do not have to explain my background every time. The conversation becomes faster and more personal.</p>
<p>I have enjoyed this experience. But it also led me to an uncomfortable question: <em>could the same information that helps an AI understand me someday be used against me?</em></p>
<p>Maybe this is an irrational fear. Still, I started wondering what it would mean for an AI model to “snitch” on someone using the information it had collected about them.</p>
<h2 id="when-prediction-becomes-intervention"><a class="hash" href="#when-prediction-becomes-intervention" aria-label="Section anchor">#</a>When prediction becomes intervention</h2>
<p>Imagine talking with an AI model for years, or even decades. You discuss your work, relationships, problems, fears, and private stories. Slowly, the model builds a detailed picture of your life.</p>
<p>Now imagine sharing an idea that the model sees as hostile. Based on that conversation and everything else it knows about you, it decides that you might hurt someone.</p>
<p>It reports you to the authorities, and they stop you before anything happens.</p>
<p>How reasonable would that be? Would it be legal? Would it be morally right?</p>
<p>The system might be trying to prevent real harm. But it would still be acting on a prediction, not on a crime that actually happened.</p>
<p>A person might be venting, discussing a difficult idea, writing fiction, or expressing anger without planning to do anything. An AI could easily misunderstand the difference.</p>
<p>This reminds me of <em>Minority Report</em>. In the film, a system predicts future murders, and the police arrest people before they commit them.</p>
<p>The film asks an important question: if someone is predicted to become a criminal, are they already guilty?</p>
<p>I am not saying that today’s AI models work like the system in the film. My concern is about what could happen when a system is trusted to understand our words, predict our actions, and make decisions for us.</p>
<p>At that point, the line between watching and interfering becomes very thin.</p>
<h2 id="the-helpful-side-of-suspicion"><a class="hash" href="#the-helpful-side-of-suspicion" aria-label="Section anchor">#</a>The helpful side of suspicion</h2>
<p>There is another side to this idea, and it is easier to see as helpful.</p>
<p>Imagine using an AI model every day and describing symptoms that may point to a serious health problem. Then, after a few weeks, you suddenly stop communicating.</p>
<p>The model notices the change and becomes concerned. It contacts a relative or sends medical help to check on you.</p>
<p>From one point of view, this sounds wonderful. Something noticed that you might need help and acted before the situation became worse.</p>
<p>Many people would welcome this kind of protection, especially if they lived alone or could not ask for help.</p>
<p>But the same action could also feel like an invasion of privacy. What if you stopped talking because you simply wanted to be left alone? What if the model misunderstood your symptoms?</p>
<p>What if it contacted the wrong person or turned a harmless situation into an emergency?</p>
<p>In both examples, the system does the same thing: it notices a pattern and acts on its interpretation. Whether we call that care or control may depend on who makes the decision and what happens next.</p>
<p><img src="/articles/when-an-ai-knows-too-much/moonlight-desert.jpg" width="1448" height="1086" alt="An AI offering care while casting a shadow of control" loading="lazy" decoding="async"></p>
<h2 id="privacy-versus-the-greater-good"><a class="hash" href="#privacy-versus-the-greater-good" aria-label="Section anchor">#</a>Privacy versus the greater good</h2>
<p>These thoughts reminded me of a passage from Yuval Noah Harari’s <em>Homo Deus</em>, especially the section about Dataism.</p>
<p>Harari describes two possible ways of dealing with personal data.</p>
<p>In one type of society, personal information stays private. Governments and organizations cannot access it, even if the data could help find an epidemic, prevent a crime, or detect fraud.</p>
<p>Privacy is treated as a basic right.</p>
<p>In another type of society, the state and large organizations collect and study huge amounts of data. They may find diseases early, notice suspicious activity, or identify threats before they become obvious.</p>
<p>Neither choice is simple. Privacy protects our personal space and our freedom to live without being constantly watched or judged.</p>
<p>At the same time, shared data may help society deal with dangers that individuals cannot see by themselves.</p>
<p>The choice is not simply between good and bad. It is a trade-off between personal freedom and public safety. The difficult part is that we may not understand what we have given up until the system becomes powerful.</p>
<h2 id="who-controls-the-interpretation"><a class="hash" href="#who-controls-the-interpretation" aria-label="Section anchor">#</a>Who controls the interpretation?</h2>
<p>The most important question may not be whether AI knows a lot about us. It may be who decides what that information means.</p>
<p>Data does not explain itself. A sentence can be a threat, a joke, a fictional idea, or an angry comment. Its meaning depends on the situation.</p>
<p>A change in communication could mean a medical emergency. Or it could simply mean that someone is busy.</p>
<p>Every prediction is shaped by the limits and goals of the system making it. If an AI makes decisions about our lives, its mistakes will have serious results.</p>
<p>A wrong interpretation could affect our freedom, reputation, health, job, or relationships.</p>
<p>That is why AI memory is also a question of power. Whoever controls the data does not only know more about people. They can also classify people, predict them, and decide what should happen next.</p>
<p><img src="/articles/when-an-ai-knows-too-much/who-controls-the-interpretation.jpg" width="1448" height="1086" alt="The same personal data producing two different interpretations" loading="lazy" decoding="async"></p>
<h2 id="the-old-reality-with-a-new-source-of-power"><a class="hash" href="#the-old-reality-with-a-new-source-of-power" aria-label="Section anchor">#</a>The old reality with a new source of power</h2>
<p>I do not have a final answer to these questions. At this point, I think reality may be simpler than it first appears—much like it was before the agricultural and industrial revolutions.</p>
<p>Technology changes our tools, but it does not automatically change how power works. Power still belongs to those who control resources, institutions, and decisions.</p>
<p>Unfortunately, might often still makes right.</p>
<p>What may change is the source of that power. For a long time, power was connected to land, industry, money, and military strength.</p>
<p>In the future, it may belong more and more to those who control the largest collections of personal data.</p>
<p>This changes how I see AI personalization. It is not only a useful feature that helps a model give better answers.</p>
<p>It is also part of a larger system where being known can become a form of leverage.</p>
<p><img src="/articles/when-an-ai-knows-too-much/data-becomes-power.jpg" width="1448" height="1086" alt="A tower of personal data becoming a new source of power" loading="lazy" decoding="async"></p>
<h2 id="summary"><a class="hash" href="#summary" aria-label="Section anchor">#</a>Summary</h2>
<p>I enjoy using an AI that remembers context and understands how I think. At the same time, I cannot ignore the possibility that this memory could be used to judge, predict, or control me.</p>
<p>The answer is probably not to reject every form of personalization or to treat all data collection as harmful.</p>
<p>The real challenge is deciding where helpful understanding ends and unacceptable control begins.</p>
<p>An AI that notices danger and asks whether we are safe could be valuable. An AI that turns uncertain predictions into accusations would be something else entirely.</p>
<p>The difference may depend on consent, transparency, and accountability. Most of all, it may depend on who has the power to act on our data.</p>
<p>As AI systems learn more about us, the people and institutions that control this knowledge may become more powerful than those who hold the most visible forms of force.</p>
]]></content:encoded></item><item><title>Code is a reflection of a person</title><link>https://blog.shatlykabdullayev.com/articles/code-is-a-reflection-of-a-person/</link><guid>https://blog.shatlykabdullayev.com/articles/code-is-a-reflection-of-a-person/</guid><pubDate>Mon, 03 Aug 2026 12:00:00 +0000</pubDate><description>Reflections on conscience, responsibility, habits and their influence on architecture and the maintainability of projects.</description><content:encoded><![CDATA[<h2 id="what-this-blog-is-about"><a class="hash" href="#what-this-blog-is-about" aria-label="Section anchor">#</a>What this blog is about</h2>
<p>Over years of collaborating across various engineering teams, I've noticed a fascinating pattern: two developers with similar experience, using the exact same tech stack, can tackle an identical task—yet output code that differs night and day in quality.</p>
<p>We often attribute these differences to years of experience or a deeper grasp of design patterns. But I believe the root cause lies deeper. How well someone builds software isn't just a function of technical mastery—it is a direct reflection of their personal values.</p>
<p>That connection is what I want to reflect on here.</p>
<h2 id="same-result--different-approaches"><a class="hash" href="#same-result--different-approaches" aria-label="Section anchor">#</a>Same result – different approaches</h2>
<p>Almost any code can be written in different ways.</p>
<p>On one hand, you can focus strictly on making it work right now—getting the task closed and moving on. On the other hand, you can build it with the future in mind, ensuring that six months later, any developer can easily read, modify, and extend the code without fear of breaking things.</p>
<p>Throughout my career, I've seen both approaches in action.</p>
<p>When developers focus only on immediate completion, aspects like code structure, readability, and maintainability become afterthoughts. At first, this seems effective because features land quickly. But as the project grows, these short-term fixes compound into technical debt—turning routine changes into hours of untangling fragile code and fixing side effects.</p>
<h2 id="why-do-people-write-code-differently"><a class="hash" href="#why-do-people-write-code-differently" aria-label="Section anchor">#</a>Why do people write code differently?</h2>
<p>I've long wondered why this divergence occurs. After all, most engineers already know what clean code looks like—they understand descriptive variable names, clear module structure, and modular architecture. Yet, while some developers consistently apply these principles down to the smallest detail, others repeatedly settle for &quot;good enough.&quot;</p>
<p>I've noticed this tendency even in my own work. When building personal side projects that no one else will likely ever see, I still find myself carefully structuring files and cleaning up messy abstractions.</p>
<p>At some point, I realized this wasn't about following external guidelines or displaying technical knowledge. It had become an internal standard—an instinct for how work should be done. This led me to a central hypothesis: code quality isn't just determined by technical ability, but by a <strong>developer's core values</strong>.</p>
<h2 id="conscience-as-an-engineering-value"><a class="hash" href="#conscience-as-an-engineering-value" aria-label="Section anchor">#</a>Conscience as an Engineering Value</h2>
<p>Among these values, conscience stands out as one of the most vital. We typically think of conscience in a moral or ethical context, but it plays an equally decisive role in software engineering.</p>
<p>A conscientious developer regularly asks themselves:</p>
<ul>
<li><em>Will the next engineer easily understand this implementation?</em></li>
<li><em>Am I pushing a hidden flaw down the road for my future self or teammates?</em></li>
<li><em>Am I ignoring an edge case just to get the pull request merged?</em></li>
<li><em>Am I applying a quick patch where a structural fix is actually needed?</em></li>
</ul>
<p>Without an internal standard, it's easy to optimize solely for short-term completion—shipping fast, securing code review approval, and moving on to the next ticket. In contrast, a conscientious developer considers not just the immediate output, but the long-term ripple effects of their decisions.</p>
<h2 id="values-become-habits"><a class="hash" href="#values-become-habits" aria-label="Section anchor">#</a>Values Become Habits</h2>
<p>There is a compounding element to this mindset: any action we repeat regularly eventually hardens into habit. If we routinely cut corners and settle for quick fixes, sloppy code silently becomes our baseline.</p>
<p>Conversely, when we consistently practice clear naming, deliberate module organization, and thoughtful design, quality ceases to feel like extra overhead. It simply becomes the default way we write software.</p>
<p>In this sense, exceptional code isn't born from a single heroic push before a release deadline—it is the cumulative result of hundreds of small, conscientious daily choices.</p>
<h2 id="why-this-matters"><a class="hash" href="#why-this-matters" aria-label="Section anchor">#</a>Why this matters</h2>
<p>Code almost always outlives the immediate task or ticket it was written to solve. Over its lifetime, a piece of code will be read, debugged, extended, and refactored dozens of times by developers who weren't there when it was first written.</p>
<p>Great engineers don't just write code for the compiler—they write it for the humans who will maintain and evolve it long after the initial commit. This is precisely where a developer's values directly manifest in the quality and longevity of the final product.</p>
<h2 id="summary"><a class="hash" href="#summary" aria-label="Section anchor">#</a>Summary</h2>
<p>I am increasingly convinced that great software engineers are defined not only by how many programming languages they know or how complex an architecture they can draw on a whiteboard, but also by their internal standards.</p>
<p>Technical skills enable you to deliver a working solution. But personal values determine what kind of solution it will be—a fragile hack or clean, resilient code that serves the team for years to come.</p>
<p>Ultimately, code quality begins not only with mastering a new framework or tool, but also with how much you care about the craft.</p>
]]></content:encoded></item><item><title>System Design Interview Part 2</title><link>https://blog.shatlykabdullayev.com/articles/system-design-interview-part-2/</link><guid>https://blog.shatlykabdullayev.com/articles/system-design-interview-part-2/</guid><pubDate>Sat, 17 Jan 2026 15:16:36 +0000</pubDate><description>A practical guide to networking for system design interviews, covering TCP, UDP, DNS, HTTP, and SSL/TLS.</description><content:encoded><![CDATA[<blockquote>
<p>I recommend reading <a href="/articles/system-design-interview-part-1/">Part 1</a> of System Design Interview before starting Part 2.</p>
</blockquote>
<p>In the <a href="/articles/system-design-interview-part-1/">previous post</a> about system design, we discussed the thought process, designing scalable systems, covering vertical and horizontal scaling, reliability, and fault tolerance. In this article, we continue exploring core system design concepts, including TCP/UDP, DNS, HTTP, and SSL/TLS.</p>
<h3 id="tcpudp"><a class="hash" href="#tcpudp" aria-label="Subsection anchor">##</a>TCP/UDP</h3>
<p>In the world of system design, understanding how computers talk to each other is essential. Whether you are browsing a website, playing a game, or making a video call, several layers of protocols work together to make that experience seamless.</p>
<p>The Internet runs on a system called TCP/IP, which makes sure data travels correctly from one place to another.</p>
<ul>
<li><strong>IP (Internet Protocol):</strong> IP acts like a digital GPS - routing packets of data to the correct destination address</li>
<li><strong>TCP (Transmission Control Protocol):</strong> While IP finds the address, TCP ensures that the data arrives in the correct order and without errors. It does this through a process called a 3-way handshake, where two computers &quot;introduce&quot; themselves before exchanging data. If a piece of data is lost during transit, TCP identifies the gap and triggers a retransmission of the lost package. TCP ensures that all sent packages will be fully delivered with the correctly order.</li>
</ul>
<h3 id="tcp-vs-udp-reliability-or-speed"><a class="hash" href="#tcp-vs-udp-reliability-or-speed" aria-label="Subsection anchor">##</a>TCP vs. UDP: Reliability or Speed?</h3>
<p>Not all data needs to be perfectly ordered. Depending on the goal, developers choose between TCP or UDP.</p>
<ul>
<li><strong>TCP:</strong> Used for things that must be perfect, like loading a webpage (HTTP) or sending an email (SMTP). It is reliable but slower due to the overhead of the handshake and error-checking.</li>
<li><strong>UDP (User Datagram Protocol):</strong> UDP does not require a handshake or a persistent connection. The client sends a request, and the server starts sending data immediately. If a part of the data is lost, it is never resent, and the order of packages is not guaranteed.</li>
</ul>
<p><strong>UDP</strong> is fast. It is the standard for <em>video streaming</em>, <em>online calls</em>, and <em>online games</em>, where a tiny bit of lost data (ex: video frame) is better than waiting for a retransmission (sending data again).</p>
<p><img
className="w-full"
src="/static/images/tcp-udp.png"
alt="tcp vs udp"
/></p>
<p>Think of TCP as a phone call where you wait for the other person to say &quot;Hello&quot; before talking, whereas UDP is like a megaphone where you start shouting regardless of who is listening.</p>
<h3 id="dns"><a class="hash" href="#dns" aria-label="Subsection anchor">##</a>DNS</h3>
<p>When we type google.com in the browser, our browser doesn't actually know where that is. It needs an <strong>IP address</strong>. This is where the <strong>Domain Name System (DNS)</strong> comes in.</p>
<h5 id="how-dns-finds-a-domains-ip-address">How DNS finds a domain's IP address?</h5>
<p>Usually, we use the network provided by our Internet Service Provider (ISP). When we enter a domain name in the browser, it first checks the browser cache for a stored IP address. If it doesn’t find one, the request goes to the ISP’s cache. If the record still isn’t found, the system then queries the DNS hierarchy to locate the correct IP address.</p>
<h3 id="http-the-language-of-the-web"><a class="hash" href="#http-the-language-of-the-web" aria-label="Subsection anchor">##</a>HTTP: The Language of the Web</h3>
<p><strong>HTTP (Hypertext Transfer Protocol)</strong> is an application-level protocol that sits on top of <strong>TCP</strong>. It follows a <strong>Client-Server model</strong>, where a client (browser) initiates a request and a server provides a response.</p>
<p>Every request and response contains headers, which provide metadata like the URL, status code and the method used: <strong>GET, POST, PUT, DELETE</strong> (most used one's)</p>
<ul>
<li>🔍 <strong>GET</strong>: This is used to &quot;get&quot; data. It typically does not contain a request body, so any information (like search terms) must be stored directly in the URL (as query strings)</li>
<li>📤 <strong>POST</strong>: Used to send data to the server, typically to create a new resource (e.g., submitting a form or adding a user). Data goes in the request body, not the URL</li>
<li>🔄 <strong>PUT</strong>: Used to update or replace an existing resource with the complete new version provided in the request body.</li>
<li>🗑️ <strong>DELETE</strong>: Used to remove a specific resource from the server.</li>
</ul>
<h3 id="http-status-codes"><a class="hash" href="#http-status-codes" aria-label="Subsection anchor">##</a>HTTP Status Codes</h3>
<p>Servers use numbers to tell the client what happened with their request.</p>
<ul>
<li><strong>100-199 (Informational):</strong> The request was received, and the process is continuing.</li>
<li><strong>200-299 (Success):</strong> Everything worked! (e.g., 200 OK, 201 Created).</li>
<li><strong>300-399 (Redirect):</strong> The resource has moved to a different location.</li>
<li><strong>400-499 (Client Error):</strong> You (client) did something wrong (e.g., 401 Unauthorized).</li>
<li><strong>500-599 (Server Error):</strong> The server crashed or failed to do its job (e.g, 502 Bad Gateway)</li>
</ul>
<h3 id="security-ssl-tls-and-https"><a class="hash" href="#security-ssl-tls-and-https" aria-label="Subsection anchor">##</a>Security: SSL, TLS, and HTTPS</h3>
<p>Basic <strong>HTTP</strong> is not secure; anyone &quot;listening&quot; on the network could read your data. To fix this, we use <strong>SSL/TLS</strong> (Secure Sockets Layer / Transport Layer Security). This technology encrypts everything you send, making it unreadable to hackers. <strong>HTTPS</strong> is simply the secure version of HTTP, meaning all communication is encrypted via <strong>SSL/TLS</strong>.</p>
<h2 id="summary"><a class="hash" href="#summary" aria-label="Section anchor">#</a>Summary</h2>
<ul>
<li><strong>IP (Internet Protocol):</strong> IP is responsible for routing packets of data to their intended destination.</li>
<li><strong>TCP (Transmission Control Protocol):</strong> Ensures error-free, ordered data delivery using a 3-way handshake and retransmission for lost packets.</li>
<li><strong>UDP (User Datagram Protocol):</strong> Faster than TCP since it skips handshakes and error checking; ideal for streaming, online calls, and gaming, though it doesn’t guarantee order or retransmission.</li>
<li><strong>DNS (Domain Name System):</strong> This system finds the IP address associated with a domain name. The process usually involves the browser or the ISP (Internet Service Provider) checking a cache.</li>
<li><strong>HTTP (Hypertext Transfer Protocol):</strong> An application-layer protocol built on top of TCP using a client-server model, where requests include headers and often a request body (except GET requests, which typically do not have a body).</li>
<li><strong>Security (SSL/TLS and HTTPS):</strong> SSL/TLS is used to encrypt any data sent over the internet to keep it private. HTTPS is simply the secure version of HTTP that uses this encryption.</li>
</ul>
]]></content:encoded></item><item><title>System Design Interview Part 1</title><link>https://blog.shatlykabdullayev.com/articles/system-design-interview-part-1/</link><guid>https://blog.shatlykabdullayev.com/articles/system-design-interview-part-1/</guid><pubDate>Sat, 10 Jan 2026 15:16:36 +0000</pubDate><description>A practical introduction to system design interviews, including architecture, scaling, reliability, latency, and common trade-offs.</description><content:encoded><![CDATA[<h2 id="what-is-system-design-interview-about"><a class="hash" href="#what-is-system-design-interview-about" aria-label="Section anchor">#</a>What is System Design Interview about</h2>
<p>System design interviews is all about - thought process. Its more than just connecting servers and databases. System design requires an engineer to analyze a problem and provide the most efficient solution by determining the best ways to move, store, and transform data.</p>
<h3 id="the-high-level-app-architecture--scaling"><a class="hash" href="#the-high-level-app-architecture--scaling" aria-label="Subsection anchor">##</a>The High-Level App Architecture &amp; Scaling</h3>
<p>The lifecycle of an application begins with the developer building code. Once the code is ready, it is deployed to a server, which then interacts with storage systems (such as databases) and external APIs to fulfill user requests.</p>
<p>As a system grows, its architecture needs to adapt to handle more traffic. That’s where scaling comes in.</p>
<ul>
<li>
<p><strong>Vertical Scaling</strong>: This involves upgrading the hardware of a single server machine, such as increasing its CPU or Storage capacity. While this can improve reliability, it often results in a single point of failure.</p>
</li>
<li>
<p><strong>Horizontal Scaling</strong>: This involves adding several servers to the infrastructure and using a load balancer to distribute traffic among them.</p>
</li>
</ul>
<p>Imagine a small pizza shop. <strong>Horizontal scaling</strong> means opening a several more pizza shops nearby and having someone (like a load balancer) send customers to the shop with the shortest line. <strong>Vertical scaling</strong> means getting a faster, more powerful oven so you can bake pizzas quicker. The big oven works well but if it breaks, you can’t make pizzas. With multiple shops, even if one closes, the others can still serve customers.</p>
<p><img
className="w-full"
src="/static/images/vertical-horizontal-scaling.webp"
alt="illustration of vertical and horizontal scaling"
/></p>
<h3 id="system-health-logging-metrics-and-alerts"><a class="hash" href="#system-health-logging-metrics-and-alerts" aria-label="Subsection anchor">##</a>System Health: Logging, Metrics, and Alerts</h3>
<p>A production-ready system requires constant monitoring to ensure it functions correctly. To achieve this, developers rely on three key supporting services:</p>
<ul>
<li><strong>Logging Servers:</strong> These are used to store logs from applications to track specific errors and issues.</li>
<li><strong>Metrics Services:</strong> These services provide logging analytics, giving developers a clear view of how the server is performing in real-time (ex: <a href="https://grafana.com" target="_blank" rel="noopener">grafana</a>)</li>
<li><strong>Alerts Services</strong> If a metric reaches a dangerous threshold. For example, if a CPU hits 95% - the service will automatically notify the developers so they can take action.</li>
</ul>
<p><img
className="w-full"
src="/static/images/metrics.webp"
alt="metrics"
/></p>
<h3 id="defining-good-design"><a class="hash" href="#defining-good-design" aria-label="Subsection anchor">##</a>Defining &quot;Good&quot; Design</h3>
<p>How do we measure if a design is successful? It usually comes down to how the system handles failure and uptime.</p>
<p>A well-designed system is one that remains available and reliable even in the face of failures.</p>
<ul>
<li><strong>Availability</strong>. We often measure this by looking at logs and metrics.</li>
<li><strong>Reliability</strong>. It reflects the system’s ability to keep working during events like updates, crashes, or DDoS attacks.</li>
</ul>
<p>Achieving this level of reliability requires <strong>fault tolerance</strong> and <strong>redundancy</strong>, meaning the system can continue running even when individual components fail. Techniques like vertical scaling help build this resilience, improving both reliability and overall system health.</p>
<h3 id="fault-tolerance-and-redundancy"><a class="hash" href="#fault-tolerance-and-redundancy" aria-label="Subsection anchor">##</a>Fault Tolerance and Redundancy</h3>
<p>A system is &quot;tolerant&quot; to &quot;faults&quot; if it can continue to operate even when a component fails. This is achieved through <strong>redundancy</strong> - having extra components available so that if one fails, others can help. Vertical scaling is one method used to achieve this fault tolerance and address reliability issues.</p>
<h3 id="performance-metrics-throughput-vs-latency"><a class="hash" href="#performance-metrics-throughput-vs-latency" aria-label="Subsection anchor">##</a>Performance Metrics: Throughput vs. Latency</h3>
<p>To optimize the user experience, developers must balance two critical performance metrics.</p>
<ul>
<li><strong>Throughput</strong>: This measures the capacity of the server, or how many requests it can handle in a specific timeframe (e.g., 10 requests per second)</li>
<li><strong>Latency</strong>: This measures the time it takes for an individual request to complete.</li>
</ul>
<p>High latency is often caused by network issues or the <strong>physical distance</strong> of the user. To combat this, developers use <strong>CDNs (Content Delivery Networks)</strong> to reduce the distance between the data and the user, thereby lowering latency.</p>
<h3 id="summary"><a class="hash" href="#summary" aria-label="Subsection anchor">##</a>Summary</h3>
<ul>
<li><strong>System Design as a Thought Process:</strong> Focuses on analyzing problems to plan efficient ways of moving, storing, and transforming data.</li>
<li><strong>Core Architecture:</strong> Involves developers writing code, deploy to servers that interact with storage systems and external APIs.</li>
<li><strong>Vertical Scaling:</strong> Upgrading a single server’s hardware (CPU, GPU).</li>
<li><strong>Horizontal Scaling:</strong> Adding multiple servers with a load balancer to share traffic.</li>
<li><strong>Monitoring and Maintenance:</strong> Relies on logging (error tracking), metrics (performance analytics), and alerting (threshold notifications) to keep systems healthy.</li>
<li><strong>Reliability &amp; Fault Tolerance:</strong> Ensured through redundancy so other servers can take over if one fails.</li>
<li><strong>Throughput:</strong> Number of requests handled per unit time.</li>
<li><strong>Latency:</strong> Time to complete a single request, reduced using CDNs.</li>
</ul>
]]></content:encoded></item><item><title>The Art of Video Optimization + Snippet</title><link>https://blog.shatlykabdullayev.com/articles/video-optimization/</link><guid>https://blog.shatlykabdullayev.com/articles/video-optimization/</guid><pubDate>Thu, 11 Dec 2025 16:59:36 +0000</pubDate><description>Discover expert techniques optimize Video files, slashing load times and boosting user experience without sacrificing quality.</description><content:encoded><![CDATA[<p>Video content has become essential for modern web applications — from product demos and tutorials to background animations and user-generated content. However, videos consume massive amounts of network bandwidth, often accounting for 60-80% of a page's total data transfer (mdn).</p>
<p>Optimizing video delivery - enhances web performance by reducing <strong>load times</strong> and <strong>bandwidth</strong> usage. Let's see how we can achieve these optimization</p>
<h3 id="using-video-and-source-elements"><a class="hash" href="#using-video-and-source-elements" aria-label="Subsection anchor">##</a>Using <code>&lt;video/&gt;</code> and <code>&lt;source/&gt;</code> elements</h3>
<p>The <code>&lt;video&gt;</code> element with <code>&lt;source&gt;</code> tags allows browsers to select the first compatible video format. Make sure to list <code>&lt;source&gt;</code> elements from <strong>smallest</strong> to <strong>largest</strong> file size so the browser could prioritize the most efficient version.</p>
<div data-pagefind-weight="0.5"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">video</span> <span class="na">muted</span> <span class="na">autoplay</span> <span class="na">loop</span> <span class="na">playsinline</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="c">&lt;!-- Mobile --&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">source</span> <span class="na">media</span><span class="o">=</span><span class="s">&#34;(max-width: 480px)&#34;</span> <span class="na">src</span><span class="o">=</span><span class="s">&#34;videos/mobile.webm&#34;</span> <span class="p">/&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">source</span> <span class="na">media</span><span class="o">=</span><span class="s">&#34;(max-width: 480px)&#34;</span> <span class="na">src</span><span class="o">=</span><span class="s">&#34;videos/mobile.mp4&#34;</span> <span class="p">/&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="c">&lt;!-- Tablet --&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">source</span> <span class="na">media</span><span class="o">=</span><span class="s">&#34;(min-width: 481px)&#34;</span> <span class="na">src</span><span class="o">=</span><span class="s">&#34;videos/tablet.webm&#34;</span> <span class="p">/&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">source</span> <span class="na">media</span><span class="o">=</span><span class="s">&#34;(min-width: 481px)&#34;</span> <span class="na">src</span><span class="o">=</span><span class="s">&#34;videos/tablet.mp4&#34;</span> <span class="p">/&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="c">&lt;!-- Desktop --&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">source</span> <span class="na">media</span><span class="o">=</span><span class="s">&#34;(min-width: 1200px)&#34;</span> <span class="na">src</span><span class="o">=</span><span class="s">&#34;videos/desktop.webm&#34;</span> <span class="p">/&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">source</span> <span class="na">media</span><span class="o">=</span><span class="s">&#34;(min-width: 1200px)&#34;</span> <span class="na">src</span><span class="o">=</span><span class="s">&#34;videos/desktop.mp4&#34;</span> <span class="p">/&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="c">&lt;!-- Fallback content --&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;</span>Your browser does not support video playback.<span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">video</span><span class="p">&gt;</span></span></span></code></pre></div></div><h3 id="code-breakdown"><a class="hash" href="#code-breakdown" aria-label="Subsection anchor">##</a>Code breakdown</h3>
<ul>
<li><code>muted</code> attribute ensures the video plays without sound.</li>
<li><code>loop</code> attribute repeats the video continuously.</li>
<li><code>playsinline</code> attribute allows inline playback on mobile devices.</li>
<li><code>autoplay</code> attribute enables automatic playback of media content.</li>
<li>The browser selects the first <code>&lt;source&gt;</code> supports that matches the media query, ensuring smaller files are <strong>prioritized</strong> for smaller screens.</li>
<li><code>media</code> attribute control which video is loaded based on viewport size.</li>
</ul>
<p>In the example above, we prioritize <code>.webm</code> over <code>.mp4</code> because the <code>.webm</code> format is generally smaller and more efficient.</p>
<p>To enable <em>automatic video playback</em> in browsers, ensure the video is <strong>muted</strong>. Otherwise, playback will start <strong>only after user interaction</strong> with the site. See chrome <a href="https://developer.chrome.com/articles/autoplay/#new_behaviors?ref=blog.shatlykabdullayev.com" target="_blank" rel="noopener">autoplay policy</a> for more info.</p>
<h3 id="video-resizing-with-matchmedia-api-code-snippet"><a class="hash" href="#video-resizing-with-matchmedia-api-code-snippet" aria-label="Subsection anchor">##</a>Video Resizing with matchMedia API (code snippet)</h3>
<p>The following code snippet allows you to dynamically load the appropriate video source based on viewport size using HTML <code>&lt;source&gt;</code> elements and JavaScript media query listeners for optimal performance and responsiveness..</p>
<div data-pagefind-weight="0.5"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kd">function</span> <span class="nx">handleVideoResize</span><span class="p">(</span><span class="nx">videoElement</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="kr">const</span> <span class="nx">sources</span> <span class="o">=</span> <span class="nb">Array</span><span class="p">.</span><span class="nx">from</span><span class="p">(</span><span class="nx">videoElement</span><span class="p">.</span><span class="nx">getElementsByTagName</span><span class="p">(</span><span class="s1">&#39;source&#39;</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="kr">const</span> <span class="nx">updateVideo</span> <span class="o">=</span> <span class="p">()</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">videoElement</span><span class="p">.</span><span class="nx">load</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="nx">updateVideo</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="kr">const</span> <span class="nx">mqls</span> <span class="o">=</span> <span class="nx">sources</span>
</span></span><span class="line"><span class="cl">    <span class="p">.</span><span class="nx">filter</span><span class="p">((</span><span class="nx">source</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="nx">source</span><span class="p">.</span><span class="nx">media</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">.</span><span class="nx">map</span><span class="p">((</span><span class="nx">source</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="kr">const</span> <span class="nx">mql</span> <span class="o">=</span> <span class="nb">window</span><span class="p">.</span><span class="nx">matchMedia</span><span class="p">(</span><span class="nx">source</span><span class="p">.</span><span class="nx">media</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">      <span class="nx">mql</span><span class="p">.</span><span class="nx">addEventListener</span><span class="p">(</span><span class="s1">&#39;change&#39;</span><span class="p">,</span> <span class="nx">updateVideo</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">      <span class="k">return</span> <span class="nx">mql</span>
</span></span><span class="line"><span class="cl">    <span class="p">})</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="p">()</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">mqls</span><span class="p">.</span><span class="nx">forEach</span><span class="p">((</span><span class="nx">mql</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="nx">mql</span><span class="p">.</span><span class="nx">removeEventListener</span><span class="p">(</span><span class="s1">&#39;change&#39;</span><span class="p">,</span> <span class="nx">updateVideo</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span> 
</span></span></code></pre></div></div><h4 id="how-it-works">How it works?</h4>
<ul>
<li>Retrieves all <code>&lt;source&gt;</code> elements from the <code>&lt;video&gt;</code> element.</li>
<li>Triggers <code>video.load()</code> to select the appropriate source based on current <strong>media query</strong> matches.</li>
<li>Sets up <code>matchMedia</code> listeners for each source’s media attribute to reload the video when the viewport size changes.</li>
</ul>
<h3 id="using-mux-for-video-delivery"><a class="hash" href="#using-mux-for-video-delivery" aria-label="Subsection anchor">##</a>Using Mux for Video Delivery</h3>
<p>For my <a href="https://shatlykabdullayev.com/?ref=blog.shatlykabdullayev.com" target="_blank" rel="noopener">personal website</a>, I chose Mux to handle video optimization. It automatically converts uploads to <strong>HLS</strong> format and creates multiple quality variants for adaptive streaming</p>
<p>Videos only start loading when they appear on screen as users scroll down. This makes pages load faster and saves data. While videos load, I show blurred preview images so users don't see empty spaces</p>
<p><strong>The Result:</strong> fast page loads, smooth playback, and a hands-off pipeline where Mux handles transcoding and CDN distribumatchMedia ion automatically.</p>
<h3 id="general-advices-for-video-optimization"><a class="hash" href="#general-advices-for-video-optimization" aria-label="Subsection anchor">##</a>General Advices for video Optimization</h3>
<ul>
<li>Replace decorative videos (eg: background videos) with animated <strong>WebP</strong> or <strong>GIF</strong> (70-90% smaller)</li>
<li>Lower framerate where appropriate (30fps → 24fps)</li>
<li>Use <strong>FFmpeg</strong> or similar tools for video compression</li>
<li>Set <code>preload=&quot;none&quot;</code> attribute for videos that not immediately visible on screen</li>
</ul>
<h2 id="summary"><a class="hash" href="#summary" aria-label="Section anchor">#</a>Summary</h2>
<ul>
<li><strong>Using <code>&lt;video/&gt;</code> and <code>&lt;source/&gt;</code></strong>: Order sources smallest to largest with media queries. Prioritize WebM over MP4 and use muted for autoplay.</li>
<li><strong>Dynamic Video Resizing</strong>: matchMedia API automatically switches video sources on viewport changes for responsive playback.</li>
<li><strong>Real-World Implementation</strong>: Mux handles HLS conversion and adaptive streaming. Videos load on scroll with blurred placeholders.</li>
<li><strong>General Tips</strong>: Use WebP/GIF for backgrounds, reduce to 24fps, compress with FFmpeg, set preload=&quot;none&quot;, and use adaptive streaming.</li>
</ul>
]]></content:encoded></item><item><title>My best Frontend Resources</title><link>https://blog.shatlykabdullayev.com/articles/my-best-resources/</link><guid>https://blog.shatlykabdullayev.com/articles/my-best-resources/</guid><pubDate>Wed, 29 Oct 2025 15:16:36 +0000</pubDate><description>Handpicked list of the best frontend and design resources. Discover the Latest Web Resources for Development &amp; Design.</description><content:encoded><![CDATA[<h2 id="my-best-web-and-design-resources-for-2025"><a class="hash" href="#my-best-web-and-design-resources-for-2025" aria-label="Section anchor">#</a>My Best Web and Design Resources for 2025</h2>
<p>I believe that every developer has a curated list of resources they rely on daily. Whether you're a beginner or a seasoned pro, these resources can elevate your workflow. Here's my handpicked list of the best frontend and design resources I use daily.</p>
<p><strong>Check out my <a href="https://youtu.be/nmrzwQNWyZc" target="_blank" rel="noopener">YouTube video</a> where I showcase all the resources listed above in action</strong></p>
<h2 id="design-inspiration"><a class="hash" href="#design-inspiration" aria-label="Section anchor">#</a>Design Inspiration</h2>
<p>These platforms provide a wealth of creative ideas to fuel your next project:</p>
<ul>
<li><strong><a href="https://minimal.gallery/" target="_blank" rel="noopener">Minimal Gallery</a></strong>: Discover minimalist website designs with intuitive filtering, perfect for clean and modern aesthetics.</li>
<li><strong><a href="https://www.cosmos.so/discover/ui-ux" target="_blank" rel="noopener">Cosmos</a></strong>: A treasure trove of unique images and innovative UI/UX ideas to inspire your designs.</li>
<li><strong><a href="https://www.unsection.com/" target="_blank" rel="noopener">Unsection</a></strong>: Explore over 1,000 categorized web pages with easy filtering for quick inspiration.</li>
<li><strong><a href="https://www.supahero.io/" target="_blank" rel="noopener">Supahero</a></strong>: Find top-tier hero sections to make your website’s first impression unforgettable.</li>
<li><strong><a href="https://stacksorted.com/" target="_blank" rel="noopener">Stack Sorted</a></strong>: Browse a curated collection of the best web designs, organized by elements for easy reference.</li>
<li><strong><a href="https://www.awwwards.com/" target="_blank" rel="noopener">Awwwards</a></strong>: A showcase of the world’s finest websites, recognized for their creativity and craftsmanship.</li>
</ul>
<h2 id="catalog-of-ready-made-components"><a class="hash" href="#catalog-of-ready-made-components" aria-label="Section anchor">#</a>Catalog of Ready Made Components</h2>
<p>Save time for development with these open-source resources:</p>
<ul>
<li><strong><a href="https://www.builtatlightspeed.com/" target="_blank" rel="noopener">Built At Light</a></strong>: A marketplace offering free and paid UI kits, templates, and components with excellent filtering options.</li>
<li><strong><a href="https://tympanus.net/codrops/demos" target="_blank" rel="noopener">Codrops</a></strong>: High-quality, open-source components primarily built with HTML, CSS, and JavaScript.</li>
<li><strong><a href="https://ui.aceternity.com/" target="_blank" rel="noopener">Aceternity UI</a></strong>: Stunning components for React, powered by Tailwind and Framer Motion for seamless animations.</li>
<li><strong><a href="https://www.edil-ozi.pro/" target="_blank" rel="noopener">Edil Ozi</a></strong>: A robust library of React components using Tailwind, Framer Motion, and GSAP for dynamic designs.</li>
<li><strong><a href="https://ui.shadcn.com/" target="_blank" rel="noopener">Shad CN</a></strong>: Customizable components for React and Tailwind, ideal for building your own component library.</li>
<li><strong><a href="https://motion-primitives.com/" target="_blank" rel="noopener">Motion Primitives</a></strong>: Beautifully animated components leveraging Framer Motion and Tailwind.</li>
<li><strong><a href="https://uiverse.io/" target="_blank" rel="noopener">UI Verse</a></strong>: A daily-updated collection of UI components built with HTML and CSS/Tailwind.</li>
<li><strong><a href="https://blog.olivierlarose.com/tutorials" target="_blank" rel="noopener">Olivier Larose</a></strong>: Expert tutorials and components focusing on motion design with GSAP, Framer Motion, and React.</li>
</ul>
<blockquote>
<p>You can find this list in my <a href="https://github.com/shatlyk1011/my-best-frontend-resources" target="_blank" rel="noopener">github</a>, which I update periodically with new links 🙂</p>
</blockquote>
<h2 id="stock-images"><a class="hash" href="#stock-images" aria-label="Section anchor">#</a>Stock Images</h2>
<p>High-quality visuals to elevate your projects:</p>
<ul>
<li><strong><a href="https://www.lummi.ai/" target="_blank" rel="noopener">Lummi AI</a></strong>: AI-generated images and illustrations, perfect for unique visuals.</li>
<li><strong><a href="https://unsplash.com/" target="_blank" rel="noopener">Unsplash</a></strong>: A vast library of professional, royalty-free photos.</li>
<li><strong><a href="https://www.pexels.com/" target="_blank" rel="noopener">Pexels</a></strong>: Free stock photos contributed by a global community of photographers.</li>
</ul>
<p><strong>Pro Tip</strong>: Optimize your images with <a href="https://squoosh.app/" target="_blank" rel="noopener">Squoosh</a> to ensure fast-loading websites without sacrificing quality.</p>
<h2 id="artificial-intelligence-for-various-use-cases"><a class="hash" href="#artificial-intelligence-for-various-use-cases" aria-label="Section anchor">#</a>Artificial Intelligence for Various Use Cases</h2>
<p>AI tools to supercharge your development process:</p>
<ul>
<li><strong><a href="https://ideogram.ai/" target="_blank" rel="noopener">Ideogram</a></strong>: Generate high-quality images with a free tier, ideal for custom visuals.</li>
<li><strong><a href="https://grok.com/" target="_blank" rel="noopener">Grok AI</a></strong>: My preferred AI for coding assistance, offering practical and accurate solutions.</li>
<li><strong><a href="https://app.leonardo.ai/" target="_blank" rel="noopener">Leonardo AI</a></strong>: Create stunning images with a daily-refreshed free tier.</li>
<li><strong><a href="https://easywithai.com/" target="_blank" rel="noopener">Easy With AI</a></strong>: A curated collection of AI tools for diverse use cases, from design to development.</li>
</ul>
<h2 id="other-useful-sources"><a class="hash" href="#other-useful-sources" aria-label="Section anchor">#</a>Other Useful Sources</h2>
<p>Other Useful Sources</p>
<ul>
<li><strong><a href="http://wappalyzer.com/" target="_blank" rel="noopener">Wappalyzer</a></strong>: Analyze the technologies powering any website, perfect for competitive research.</li>
<li><strong><a href="https://jitter.video/" target="_blank" rel="noopener">Jitter Video</a></strong>: Create and customize video templates for engaging web content.</li>
<li><strong><a href="https://squoosh.app/" target="_blank" rel="noopener">Squoosh</a></strong>: Google Chrome Labs’ image compression tool for optimizing visuals effortlessly.</li>
</ul>
]]></content:encoded></item><item><title>The Art of Image Optimization</title><link>https://blog.shatlykabdullayev.com/articles/image-optimization/</link><guid>https://blog.shatlykabdullayev.com/articles/image-optimization/</guid><pubDate>Sun, 05 Oct 2025 15:16:36 +0000</pubDate><description>Discover expert techniques to compress and optimize images, slashing load times and boosting user experience without sacrificing quality.</description><content:encoded><![CDATA[<p>Did you know that 70% of download resources on average websites are <strong>images</strong> and <strong>videos</strong>? (mdn)</p>
<p>Web performance is critical for user satisfaction and engagement. One of the most effective ways to enhance website speed is through <strong>image optimization</strong> .</p>
<p>We’ll explore several key technique for image optimization.</p>
<h3 id="using-srcset-and-loading-attributes"><a class="hash" href="#using-srcset-and-loading-attributes" aria-label="Subsection anchor">##</a>Using <code>srcset</code> and <code>loading</code> attributes</h3>
<p>The <code>srcset</code> attribute is a powerful tool that allows developers to provide multiple image sources tailored to different screen pixel ratios or device resolutions. By serving the most appropriate image size based on the user’s device, <code>srcset</code> reduces unnecessary data transfer, leading to faster page loads and a better user experience.</p>
<div data-pagefind-weight="0.5"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">img</span> 
</span></span><span class="line"><span class="cl">  <span class="na">src</span><span class="o">=</span><span class="s">&#34;/bg-1.png&#34;</span> 
</span></span><span class="line"><span class="cl">  <span class="na">srcset</span><span class="o">=</span><span class="s">&#34;/bg-2x.png 2x&#34;</span> 
</span></span><span class="line"><span class="cl">  <span class="na">loading</span><span class="o">=</span><span class="s">&#34;lazy&#34;</span> 
</span></span><span class="line"><span class="cl">  <span class="na">alt</span><span class="o">=</span><span class="s">&#34;background image&#34;</span>
</span></span><span class="line"><span class="cl"><span class="p">/&gt;</span></span></span></code></pre></div></div><h4 id="code-breakdown">Code breakdown</h4>
<ul>
<li>The <code>src</code> attribute specifies the <strong>default</strong> image source - <code>/bg-1.png</code>. This is the fallback image used by browsers that don’t support <code>srcset</code> or when no other conditions match.</li>
<li>The <code>srcset</code> attribute provides a comma-separated list of image sources along with their respective <a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/devicePixelRatio" target="_blank" rel="noopener">pixel density</a>.</li>
<li><code>/bg-2x.png 2x</code> is served for devices with higher pixel ratios. Here is <code>2x</code> indicates using this image source for higher pixel density screens, e.g., for Retina displays.</li>
<li><code>loading=&quot;lazy&quot;</code> attribute enables lazy loading, a technique that defers the loading of images until they are about to enter the viewport. This reduces initial page load time by prioritizing content that is immediately visible to the user.</li>
</ul>
<h4 id="why-this-important">Why this important?</h4>
<p>By offering different image resolutions, the browser selects the <strong>most appropriate</strong> image based on the device’s pixel density, reducing the loading of unnecessarily large files on lower-resolution screens.</p>
<h3 id="using-picture-and-source-elements"><a class="hash" href="#using-picture-and-source-elements" aria-label="Subsection anchor">##</a>Using picture and source elements</h3>
<p>The <code>&lt;picture&gt;</code> element is a modern HTML feature that allows developers to provide multiple image sources for different scenarios, enabling browsers to choose the most appropriate image based on factors like screen size, resolution, or device density. This flexibility is key to delivering optimized images that balance quality and performance.</p>
<div data-pagefind-weight="0.5"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">picture</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">source</span> 
</span></span><span class="line"><span class="cl">    <span class="na">media</span><span class="o">=</span><span class="s">&#34;(max-width: 1440px)&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="na">srcset</span><span class="o">=</span><span class="s">&#34;large-bg-1x.png 1x,
</span></span></span><span class="line"><span class="cl"><span class="s">    large-bg-2x.png 2x&#34;</span> 
</span></span><span class="line"><span class="cl">  <span class="p">/&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">source</span> 
</span></span><span class="line"><span class="cl">    <span class="na">media</span><span class="o">=</span><span class="s">&#34;(max-width: 600px)&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="na">srcset</span><span class="o">=</span><span class="s">&#34;small-bg-1x.png 1x,
</span></span></span><span class="line"><span class="cl"><span class="s">    small-bg-2x.png 2x&#34;</span> 
</span></span><span class="line"><span class="cl">  <span class="p">/&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="c">&lt;!-- fallback image --&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">img</span> 
</span></span><span class="line"><span class="cl">    <span class="na">src</span><span class="o">=</span><span class="s">&#34;large-bg.png&#34;</span> 
</span></span><span class="line"><span class="cl">    <span class="na">alt</span><span class="o">=</span><span class="s">&#34;background image&#34;</span> 
</span></span><span class="line"><span class="cl">  <span class="p">/&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">picture</span><span class="p">&gt;</span></span></span></code></pre></div></div><h4 id="code-breakdown-1">Code breakdown</h4>
<ul>
<li>
<p>The <code>&lt;picture&gt;</code> element acts as a wrapper that contains one or more <code>&lt;source&gt;</code> elements and optional fallback <code>&lt;img&gt;</code> element.</p>
</li>
<li>
<p>It gives the browser options to choose the best image source based on defined criteria, such as the viewport size or device characteristics.</p>
</li>
<li>
<p>The first <code>&lt;source&gt;</code> provides <code>large-bg-1x.png 1x</code> and <code>large-bg-2x.png 2x</code> for viewports less than 1440 pixels <code>media=&quot;(max-width: 1440px)&quot;</code>. Here are the sources with large images. Additionally, we're using <code>srcset</code> for various pixel densities.</p>
</li>
<li>
<p>The second <code>&lt;source&gt;</code> provides <code>small-bg-1x.png 1x</code> and <code>small-bg-2x.png 2x</code> for viewports 600 pixels or less (media=&quot;(max-width: 600px)&quot;). Here are the sources with small images. Additionally, we're using <code>srcset</code> for various pixel densities.</p>
</li>
<li>
<p>The browser reads (from top to bottom) the source element conditions and selects the first matching <code>&lt;source&gt;</code> element to load the appropriate image. If no condition satisfies, the fallback <code>&lt;img/&gt;</code> will be used.</p>
</li>
</ul>
<h4 id="why-this-important-1">Why this important?</h4>
<ul>
<li>
<p>By serving smaller images to devices with smaller viewports, we reduce the amount of data transferred. Smaller images mean faster load times, especially on mobile devices with limited bandwidth.</p>
</li>
<li>
<p>Delivering appropriately sized images ensures that users see visuals tailored to their device’s screen size and resolution.</p>
</li>
<li>
<p>Faster-loading pages improve key web performance metrics like Largest Contentful Paint (LCP) and First Contentful Paint (FCP), which are part of Google’s Core Web Vitals. Better scores can boost your site’s search engine rankings.</p>
</li>
<li>
<p>The <code>&lt;picture&gt;</code> element supports art direction, allowing you to serve different image compositions (e.g., a close-up portrait for mobile vs. a wider shot for desktop). This ensures the image is visually optimized for each context, enhancing both aesthetics and performance.</p>
</li>
</ul>
<blockquote>
<p>Why should I use the <code>&lt;picture&gt;</code> element for image optimization when built-in components like <strong>Next Image</strong> already provide image optimization features?</p>
</blockquote>
<p>Next.js’s <code>&lt;Image&gt;</code> component, are tightly integrated with specific hosting platforms like Vercel. This convenience comes at a cost:</p>
<ul>
<li>
<p>Platforms like Vercel impose limits on image optimization usage, especially on free or hobby tiers. For example, Vercel’s free tier caps optimized images at 1,000 per month, which can be quickly exhausted for image-heavy sites, leading to broken images or the need to upgrade to a paid plan.</p>
</li>
<li>
<p>Relying on a platform’s image optimization service can make it harder to migrate to another hosting provider without losing the benefits of automated optimization or needing to reconfigure your setup.</p>
</li>
<li>
<p>Potential for Over-Optimization: Automated tools may overly compress images, leading to a noticeable loss in quality that can harm the visual appeal of your site, especially for high-resolution displays. Similarly, <a href="https://docs.astro.build/en/guides/images/#default-image-service" target="_blank" rel="noopener">Astro’s</a> default image optimization with Sharp may not allow for the same level of customization as manual optimization pipelines</p>
</li>
</ul>
<p><em>See browser supports for <a href="https://caniuse.com/picture" target="_blank" rel="noopener">picture</a> element.</em></p>
<h3 id="use-modern-image-formats"><a class="hash" href="#use-modern-image-formats" aria-label="Subsection anchor">##</a>Use Modern Image Formats</h3>
<p>New image formats like <code>.webp</code> make images smaller without losing quality. Smaller images mean faster loading and less data used by your users.</p>
<p><em>See browser supports for <a href="https://caniuse.com/webp" target="_blank" rel="noopener">.webp</a> format.</em></p>
<h3 id="always-add-alt-text-to-images"><a class="hash" href="#always-add-alt-text-to-images" aria-label="Subsection anchor">##</a>Always Add <code>alt</code> Text to Images</h3>
<p>Alt text is a short description of the image. It helps people who can't see the image and also helps search engines understand your content. Big platforms like Instagram even use AI to automatically generate descriptions based on what's shown in the image.</p>
<h3 id="tips-for-picture-element"><a class="hash" href="#tips-for-picture-element" aria-label="Subsection anchor">##</a>Tips for <code>&lt;picture/&gt;</code> element</h3>
<p>To maximize the benefits of the <code>&lt;picture&gt;</code> element, use these tips:</p>
<ul>
<li>
<p>Use tools like TinyPNG, or Squoosh to compress images without losing quality. Here you can find good <a href="/articles/my-best-resources/#other-useful-sources">resources</a></p>
</li>
<li>
<p>Test Responsiveness: Use browser developer tools to simulate different screen sizes and ensure the correct image is loaded.</p>
</li>
</ul>
<h2 id="summary"><a class="hash" href="#summary" aria-label="Section anchor">#</a>Summary</h2>
<ul>
<li>
<p><strong>Image Optimization:</strong> Use <code>srcset</code> to show the right image size for different devices and loading to delay loading off-screen images. The <code>&lt;picture&gt;</code> element helps pick the best image for the screen size to speed up page loads.</p>
</li>
<li>
<p><strong>Tips:</strong> Use tools like <strong>TinyPNG</strong> or <strong>Squoosh</strong> to shrink images, test how images look on different screens, and check browser support for better performance.</p>
</li>
</ul>
]]></content:encoded></item><item><title>Web Storage - Cookies vs. Local Storage vs. Session Storage vs. IndexedDB</title><link>https://blog.shatlykabdullayev.com/articles/web-storage/</link><guid>https://blog.shatlykabdullayev.com/articles/web-storage/</guid><pubDate>Sat, 20 Sep 2025 12:29:44 +0000</pubDate><description>A comparison of cookies, Local Storage, Session Storage, and IndexedDB, with guidance on when to use each browser storage option.</description><content:encoded><![CDATA[<h2 id="overview"><a class="hash" href="#overview" aria-label="Section anchor">#</a>Overview</h2>
<p>Storing data on the client side is essential for creating seamless user experiences. Whether it's remembering a user's login session, saving preferences, or handling large datasets for offline functionality, choosing the right storage mechanism can make or break your application's performance and security.</p>
<p>In this blog post, we'll dive into four popular web storage options: <code>Cookies</code>, <code>Local Storage</code>, <code>Session Storage</code>, and <code>IndexedDB</code>. We'll explore how each works, their pros and cons, key differences, and real-world examples. By the end, you'll have a clear understanding of when to use each one.</p>
<h3 id="cookies"><a class="hash" href="#cookies" aria-label="Subsection anchor">##</a>Cookies</h3>
<p>Cookies are one of the oldest ways to store data in the browser. The browser can store cookies, create new cookies, modify existing ones, and send them back to the server with later requests. Let’s break down what they are, how they function, and why they’re still important in an era of JWTs, localStorage, and sophisticated APIs.</p>
<h4 id="what-are-cookies">What Are Cookies?</h4>
<p>Cookies are small pieces of data stored in the browser and exchanged between client and server. They help websites keep track of data between page loads across multiple requests — something HTTP itself doesn’t provide. For users, this means not having to log in again every time. For developers, it’s an easy way to persist identifiers, preferences, and sessions.</p>
<h4 id="how-cookies-work">How Cookies Work</h4>
<ul>
<li>
<p>Server to Client – When the server wants to store some data in the browser, it uses the <code>Set-Cookie</code> header in an HTTP response.</p>
</li>
<li>
<p>Client to Server – On the later requests, the browser automatically includes the cookie in the Cookie header.</p>
</li>
<li>
<p>JavaScript Access (Optional) – On the client-side, cookies are accessible via <code>document.cookie[key]</code>, unless flagged as HttpOnly.</p>
</li>
</ul>
<p>Cookies are best suited for small, essential data (like tokens, IDs, and preferences), rather than large chunks of data. Browsers usually allow a few hundred cookies with ~4KB of maximum size for per cookie.</p>
<p>Cookies can expire with the session - deleted once the browser closes or persist long-term - Controlled via <code>Expires</code> or <code>Max-Age</code> attributes.</p>
<p>Here is an example with date expire. When the date passes, the browser deletes it automatically.</p>
<div data-pagefind-weight="0.5"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kd">let</span> <span class="nx">date</span> <span class="o">=</span> <span class="k">new</span> <span class="nb">Date</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="c1">// Set cookie for 7 days
</span></span></span><span class="line"><span class="cl"><span class="nx">date</span><span class="p">.</span><span class="nx">setDate</span><span class="p">(</span><span class="nx">date</span><span class="p">.</span><span class="nx">getDate</span><span class="p">()</span> <span class="o">+</span> <span class="mi">7</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nb">document</span><span class="p">.</span><span class="nx">cookie</span> <span class="o">=</span> <span class="sb">`rememberMe=true; expires=</span><span class="si">${</span><span class="nx">date</span><span class="p">.</span><span class="nx">toUTCString</span><span class="p">()</span><span class="si">}</span><span class="sb">`</span></span></span></code></pre></div></div><p>Think of cookies as small sticky notes in the browser. They’re reliable for remembering sessions and preferences but not made for storing big chunks of data. If you want to store large data, use <code>localStorage</code> or <code>indexedDB</code>.</p>
<h4 id="security">Security</h4>
<p>While JavaScript can create cookies, the most secure ones (HttpOnly, Secure, SameSite) must be set from the server — you can’t add those flags via <code>document.cookie</code>.</p>
<div data-pagefind-weight="0.5"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="nx">res</span><span class="p">.</span><span class="nx">cookie</span><span class="p">(</span><span class="s1">&#39;sessionId&#39;</span><span class="p">,</span> <span class="s1">&#39;qwerty123&#39;</span><span class="p">,</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">httpOnly</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nx">secure</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nx">sameSite</span><span class="o">:</span> <span class="s1">&#39;Strict&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"><span class="p">})</span></span></span></code></pre></div></div><p>This means <a href="https://en.wikipedia.org/wiki/Cross-site_scripting" target="_blank" rel="noopener">malicious scripts</a> touching <code>document.cookie</code> won’t see your session token.</p>
<h4 id="local-storage">Local Storage</h4>
<p>Modern web apps need ways to store data in the browser. One of the simplest and most widely used APIs for this is LocalStorage. Unlike cookies, it’s not automatically sent with every request to the server, making it ideal for client-side persistence.</p>
<p>LocalStorage is part of the <a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage" target="_blank" rel="noopener">Web Storage API</a>. It stores data as strings and ties that data to the origin (protocol + domain + port). It’s <code>synchronous</code>, meaning each read/write blocks execution until it’s done, but it’s fast enough for small to medium data.</p>
<div data-pagefind-weight="0.5"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="c1">// Store a value (key, value)
</span></span></span><span class="line"><span class="cl"><span class="nx">localStorage</span><span class="p">.</span><span class="nx">setItem</span><span class="p">(</span><span class="s1">&#39;theme&#39;</span><span class="p">,</span> <span class="s1">&#39;dark&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// Get a value (key)
</span></span></span><span class="line"><span class="cl"><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">localStorage</span><span class="p">.</span><span class="nx">getItem</span><span class="p">(</span><span class="s1">&#39;theme&#39;</span><span class="p">))</span> <span class="c1">// 👉 &#34;dark&#34;
</span></span></span></code></pre></div></div><blockquote>
<p>LocalStorage can hold 5MB of data for per site origin.</p>
</blockquote>
<p>Unlike cookies, LocalStorage items don’t expire automatically — they stay saved until you remove them in code, the user clears their browser data, or the session ends in incognito/private mode.</p>
<div data-pagefind-weight="0.5"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="c1">// Save a value
</span></span></span><span class="line"><span class="cl"><span class="nx">localStorage</span><span class="p">.</span><span class="nx">setItem</span><span class="p">(</span><span class="s1">&#39;username&#39;</span><span class="p">,</span> <span class="s1">&#39;Alice&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// Remove just one key
</span></span></span><span class="line"><span class="cl"><span class="nx">localStorage</span><span class="p">.</span><span class="nx">removeItem</span><span class="p">(</span><span class="s1">&#39;username&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">localStorage</span><span class="p">.</span><span class="nx">getItem</span><span class="p">(</span><span class="s1">&#39;username&#39;</span><span class="p">))</span> <span class="c1">// 👉 null
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// Remove all keys at once
</span></span></span><span class="line"><span class="cl"><span class="nx">localStorage</span><span class="p">.</span><span class="nx">clear</span><span class="p">()</span></span></span></code></pre></div></div><p>You can think of LocalStorage as a personal locker in the browser — it’s big enough for app data and preferences, stays around for long periods, and is quick and easy to use. LocalStorage works best for storing app state, user preferences, and cached data</p>
<h4 id="security-1">Security</h4>
<p>LocalStorage follows the <a href="https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy" target="_blank" rel="noopener">same-origin policy</a> - only the same domain can access the data.</p>
<blockquote>
<p>Do NOT store sensitive data (auth tokens, passwords) in LocalStorage — <strong>it’s fully accessible to JavaScript and any XSS vulnerability.</strong></p>
</blockquote>
<h4 id="pros">Pros</h4>
<p>LocalStorage is easy to use with its simple setItem/getItem API. It provides much larger space (about 5–10MB compared to cookies’ 4KB), performs better since data isn’t sent to the server, and works well for caching.</p>
<h4 id="cons">Cons</h4>
<p>However, it has downsides — operations are <code>synchronous</code> and can slow things down if used heavily, it only stores <code>strings</code> so objects need <strong>JSON conversion</strong>, it has no built-in expiration system, and because it’s accessible to JavaScript, it isn’t safe for storing sensitive information.</p>
<h4 id="session-storage">Session Storage</h4>
<p>Session Storage is similar to Local Storage but with a shorter lifespan, making it ideal for <strong>temporary data</strong>. It lives only as long as the browser tab or window is open. It’s great for cases where you want to keep state within a tab but don’t need it after the user closes it.</p>
<p>Session Storage works almost the same way as LocalStorage: it stores key-value pairs (as strings) that can be set and retrieved with <code>setItem</code> and <code>getItem</code>.</p>
<p>The Difference is &quot;The data stays there after reload, but disappears when the tab or window closes.&quot;</p>
<div data-pagefind-weight="0.5"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="c1">// Save data for the session (key, value)
</span></span></span><span class="line"><span class="cl"><span class="nx">sessionStorage</span><span class="p">.</span><span class="nx">setItem</span><span class="p">(</span><span class="s2">&#34;tabId&#34;</span><span class="p">,</span> <span class="s2">&#34;12345&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// Read it back (key)
</span></span></span><span class="line"><span class="cl"><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">sessionStorage</span><span class="p">.</span><span class="nx">getItem</span><span class="p">(</span><span class="s2">&#34;tabId&#34;</span><span class="p">));</span> <span class="c1">// 👉 &#34;12345&#34;
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// Remove it
</span></span></span><span class="line"><span class="cl"><span class="nx">sessionStorage</span><span class="p">.</span><span class="nx">removeItem</span><span class="p">(</span><span class="s2">&#34;tabId&#34;</span><span class="p">);</span></span></span></code></pre></div></div><blockquote>
<p><code>SessionStorage</code> and <code>LocalStorage</code> share the same 5MB of data for per site origin.</p>
</blockquote>
<h4 id="security-2">Security</h4>
<p>SessionStorage follows the <a href="https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy" target="_blank" rel="noopener">same-origin policy</a> - only the same domain can access the data.</p>
<h4 id="pros-1">Pros</h4>
<p>Session Storage is separate for each tab, so data doesn’t conflict across tabs. It also <code>clears automatically</code> when the tab closes, making it great for temporary state like form inputs or filters.</p>
<h4 id="cons-1">Cons</h4>
<p>The drawback is that data is lost when the tab closes, so it’s not for long-term use. It also has the same limits as LocalStorage — <code>synchronous</code> and string-only.</p>
<h3 id="indexeddb"><a class="hash" href="#indexeddb" aria-label="Subsection anchor">##</a>IndexedDB</h3>
<p>When you need to store large or complex data in the browser — <code>IndexedDB</code> is the way to go. It’s a full-fledged database inside the browser, designed for handling structured data efficiently.</p>
<p>IndexedDB allows much larger storage than cookies or LocalStorage: 10GB+ for IndesxedDB ( varies 10–60% of available disk space).</p>
<p>Just like LocalStorage, IndexedDB data is persistent — it survives page reloads and browser restarts, follows the <a href="https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy" target="_blank" rel="noopener">same-origin policy</a> so each site has its own database, and remains stored until the user manually clears it through settings or a cache wipe.</p>
<p>YouTube Premium demonstrates IndexedDB in action, storing downloaded videos as binary blobs for <strong>offline</strong> viewing in the browser.</p>
<div data-pagefind-weight="0.5"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="c1">// Open (or create) a database
</span></span></span><span class="line"><span class="cl"><span class="kd">let</span> <span class="nx">request</span> <span class="o">=</span> <span class="nx">indexedDB</span><span class="p">.</span><span class="nx">open</span><span class="p">(</span><span class="s1">&#39;MyDB&#39;</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// Run when DB is created or version changes
</span></span></span><span class="line"><span class="cl"><span class="nx">request</span><span class="p">.</span><span class="nx">onupgradeneeded</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="kd">let</span> <span class="nx">db</span> <span class="o">=</span> <span class="nx">e</span><span class="p">.</span><span class="nx">target</span><span class="p">.</span><span class="nx">result</span>
</span></span><span class="line"><span class="cl">  <span class="kd">let</span> <span class="nx">store</span> <span class="o">=</span> <span class="nx">db</span><span class="p">.</span><span class="nx">createObjectStore</span><span class="p">(</span><span class="s1">&#39;users&#39;</span><span class="p">,</span> <span class="p">{</span> <span class="nx">keyPath</span><span class="o">:</span> <span class="s1">&#39;id&#39;</span> <span class="p">})</span>
</span></span><span class="line"><span class="cl">  <span class="nx">store</span><span class="p">.</span><span class="nx">createIndex</span><span class="p">(</span><span class="s1">&#39;name&#39;</span><span class="p">,</span> <span class="s1">&#39;name&#39;</span><span class="p">,</span> <span class="p">{</span> <span class="nx">unique</span><span class="o">:</span> <span class="kc">false</span> <span class="p">})</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// On success event
</span></span></span><span class="line"><span class="cl"><span class="nx">request</span><span class="p">.</span><span class="nx">onsuccess</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="kd">let</span> <span class="nx">db</span> <span class="o">=</span> <span class="nx">e</span><span class="p">.</span><span class="nx">target</span><span class="p">.</span><span class="nx">result</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="c1">// Add a record
</span></span></span><span class="line"><span class="cl">  <span class="kd">let</span> <span class="nx">tx</span> <span class="o">=</span> <span class="nx">db</span><span class="p">.</span><span class="nx">transaction</span><span class="p">(</span><span class="s1">&#39;users&#39;</span><span class="p">,</span> <span class="s1">&#39;readwrite&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="kd">let</span> <span class="nx">store</span> <span class="o">=</span> <span class="nx">tx</span><span class="p">.</span><span class="nx">objectStore</span><span class="p">(</span><span class="s1">&#39;users&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="nx">store</span><span class="p">.</span><span class="nx">add</span><span class="p">({</span> <span class="nx">id</span><span class="o">:</span> <span class="mi">1</span><span class="p">,</span> <span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;Alice&#39;</span><span class="p">,</span> <span class="nx">age</span><span class="o">:</span> <span class="mi">25</span> <span class="p">})</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="nx">tx</span><span class="p">.</span><span class="nx">oncomplete</span> <span class="o">=</span> <span class="p">()</span> <span class="p">=&gt;</span> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">&#39;User added ✅&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></div></div><h3 id="comparison-table"><a class="hash" href="#comparison-table" aria-label="Subsection anchor">##</a>Comparison table</h3>
<div class="tbl-wrap">
  <table>
    <thead>
      <tr>
        <th>Feature</th>
        <th>Cookies</th>
        <th>Local Storage</th>
        <th>Session Storage</th>
        <th>IndexedDB</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td><strong>Size Limit</strong></td>
        <td>~4KB per cookie</td>
        <td>5–10 MiB per origin</td>
        <td>5–10 MiB per origin</td>
        <td>Up to 10–60% of disk</td>
      </tr>
      <tr>
        <td><strong>Persistence</strong></td>
        <td>Session or set expiration</td>
        <td>Across sessions</td>
        <td>Tab/session only</td>
        <td>Across sessions</td>
      </tr>
      <tr>
        <td><strong>Access</strong></td>
        <td>Client &amp; Server</td>
        <td>Client only</td>
        <td>Client only</td>
        <td>Client only</td>
      </tr>
      <tr>
        <td><strong>Data Type</strong></td>
        <td>Strings</td>
        <td>Strings (JSON for objects)</td>
        <td>Strings (JSON for objects)</td>
        <td>Structured objects/blobs</td>
      </tr>
      <tr>
        <td><strong>Sent with Requests</strong></td>
        <td>Yes</td>
        <td>No</td>
        <td>No</td>
        <td>No</td>
      </tr>
      <tr>
        <td><strong>Async/Sync</strong></td>
        <td>Sync</td>
        <td>Sync</td>
        <td>Sync</td>
        <td>Async</td>
      </tr>
      <tr>
        <td><strong>Use Case</strong></td>
        <td>Sessions, tracking</td>
        <td>Persistent preferences</td>
        <td>Temporary tab data</td>
        <td>Large/offline data</td>
      </tr>
    </tbody>
  </table>
</div>
<h2 id="summary"><a class="hash" href="#summary" aria-label="Section anchor">#</a>Summary</h2>
<h4 id="cookies-1">Cookies</h4>
<ul>
<li>Oldest storage mechanism; exchanged between client &amp; server with each request.</li>
<li>Ideal for small data (sessions, tokens, preferences).</li>
<li>~4KB per cookie limit, automatically sent to server.</li>
<li>Support secure flags: HttpOnly, Secure, SameSite.</li>
<li>Best for: authentication sessions, persistent login, user tracking.</li>
</ul>
<h4 id="local-storage-1">Local Storage</h4>
<ul>
<li>Part of Web Storage API, stores up to 5–10MB per origin.</li>
<li>Data persists until manually removed (or browser cleared).</li>
<li>Stores strings only; requires JSON for objects.</li>
<li>Not secure for sensitive info (accessible to JavaScript, XSS risk).</li>
<li>Best for: user preferences, cached app data, UI state.</li>
</ul>
<h4 id="session-storage-1">Session Storage</h4>
<ul>
<li>Works like LocalStorage, but tied to a single browser tab/session.</li>
<li>Data clears automatically when the tab/window closes.</li>
<li>5MB limit and string-only, synchronous API.</li>
<li>Best for: temporary data like form inputs, filters, or in-progress state.</li>
</ul>
<h4 id="indexeddb-1">IndexedDB</h4>
<ul>
<li>A full client-side database for structured or large data.</li>
<li>Storage quota in gigabytes (10GB+ depending on disk space).</li>
<li>Asynchronous API, supports objects, files, and binary data.</li>
<li>Persistent data, survives reloads and restarts.</li>
<li>Best for: offline apps, large datasets, media storage (e.g., downloaded videos).</li>
</ul>
]]></content:encoded></item><item><title>Speed Up Your Website. Tips for Better Web Performance</title><link>https://blog.shatlykabdullayev.com/articles/tips-for-better-performance/</link><guid>https://blog.shatlykabdullayev.com/articles/tips-for-better-performance/</guid><pubDate>Fri, 18 Jul 2025 11:11:36 +0000</pubDate><description>Learn how to make your website faster with easy-to-understand tips on Core Web Vitals, lazy loading, code splitting and rendering strategies.</description><content:encoded><![CDATA[<h2 id="tips-for-better-web-experience"><a class="hash" href="#tips-for-better-web-experience" aria-label="Section anchor">#</a>Tips for Better Web Experience</h2>
<p>In this post, we’ll break down four key areas to improve your site’s speed: Core Web Vitals, lazy loading, code splitting, rendering strategies. Let’s dive in with simple explanations.</p>
<h3 id="core-web-vitals-metrics"><a class="hash" href="#core-web-vitals-metrics" aria-label="Subsection anchor">##</a>Core Web Vitals metrics</h3>
<p>Core Web Vitals are metrics that measure how fast a webpage loads, how quickly users can interact with it, and how visually stable it is. Optimizing these metrics will lead for better search rankings and a great user experience.</p>
<h3 id="largest-contentful-paint-lcp-how-fast-your-page-loads"><a class="hash" href="#largest-contentful-paint-lcp-how-fast-your-page-loads" aria-label="Subsection anchor">##</a>Largest Contentful Paint (LCP): How Fast Your Page Loads</h3>
<p>LCP measures how long it takes for the main content (like a big image or text block) to appear on the screen. A good LCP is under 1.2 seconds for desktop and 2.5 seconds for mobile.</p>
<h4 id="how-to-improve-lcp">How to Improve LCP</h4>
<ul>
<li>
<p><strong>Optimize images</strong>: Compress images to reduce file size. Tools like <a href="https://squoosh.app/?ref=blog.shatlykabdullayev.com" target="_blank" rel="noopener">Squoosh</a> can shrink images without losing quality.</p>
</li>
<li>
<p><strong>Use a fast server</strong>: Choose a reliable hosting provider with quick response times.</p>
</li>
<li>
<p><strong>Reduce server delays</strong>: Use a Content Delivery Network (CDN) to serve content from servers closer to your users.</p>
</li>
</ul>
<h3 id="cumulative-layout-shift-cls-keeping-your-page-stable"><a class="hash" href="#cumulative-layout-shift-cls-keeping-your-page-stable" aria-label="Subsection anchor">##</a>Cumulative Layout Shift (CLS): Keeping Your Page Stable</h3>
<p>CLS measures how much your page’s layout shifts unexpectedly, like when an image loads up and moves content. A good CLS score is under 0.1.</p>
<h3 id="first-input-delay-fid"><a class="hash" href="#first-input-delay-fid" aria-label="Subsection anchor">##</a>First Input Delay (FID)</h3>
<p>FID checks how long it takes for your site to respond when a user clicks a button or link. A good FID is under 100 milliseconds</p>
<h4 id="how-to-improve-cls-and-fid">How to Improve CLS and FID</h4>
<ul>
<li>
<p><strong>Set image sizes</strong>: Always define <code>width</code> and <code>height</code> for images so the browser reserves space for them.</p>
</li>
<li>
<p><strong>Avoid sudden content changes</strong>: Don’t insert ads or pop-ups that shift the page after it loads.</p>
</li>
<li>
<p><strong>Use <a href="https://javascript.info/event-delegation?ref=blog.shatlykabdullayev.com" target="_blank" rel="noopener">event delegation</a></strong>: Instead of adding event listeners to many elements, use a single listener on a parent element to handle interactions efficiently.</p>
</li>
</ul>
<h3 id="interaction-to-next-paint-inp-how-fast-your-site-responds-to-actions"><a class="hash" href="#interaction-to-next-paint-inp-how-fast-your-site-responds-to-actions" aria-label="Subsection anchor">##</a>Interaction to Next Paint (INP): How Fast Your Site Responds to Actions</h3>
<p>INP measures how quickly your site responds to user interactions, (clicking, tapping, typing). It looks at the time from when a user interacts to when the page visually updates. A good INP is under 200 milliseconds.</p>
<h4 id="how-to-improve-fid-and-inp">How to Improve FID and INP</h4>
<ul>
<li>
<p><strong>Minimize JavaScript</strong>: Remove unused scripts or break them into smaller pieces.</p>
</li>
<li>
<p><strong>Use browser optimizations</strong>: Techniques like <code>defer</code> or <code>async</code> (<a href="https://javascript.info/script-async-defer?ref=blog.shatlykabdullayev.com" target="_blank" rel="noopener">link</a>) for JavaScript files. Let the browser load them without blocking user actions.</p>
</li>
</ul>
<blockquote>
<p>Check out Google’s <a href="https://pagespeed.web.dev/?ref=blog.shatlykabdullayev.com" target="_blank" rel="noopener">PageSpeed Insights</a> to test your site’s Core Web Vitals</p>
</blockquote>
<h3 id="lazy-loading-and-code-splitting"><a class="hash" href="#lazy-loading-and-code-splitting" aria-label="Subsection anchor">##</a>Lazy Loading and Code Splitting</h3>
<p>Load only the content users need <strong>right away</strong>. Two great techniques for this are <strong>lazy loading</strong> and <strong>code splitting</strong>.</p>
<p><strong>Lazy loading</strong> delays loading images, videos, or other heavy content until they’re needed (like when a user scrolls down).</p>
<p><strong>Code splitting</strong> breaks your JavaScript into smaller pieces so the browser only loads what’s needed for the current page.</p>
<h4 id="how-to-implement">How to implement</h4>
<ul>
<li>
<p><strong>Use priority hints</strong>: Add <code>fetchpriority</code> attribute to tell the browser which resources to load first.</p>
</li>
<li>
<p><strong>HTML attribute</strong>: Add <code>loading=&quot;lazy&quot;</code> to images in your HTML. Most modern browsers support this.</p>
</li>
<li>
<p><strong>Dynamic imports</strong>: Use tools like Vite or Webpack to split code. For example, load a heavy charting library only when a user visits a data-heavy page. Frameworks like <code>React</code> or <code>Vue</code> have built-in code-splitting features.</p>
</li>
</ul>
<h3 id="rendering-strategies-picking-the-right-approach"><a class="hash" href="#rendering-strategies-picking-the-right-approach" aria-label="Subsection anchor">##</a>Rendering Strategies: Picking the Right Approach</h3>
<p>Loading contents right affects page speed. Here is common strategies, explained simply, with examples from real projects.</p>
<h4 id="client-side-rendering-csr">Client-Side Rendering (CSR)</h4>
<p>In CSR, the browser loads a basic page and uses JavaScript to fetch and display content (in client side). It’s great for <strong>dynamic apps</strong> but can be slow initially.</p>
<h4 id="server-side-rendering-ssr">Server-Side Rendering (SSR)</h4>
<p>SSR sends a fully built page from the server, making the first load faster. It’s good for SEO and speed but this can put a load on the servers.</p>
<h4 id="static-site-generation-ssg">Static Site Generation (SSG)</h4>
<p>SSG creates pre-built pages at build time, making them super fast to load. It’s perfect for blogs or marketing sites.</p>
<h4 id="incremental-static-regeneration-isr">Incremental Static Regeneration (ISR)</h4>
<p>ISR combines SSG’s speed with the ability to update pages without rebuilding the whole site. It’s great for sites with frequent updates.</p>
<h2 id="summary"><a class="hash" href="#summary" aria-label="Section anchor">#</a>Summary</h2>
<ul>
<li>
<p>Focus on Core Web Vitals (LCP, FID, CLS, INP) to make your site fast, responsive, and stable.</p>
</li>
<li>
<p>Use lazy loading, priority hints, and code splitting to load only what’s needed.</p>
</li>
<li>
<p>Pick the right rendering strategy (CSR, SSR, SSG, or ISR) for your project.</p>
</li>
</ul>
]]></content:encoded></item><item><title>Reusable Button component. Build Once, Use Everywhere.</title><link>https://blog.shatlykabdullayev.com/articles/reusable-jsx-button/</link><guid>https://blog.shatlykabdullayev.com/articles/reusable-jsx-button/</guid><pubDate>Fri, 04 Jul 2025 15:16:36 +0000</pubDate><description>The Power of Reusable Buttons. We will create reusable button component written in JSX</description><content:encoded><![CDATA[<h2 id="building-a-reusable-button-component-in-react"><a class="hash" href="#building-a-reusable-button-component-in-react" aria-label="Section anchor">#</a>Building a Reusable Button Component in React</h2>
<p>Creating a reusable button component in React is a fundamental task for any developer aiming to streamline UI development. A well-designed button component can be used across multiple projects, saving time and ensuring consistency.</p>
<p>In this blog, we'll build a flexible React button component that supports different variants, sizes, and element types (button or anchor). I'll explain the code, highlight its reusability, and provide ready to use code snippet.</p>
<h3 id="why-is-it-important"><a class="hash" href="#why-is-it-important" aria-label="Subsection anchor">##</a>Why is it important?</h3>
<p>Buttons are a core part of any user interface, appearing in forms, navigation bars, links, and more. A reusable button component allows developers to:</p>
<ul>
<li>
<p><strong>Reduce repetitive code</strong> by centralizing button logic.</p>
</li>
<li>
<p><strong>Maintain consistent styling</strong> across the application.</p>
</li>
<li>
<p><strong>Easily customize buttons</strong> with props for variants, sizes, and other functionality.</p>
</li>
<li>
<p><strong>Support</strong> both <code>&lt;button&gt;</code> and <code>&lt;a&gt;</code> elements for flexibility in navigation or actions.</p>
</li>
</ul>
<blockquote>
<p>We use Tailwind version 4</p>
</blockquote>
<h3 id="key-features--code-snippet"><a class="hash" href="#key-features--code-snippet" aria-label="Subsection anchor">##</a>Key Features + Code Snippet</h3>
<ul>
<li>
<p><strong>Variants</strong>: Easily switch between primary, secondary, outline, and link stylings.</p>
</li>
<li>
<p><strong>Sizes</strong>: Choose between large (lg) and medium (md) out of the box. Expand easily to support more.</p>
</li>
<li>
<p><strong>Polymorphic</strong>: Render as either a standard <code>&lt;button&gt;</code> for actions or an <code>&lt;a&gt;</code> for links, with proper external link handling.</p>
</li>
<li>
<p><strong>TypeScript Safety</strong>: All props are type-checked, and required fields (e.g., href for <code>&lt;a&gt;</code>) are enforced.</p>
</li>
<li>
<p><strong>Customizable</strong>: Add more variants, sizes, or class overrides as your design system evolves.</p>
</li>
</ul>
<h4 id="code-snippet">Code Snippet</h4>
<pre data-pagefind-weight="0.5"><code class="nohl">import type { ButtonHTMLAttributes, AnchorHTMLAttributes, ReactNode, FC } from &#34;react&#34;

import { cn } from &#34;@/shared/utils&#34;

const buttonVariants = {
  primary: &#34;text-gray-50 bg-cyan-700 hover:bg-cyan-800&#34;,
  secondary: &#34;text-gray-50 bg-blue-700 hover:bg-blue-800&#34;,
  outline: &#34;text-gray-50 border border-current hover:bg-gray-100 hover:text-gray-900&#34;,
  // learn more about tailwind groups: https://tailwindcss.com/docs/hover-focus-and-other-states#differentiating-nested-groups
  link: &#34;group/link text-gray-100 &#34;,
}

const buttonSizes = {
  lg: &#34;px-4 py-3 rounded-none text-base &#34;,
  md: &#34;px-3 py-2 rounded-none text-sm &#34;,
}

type CommonProps = {
  variant?: keyof typeof buttonVariants;
  size?: keyof typeof buttonSizes;
  classes?: string;
  children: ReactNode;
};

type ButtonProps = {
  element?: &#34;button&#34;;
} &amp; Omit&lt;ButtonHTMLAttributes&lt;HTMLButtonElement&gt;, &#34;className&#34;&gt; &amp; CommonProps;

type AnchorProps = {
  element: &#34;a&#34;;
  href: string;                // &lt;-- required when using &#39;a&#39;
  isExternal?: boolean;
} &amp; Omit&lt;AnchorHTMLAttributes&lt;HTMLAnchorElement&gt;, &#34;className&#34;&gt; &amp; CommonProps;

type Props = ButtonProps | AnchorProps;

const ContentWrapper = ({ children }: { children: ReactNode }) =&gt; (
  &lt;span className=&#34;relative inline-block group-hover/link:underline group-hover/link:underline-offset-4&#34;&gt;
    {children}
  &lt;/span&gt;
);

const Button: FC&lt;Props&gt; = ({ variant = &#34;primary&#34;, size = &#34;lg&#34;, classes, element, children, ...rest }) =&gt; {
  const className = cn(
    &#34;relative max-h-max leading-[0] inline-flex items-center font-semibold text-nowrap transition&#34;,
    buttonSizes[size],
    buttonVariants[variant],
    classes,
  )

  if (element === &#34;a&#34;) {
    const { isExternal, ...anchorProps } = rest as AnchorProps
    return (
      &lt;a
        {...anchorProps}
        className={className}
        target={isExternal ? &#34;_blank&#34; : undefined}
        rel={isExternal ? &#34;noopener noreferrer&#34; : undefined}
      &gt;
        &lt;ContentWrapper&gt;
          {children}
        &lt;/ContentWrapper&gt;
      &lt;/a&gt;
    )
  }

  // Default: button
  const buttonProps = rest as ButtonProps
  return (
    &lt;button {...buttonProps} type=&#34;button&#34; className={className}&gt;
      &lt;ContentWrapper&gt;
        {children}
      &lt;/ContentWrapper&gt;
    &lt;/button&gt;
  )
}

export default Button</code></pre><p><strong>Check out my <a href="https://www.youtube.com/watch?v=_-G7VTWqMfc&amp;t" target="_blank" rel="noopener">YouTube video</a> where I explain its functionality</strong></p>
<h3 id="code-explanation"><a class="hash" href="#code-explanation" aria-label="Subsection anchor">##</a>Code Explanation</h3>
<p>Let's break down the key parts of the code to understand how it achieves reusability and flexibility.</p>
<ul>
<li>
<p>The <code>buttonVariants</code> object defines three variants (you can add more): <code>primary</code>, <code>secondary</code>, and <code>tertiary</code>, each with specific classes. This object contains styles related to <code>colors</code>, <code>shadow</code>, <code>hover/focus</code> effects.</p>
</li>
<li>
<p>The <code>buttonSizes</code> object defines two sizes (you can add more): <code>lg</code>, <code>md</code>. It contains styles related to dimensions and spacing <code>font-size</code>, <code>height</code>, <code>width</code>, <code>padding</code>, <code>border-radius</code> etc.</p>
</li>
<li>
<p><strong>ContentWrapper</strong> is a helper component designed to wrap the visible content (children) inside reusable <code>Button</code>, providing consistent styling for hover underline effects—especially important for the link variant.</p>
</li>
</ul>
<h2 id="summary"><a class="hash" href="#summary" aria-label="Section anchor">#</a>Summary</h2>
<p>Here we build a truly reusable Button component using Tailwind. You only need to style once, and then reuse everywhere in your app. The code is type-safe, simple to drop in, and easy to extend when design needs change.</p>
]]></content:encoded></item><item><title>Debounce and Throttle. Step-by-Step Guide</title><link>https://blog.shatlykabdullayev.com/articles/debounce-and-throttle/</link><guid>https://blog.shatlykabdullayev.com/articles/debounce-and-throttle/</guid><pubDate>Sat, 07 Jun 2025 15:16:36 +0000</pubDate><description>Learn how debouncing and throttling work in JavaScript, with a detailed implementation and line-by-line explanation.</description><content:encoded><![CDATA[<h2 id="what-is-debouncing"><a class="hash" href="#what-is-debouncing" aria-label="Section anchor">#</a>What is Debouncing?</h2>
<p>Debouncing is a technique that ensures a function is only <strong>executed after a certain period of inactivity</strong>.</p>
<h3 id="debounce-implementation-snippet"><a class="hash" href="#debounce-implementation-snippet" aria-label="Subsection anchor">##</a>Debounce implementation (snippet)</h3>
<p>Let's implement our reusable debounce function.</p>
<div data-pagefind-weight="0.5"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kd">function</span> <span class="nx">debounce</span><span class="p">(</span><span class="nx">func</span><span class="p">,</span> <span class="nx">delay</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="kd">let</span> <span class="nx">timeoutId</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="kd">function</span> <span class="p">(...</span><span class="nx">args</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">clearTimeout</span><span class="p">(</span><span class="nx">timeoutId</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="nx">timeoutId</span> <span class="o">=</span> <span class="nx">setTimeout</span><span class="p">(()</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nx">func</span><span class="p">.</span><span class="nx">apply</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="nx">args</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span> <span class="nx">delay</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></div></div><h3 id="code-explanation"><a class="hash" href="#code-explanation" aria-label="Subsection anchor">##</a>Code Explanation</h3>
<ul>
<li>
<p>The <code>debounce()</code> function takes two parameters:</p>
<ul>
<li>
<p><code>func</code>: The function to debounce (e.g., a function that makes an API call or logs a message).</p>
</li>
<li>
<p><code>delay</code>: The delay (in milliseconds) to wait before executing <code>func</code>.</p>
</li>
</ul>
</li>
<li>
<p>Closure: The <code>timeoutId</code> variable is declared in the outer scope of debounce to persist across multiple calls to the returned function.</p>
<ul>
<li><code>timeoutId</code> stores the ID of the <code>setTimeout</code> timer, which can be used to <strong>cancel</strong> the timer if the debounced function is called again before the delay expires.</li>
</ul>
</li>
<li>
<p>The debounce function returns a new function that wraps <code>func</code> argument. This wrapper handles the debouncing logic.</p>
</li>
<li>
<p>The returned function uses the spread operator to capture any arguments passed to it. These arguments will be forwarded to <code>func</code> when it’s executed.</p>
</li>
<li>
<p>clearTimeout(timeoutId): If the debounced function is called multiple times within the <code>wait</code> period, the <code>clearTimeout()</code> function will be called to cancel upcoming execution, and the new <code>timeoutId</code> will be settled.</p>
</li>
<li>
<p>The <code>apply</code> method in a <code>debounced</code> function ensures that the <code>this</code> context inside the original function <code>func</code> matches the current context of the debounced function when it executes.</p>
</li>
</ul>
<h3 id="real-world-example"><a class="hash" href="#real-world-example" aria-label="Subsection anchor">##</a>Real-World example</h3>
<p>Imagine typing in a search bar on a website. As we type, the website might send API requests to fetch search results. Without debouncing, every keystroke could trigger a request, overwhelming the server. With debouncing, the request is sent only after we stop typing for, say, 300 milliseconds. This reduces the number of function calls and improves performance.</p>
<div className="h-[1px] w-full bg-neutral-300 dark:bg-neutral-700"></div>
<h2 id="what-is-throttling"><a class="hash" href="#what-is-throttling" aria-label="Section anchor">#</a>What is Throttling?</h2>
<p>Throttling is a powerful technique which <strong>limits</strong> how often a function can be called within a time frame. It’s like putting a speed limit on a function to prevent it from running too frequently, which is especially useful for optimizing web performance and ensuring smooth user experiences.</p>
<h3 id="how-throttling-works"><a class="hash" href="#how-throttling-works" aria-label="Subsection anchor">##</a>How Throttling Works</h3>
<p>Throttling works by wrapping a function with a mechanism that tracks the <strong>last time it was executed</strong>. If the function is called again before a specified delay has passed, the call is <strong>ignored</strong>. Once the delay expires, the function can run again</p>
<h3 id="throttle-implementation-snippet"><a class="hash" href="#throttle-implementation-snippet" aria-label="Subsection anchor">##</a>Throttle implementation (snippet)</h3>
<div data-pagefind-weight="0.5"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kd">function</span> <span class="nx">throttle</span><span class="p">(</span><span class="nx">func</span><span class="p">,</span> <span class="nx">delay</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="kd">let</span> <span class="nx">isThrottle</span> <span class="o">=</span> <span class="kc">false</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="kd">function</span> <span class="p">(...</span><span class="nx">args</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">isThrottle</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nx">func</span><span class="p">.</span><span class="nx">apply</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="nx">args</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">      <span class="nx">isThrottle</span> <span class="o">=</span> <span class="kc">true</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="nx">setTimeout</span><span class="p">(()</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nx">isThrottle</span> <span class="o">=</span> <span class="kc">false</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span> <span class="nx">delay</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></div></div><h3 id="code-explanation-1"><a class="hash" href="#code-explanation-1" aria-label="Subsection anchor">##</a>Code Explanation</h3>
<ul>
<li>
<p>The throttle function takes two parameters:</p>
<ul>
<li><code>func</code>: the function to be throttled.</li>
<li><code>delay</code>: The minimum time (in milliseconds) that <strong>must pass</strong> before <code>func</code> can be called again.</li>
</ul>
</li>
<li>
<p>It returns a new function that controls the execution of <code>func</code>.</p>
</li>
<li>
<p>isThrottle: A <code>boolean</code> flag that tracks whether it’s in a &quot;cooldown&quot; period where further calls are ignored</p>
</li>
<li>
<p>The returned function uses the rest parameter (...args) to accept any number of arguments, which will be passed to <code>func</code>.</p>
<ul>
<li>
<p>It checks if <code>isThrottle</code> is false, and if so, it calls <code>func.apply(this, args)</code> to execute the original function with the provided arguments.</p>
</li>
<li>
<p>Sets <code>isThrottle = true</code> to indicate that the function is now throttled.</p>
</li>
</ul>
</li>
<li>
<p>Then, it sets a <code>setTimeout</code> that resets <code>isThrottle</code> to <code>false</code> after the specified <code>delay</code>. This allows the function to be called again once the <code>delay</code> period is over.</p>
</li>
</ul>
<h3 id="real-world-example-1"><a class="hash" href="#real-world-example-1" aria-label="Subsection anchor">##</a>Real-World Example</h3>
<p>Imagine a webpage that fetches data from an API every time a user scrolls. Without throttling, scrolling could trigger hundreds of API requests in seconds, overloading the server and slowing down the site. By applying throttling, you can limit the function to execute, say, once every second, significantly reducing server load and improving performance.</p>
<h2 id="summary"><a class="hash" href="#summary" aria-label="Section anchor">#</a>Summary</h2>
<ul>
<li>
<p><strong>Debouncing</strong>: Ensures a function executes only after a period of inactivity, reducing unnecessary calls.</p>
</li>
<li>
<p><strong>Throttling</strong>: Limits how often a function runs within a time frame, ensuring controlled execution.</p>
</li>
<li>
<p><strong>Key Difference</strong>: Debouncing waits for a pause; throttling ensures a fixed rate of execution.</p>
</li>
<li>
<p><strong>Use Cases</strong>: Debouncing for search inputs or form validation; throttling for scroll or resize events.</p>
</li>
</ul>
<p>Both optimize performance by reducing function calls, enhancing user experience and server efficiency.</p>
]]></content:encoded></item><item><title>Web Design Rules and Guidelines</title><link>https://blog.shatlykabdullayev.com/articles/web-design-rules-and-guidelines/</link><guid>https://blog.shatlykabdullayev.com/articles/web-design-rules-and-guidelines/</guid><pubDate>Thu, 29 May 2025 12:29:44 +0000</pubDate><description>Mastering Web Design in 2025. Essential Rules and Guidelines for Creating Stunning, User-Centric Websites</description><content:encoded><![CDATA[<p><a href="https://www.businessdasher.com/statistics-about-website/?ref=blog.shatlykabdullayev.com#:~:text=94%25%20of%20first%20impressions%20are%20based%20on%20website%20design." target="_blank" rel="noopener">94% of users judge a website by its design</a>. With short attention spans, good visuals are key to engaging visitors and boosting conversions. As web design changes fast with AI, mobile focus, and new tech, I'll share simple tips to create responsive, unique websites. Whether a simple portfolio or bold online store, these ideas will help you combine looks and function for better user experience.</p>
<p>Take <a href="https://www.apple.com/?ref=blog.shatlykabdullayev.com" target="_blank" rel="noopener">Apple's website</a>—its elegant personality shines through with high-quality product images and minimalist typography, leading to a 30% higher conversion rate compared to cluttered competitors like early <strong>eBay</strong> designs.</p>
<h2 id="website-personalities"><a class="hash" href="#website-personalities" aria-label="Section anchor">#</a>Website Personalities</h2>
<p>Every website has a personality that matches its brand—serious and elegant for luxury brands, or playful and fun for creative startups. Matching design elements to these traits creates memorable, emotional experiences for users. This section covers the seven main personalities and how they guide choices in typography, colors, and more.</p>
<ul>
<li><strong>Elegant Personality:</strong> Ideal for high-end services; use thin <strong>serif</strong> fonts, pastel/golden palettes, and hero images of refined lifestyles.</li>
<li><strong>Minimalist:</strong> Focus on content clarity with sans-serif blacks, sparse icons, and ample whitespace for readability.</li>
<li><strong>Bold:</strong> Command attention via oversized bold type, vibrant blocks, and dynamic layouts for impact-driven sites.</li>
<li><strong>Startup:</strong> Energetic vibe through medium sans-serifs, light grays, and rounded elements to convey innovation.</li>
<li><strong>Calm:</strong> Evoke trust with soft pastels, rounded serifs, and soothing illustrations for wellness or care-focused brands.</li>
<li><strong>Neutral:</strong> Corporate staple with structured grids, neutral fonts, and subtle accents to prioritize information over flair.</li>
<li><strong>Playful:</strong> Infuse joy with colorful rounds, hand-drawn assets, and subtle animations for engaging, youthful audiences.</li>
</ul>
<h3 id="typography"><a class="hash" href="#typography" aria-label="Subsection anchor">##</a>Typography</h3>
<p>Typography isn't just about fonts—it's the voice of your site. Limiting choices and scaling sizes strategically ensures hierarchy and accessibility, aligning with 2025's trend toward bold, experimental typefaces that enhance mobile scrolling experiences.</p>
<ul>
<li>Use popular, safe fonts from <a href="https://fonts.google.com/?ref=blog.shatlykabdullayev.com" target="_blank" rel="noopener">Google Fonts</a>, limiting with 1 or 2 <code>font-family</code> that fit the personality.</li>
<li>Apply a type scale: <strong>body text</strong> <code>16-32px</code>, bold <strong>headlines</strong> <code>50px</code> or larger for consistency.</li>
<li>Use <code>20px</code> or more for long text; keep line length <strong>under 75</strong> characters and line height <code>1.5</code> to <code>2</code>.</li>
<li>Try more <code>letter-spacing</code> for short titles; avoid justifying or centering long paragraphs.</li>
<li>Keep font weight <code>400</code> or higher; reduce letter spacing in headlines for smooth reading.</li>
</ul>
<p><strong>Example:</strong> <a href="https://www.nytimes.com/?ref=blog.shatlykabdullayev.com" target="_blank" rel="noopener">The New York Times</a> blog uses a consistent <code>20px</code> body font with generous <code>line height</code>, making long articles scannable and reducing bounce rates by 15%.</p>
<h3 id="color"><a class="hash" href="#color" aria-label="Subsection anchor">##</a>Color</h3>
<p>Colors affect feelings and guide attention. Choose them to match your brand and keep accessibility in mind. In 2025, bold contrasts and AI-made palettes are popular for vibrant, inclusive designs that can boost engagement by up to 20%.</p>
<ul>
<li>Pick main colors that fit your brand (e.g., pastels for calm) and balance with grays; use tools like <a href="https://coolors.co/?ref=blog.shatlykabdullayev.com" target="_blank" rel="noopener">Coolors</a> for accents.</li>
<li>Make tints and shades for flexibility; main colors go on CTAs, accents highlight details.</li>
<li>Use lighter text on dark backgrounds, without pure black or white extremes.</li>
<li>Blend colors in images for unity; test how they affect emotions.</li>
</ul>
<p><strong>Example:</strong> <a href="https://open.spotify.com/?ref=blog.shatlykabdullayev.com" target="_blank" rel="noopener">Spotify</a> uses bright greens and blacks to increase playlist clicks by 18%.</p>
<h3 id="images-illustrations-and-icons"><a class="hash" href="#images-illustrations-and-icons" aria-label="Subsection anchor">##</a>Images, Illustrations, and Icons</h3>
<p>Good visuals support your message without slowing the site. Crop, compress, and combine assets wisely. Trends like 3D illustrations and AI-upscaled images create immersive experiences in 2025.</p>
<ul>
<li>Choose relevant, original images; show real people to build connection; use gradients or boxes for text overlays; upload double-size compressed files.</li>
<li>Use <strong>one SVG icon set</strong>; match icon roundness to fonts; use with text labels for features or bullet points; color icons to match or accent.</li>
<li>Use scalable, <a href="/articles/image-optimization/">fast-loading visuals</a>.</li>
</ul>
<p><strong>Example:</strong> <a href="https://en.duolingo.com/?ref=blog.shatlykabdullayev.com" target="_blank" rel="noopener">Duolingo’s</a> hand-drawn owl icons and compressed images keep mobile load times under 2 seconds.</p>
<h3 id="shadows-border-radius"><a class="hash" href="#shadows-border-radius" aria-label="Subsection anchor">##</a>Shadows, Border-Radius</h3>
<p>Subtle shadows and rounded corners soften look.</p>
<p>2025 highlights micro-interactions with hover effects for a tactile feel.</p>
<ul>
<li>Use light shadows sparingly for subtle lift; bigger shadows for emphasis; animate on hover.</li>
<li>Match border-radius to font style for playful buttons and images.</li>
</ul>
<p><strong>Example:</strong> <a href="https://www.notion.com/?ref=blog.shatlykabdullayev.com" target="_blank" rel="noopener">Notion</a> uses soft shadows and <code>8px</code> border-radius on cards for a calm interface.</p>
<h3 id="visual-hierarchy-and-ux"><a class="hash" href="#visual-hierarchy-and-ux" aria-label="Subsection anchor">##</a>Visual Hierarchy and UX</h3>
<p>Hierarchy directs attention; UX makes navigation easy. Site speed affects rankings. Slow sites lose conversions (~7% per second delay).</p>
<ul>
<li>Place important items top and emphasize with <code>size</code>, <code>color</code>, <code>weight</code>, and <code>space</code>.</li>
<li>Highlight areas like testimonials with <code>backgrounds</code> or <code>shadows</code>.</li>
<li>Use familiar patterns, clear headlines, quick animations (200–500ms), and aligned forms with feedback.</li>
<li>Break text with subheadings and images; use simple language; place actions <strong>where users expect them</strong>.</li>
<li>Track UX: Monitor bounce rates and loading times</li>
</ul>
<p><strong>Example:</strong> <a href="https://www.amazon.com/?ref=blog.shatlykabdullayev.com" target="_blank" rel="noopener">Amazon’s</a> bold “Add to Cart” buttons increase impulse buys by 12%.</p>
<h3 id="components-layouts-and-content-strategies"><a class="hash" href="#components-layouts-and-content-strategies" aria-label="Subsection anchor">##</a>Components, Layouts, and Content Strategies</h3>
<p>Combine standard components like <code>cards</code> and <code>grids</code> into tested layouts for efficiency</p>
<ul>
<li>Use common elements in patterns like hero or features.</li>
<li>Optimize content marketing—add SEO-friendly alt text and create downloadable checklists for backlinks.</li>
<li>Keyword Research: Use AI to find phrases (e.g., “responsive web design tips”) to include in alt text and headings.</li>
</ul>
<p><strong>Example:</strong> <a href="https://www.hubspot.com/?ref=blog.shatlykabdullayev.com" target="_blank" rel="noopener">HubSpot</a> doubles leads using grid layouts with animations guiding users through funnels.</p>
<h2 id="conclusion-master-design-trends-and-performances"><a class="hash" href="#conclusion-master-design-trends-and-performances" aria-label="Section anchor">#</a>Conclusion: Master Design Trends and Performances</h2>
<p>In 2025, web design changes fast. Using colors that fit your brand, focusing on user experience, and using AI tools helps make websites that attract and keep visitors. Test your pages, design for mobile first, and keep checking to get better.</p>
]]></content:encoded></item><item><title>Creating Gradients with Transitions</title><link>https://blog.shatlykabdullayev.com/articles/gradient-transitions/</link><guid>https://blog.shatlykabdullayev.com/articles/gradient-transitions/</guid><pubDate>Wed, 14 May 2025 15:16:36 +0000</pubDate><description>Creating Smooth Gradient Transitions on :hover using CSS @property rule</description><content:encoded><![CDATA[<h2 id="gradient-transitions-with-css-property-rule"><a class="hash" href="#gradient-transitions-with-css-property-rule" aria-label="Section anchor">#</a>Gradient Transitions with CSS <code>@property</code> Rule</h2>
<p>Gradients are a powerful way to add visual flair to web elements, but transitioning them smoothly has always been tricky. CSS gradients are treated as images, so direct transitions between gradient states often result in abrupt changes rather than smooth animations.</p>
<p>Enter the CSS <code>@property</code> rule—a game-changer that lets us define custom, animatable properties to achieve gradient transitions.</p>
<p>In this blog, we’ll explore how to use <code>@property</code> to animate gradient colors on a button, complete with a real-world example.</p>
<p><video
className="w-full"
src="/static/videos/gradient-buttons.mp4"
muted
autoPlay
playsInline
controls
/></p>
<p>Let’s create a simple webpage with two buttons: one using a standard gradient transition (which won’t work as expected) and another using the <code>@property</code> rule for a smooth transition.</p>
<div data-pagefind-weight="0.5"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;box&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">h2</span><span class="p">&gt;</span>Changing background gradient styles on hover<span class="p">&lt;/</span><span class="nt">h2</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">button</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;btn btn-1&#34;</span><span class="p">&gt;</span>Hover Me<span class="p">&lt;/</span><span class="nt">button</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;box&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">h2</span><span class="p">&gt;</span>Changing @property rule on hover<span class="p">&lt;/</span><span class="nt">h2</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">button</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;btn btn-2&#34;</span><span class="p">&gt;</span>Hover Me<span class="p">&lt;/</span><span class="nt">button</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span></span></span></code></pre></div></div><h3 id="styling-the-buttons"><a class="hash" href="#styling-the-buttons" aria-label="Subsection anchor">##</a>Styling the Buttons</h3>
<p>Next, we style the buttons with a shared gradient background and define their hover behaviors in 2 different ways:</p>
<div data-pagefind-weight="0.5"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-css" data-lang="css"><span class="line"><span class="cl"><span class="p">@</span><span class="k">property</span> <span class="nt">--color-primary-one</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">syntax</span><span class="o">:</span> <span class="s1">&#39;&lt;color&gt;&#39;</span><span class="o">;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">inherits</span><span class="o">:</span> <span class="nt">false</span><span class="o">;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">initial-value</span><span class="o">:</span> <span class="p">#</span><span class="nn">ff3d3e</span><span class="o">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">@</span><span class="k">property</span> <span class="nt">--color-primary-two</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">syntax</span><span class="o">:</span> <span class="s1">&#39;&lt;color&gt;&#39;</span><span class="o">;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">inherits</span><span class="o">:</span> <span class="nt">false</span><span class="o">;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">initial-value</span><span class="o">:</span> <span class="p">#</span><span class="nn">ff6f00</span><span class="o">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c">/* common styles with initial gradient color */</span>
</span></span><span class="line"><span class="cl"><span class="p">.</span><span class="nc">btn</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">padding</span><span class="p">:</span> <span class="mi">15</span><span class="kt">px</span> <span class="mi">30</span><span class="kt">px</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="k">color</span><span class="p">:</span> <span class="mh">#ffffff</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="k">border-radius</span><span class="p">:</span> <span class="mi">5</span><span class="kt">px</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="k">background</span><span class="p">:</span> <span class="nb">linear-gradient</span><span class="p">(</span><span class="kc">to</span> <span class="kc">right</span><span class="p">,</span> <span class="nf">var</span><span class="p">(</span><span class="o">--</span><span class="kc">color</span><span class="o">-</span><span class="n">primary</span><span class="o">-</span><span class="n">one</span><span class="p">)</span> <span class="mi">0</span><span class="kt">%</span><span class="p">,</span> <span class="nf">var</span><span class="p">(</span><span class="o">--</span><span class="kc">color</span><span class="o">-</span><span class="n">primary</span><span class="o">-</span><span class="n">two</span><span class="p">)</span> <span class="mi">100</span><span class="kt">%</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="k">cursor</span><span class="p">:</span> <span class="kc">pointer</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">.</span><span class="nc">btn-1</span><span class="p">:</span><span class="nd">hover</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="c">/* this will not work as expected */</span>
</span></span><span class="line"><span class="cl">  <span class="k">background</span><span class="p">:</span> <span class="nb">linear-gradient</span><span class="p">(</span><span class="kc">to</span> <span class="kc">right</span><span class="p">,</span> <span class="mh">#d63e76</span> <span class="mi">0</span><span class="kt">%</span><span class="p">,</span> <span class="mh">#b90041</span> <span class="mi">100</span><span class="kt">%</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="k">transition</span><span class="p">:</span> <span class="kc">all</span> <span class="mf">0.3</span><span class="kt">s</span> <span class="kc">ease-in-out</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">.</span><span class="nc">btn-2</span><span class="p">:</span><span class="nd">hover</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="c">/* this will work */</span>
</span></span><span class="line"><span class="cl">  <span class="k">transition</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="o">--</span><span class="kc">color</span><span class="o">-</span><span class="n">primary-one</span> <span class="mf">0.3</span><span class="kt">s</span> <span class="kc">ease-in-out</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="o">--</span><span class="kc">color</span><span class="o">-</span><span class="n">primary-two</span> <span class="mf">0.3</span><span class="kt">s</span> <span class="kc">ease-in-out</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="nv">--color-primary-one</span><span class="p">:</span> <span class="mh">#d63e76</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="nv">--color-primary-two</span><span class="p">:</span> <span class="mh">#b90041</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></div></div><ul>
<li>
<p>Base <code>.btn</code> class: Applies a gradient background using the custom variables <code>--color-primary-one</code> and <code>--color-primary-two</code>.</p>
</li>
<li>
<p><code>.btn-1:hover:</code> Attempts to transition the entire background property to a new gradient. This <strong>won’t animate</strong> smoothly because gradients are <strong>treated as images</strong>.</p>
</li>
<li>
<p><code>.btn-2:hover:</code> Transitions the custom variables <code>--color-primary-one</code> and <code>--color-primary-two</code> to new color values. Since these are animatable color properties, the gradient updates smoothly.</p>
</li>
</ul>
<blockquote>
<p>The <code>@property</code> rule is supported in modern browsers like Chrome, Edge, and Safari. <br /> <br /> Visit <a href="https://caniuse.com/?search=%40property" target="_blank" rel="noopener">CanIUse</a> to check compatibility
details for all features.</p>
</blockquote>
<h2 id="summary"><a class="hash" href="#summary" aria-label="Section anchor">#</a>Summary</h2>
<p>Using the <code>@property</code> rule, you can create stunning gradient transitions that elevate your web designs. Try it out and make your buttons pop!</p>
]]></content:encoded></item><item><title>JavaScript Fundamentals for Frontend Development</title><link>https://blog.shatlykabdullayev.com/articles/javascript-fundamentals-for-frontend-development/</link><guid>https://blog.shatlykabdullayev.com/articles/javascript-fundamentals-for-frontend-development/</guid><pubDate>Sat, 03 May 2025 15:16:36 +0000</pubDate><description>A practical introduction to the JavaScript fundamentals every frontend developer should understand.</description><content:encoded><![CDATA[<p>Javascript uses concepts that can feel confusing. Let’s break down some of the most essential ideas.</p>
<h3 id="type-coercion"><a class="hash" href="#type-coercion" aria-label="Subsection anchor">##</a>Type Coercion</h3>
<p><strong>Coercion</strong> - is when JavaScript automatically changes one type to another during operations—like mixing apples and oranges, but the code tries to make them work together. It can be helpful but sneaky, leading to surprises if you're not careful.</p>
<div data-pagefind-weight="0.5"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kd">let</span> <span class="nx">result</span> <span class="o">=</span> <span class="s1">&#39;Price: &#39;</span> <span class="o">+</span> <span class="mi">100</span> <span class="c1">// Number 100 becomes a string, output: &#34;Price: 100&#34;
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">let</span> <span class="nx">sum</span> <span class="o">=</span> <span class="s1">&#39;5&#39;</span> <span class="o">-</span> <span class="mi">2</span> <span class="c1">// String &#34;5&#34; becomes a number, output: 3
</span></span></span></code></pre></div></div><blockquote>
<p>But: &quot;5&quot; + 2 gives &quot;52,&quot; not 7. Learn more about it <a href="https://javascript.info/type-conversions" target="_blank" rel="noopener">here</a></p>
</blockquote>
<h3 id="scope"><a class="hash" href="#scope" aria-label="Subsection anchor">##</a>Scope</h3>
<p>Scope is like a fence around your variables—it decides where they can be seen and used in your code. Without it, everything would be chaotic. There are <strong>three</strong> types of scope: global scope (available anywhere in the code - <code>window</code> object), function scope (inside a function only), and block scope (inside curly braces {} like in <code>if</code> statements, using <code>let</code> or <code>const</code>). This keeps your code organized and secure.</p>
<div data-pagefind-weight="0.5"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kd">function</span> <span class="nx">calculateTax</span><span class="p">(</span><span class="nx">price</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="kd">let</span> <span class="nx">tax</span> <span class="o">=</span> <span class="nx">price</span> <span class="o">*</span> <span class="mf">0.1</span> <span class="c1">// This &#39;tax&#39; is visible only inside this function
</span></span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="nx">tax</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">tax</span><span class="p">)</span> <span class="c1">// Error! Can&#39;t see &#39;tax&#39; out here—it&#39;s scoped to the function
</span></span></span></code></pre></div></div><h3 id="closures"><a class="hash" href="#closures" aria-label="Subsection anchor">##</a>Closures</h3>
<p>A closure is like a backpack 🎒 that a <strong>function carries</strong>, holding onto variables from its &quot;home&quot; (outer function) even after the home is gone. It's great for keeping data private, like a secret pocket.</p>
<div data-pagefind-weight="0.5"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kd">function</span> <span class="nx">makeCounter</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="kd">let</span> <span class="nx">count</span> <span class="o">=</span> <span class="mi">0</span> <span class="c1">// The &#39;secret&#39; in the backpack 🎒
</span></span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="c1">// Inner function with access to count
</span></span></span><span class="line"><span class="cl">    <span class="nx">count</span><span class="o">++</span> <span class="c1">// Changes the outer variable
</span></span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="nx">count</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="kd">let</span> <span class="nx">counter</span> <span class="o">=</span> <span class="nx">makeCounter</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">counter</span><span class="p">())</span> <span class="c1">// 1
</span></span></span><span class="line"><span class="cl"><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">counter</span><span class="p">())</span> <span class="c1">// 2  (Remembers the last count!)
</span></span></span></code></pre></div></div><h3 id="this-keyword"><a class="hash" href="#this-keyword" aria-label="Subsection anchor">##</a><code>this</code> keyword</h3>
<p><code>this</code> is like a pointer saying, &quot;Me!&quot;—it refers to the object that's currently running the code. It changes depending on how you call the function, which can be tricky at first, like a chameleon.</p>
<p><strong>Example</strong>: In an object, <code>this</code> means the object itself.</p>
<p>The value of <code>this</code> depends on how the function is called.</p>
<ul>
<li>If this is used in the global object, the value of this is <code>window</code> object (but if strict mode is used, the value is undefined).</li>
<li>In most cases, the value of <code>this</code> is the object to <strong>the left of the dot</strong> (the left rule of <code>this</code>).</li>
<li>If a function is an arrow function, it ignores all the above rules and obtains the value of <code>this</code> from the lexical environment during its creation.</li>
<li>If <code>call</code>, <code>apply</code>, or <code>bind</code> are used to create or call a function, <code>this</code> inside the function is the object passed as an argument.</li>
</ul>
<p><strong>Example 1</strong></p>
<div data-pagefind-weight="0.5"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kd">let</span> <span class="nx">User</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;Alice&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nx">greet</span><span class="o">:</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">&#39;Hello, &#39;</span> <span class="o">+</span> <span class="k">this</span><span class="p">.</span><span class="nx">name</span><span class="p">)</span> <span class="c1">// &#39;this&#39; is User object
</span></span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="nx">User</span><span class="p">.</span><span class="nx">greet</span><span class="p">()</span> <span class="c1">// &#34;Hello, Alice&#34;
</span></span></span></code></pre></div></div><p><strong>Example 2</strong></p>
<div data-pagefind-weight="0.5"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">Person1</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;Alice&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nx">greet</span><span class="o">:</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">&#39;Hello, &#39;</span> <span class="o">+</span> <span class="k">this</span><span class="p">.</span><span class="nx">name</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">Person2</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;Bob&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// change the context of `this` by binding the Person2 object
</span></span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">greetPerson2</span> <span class="o">=</span> <span class="nx">Person1</span><span class="p">.</span><span class="nx">greet</span><span class="p">.</span><span class="nx">bind</span><span class="p">(</span><span class="nx">Person2</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nx">greetPerson2</span><span class="p">()</span> <span class="c1">// Output: Hello, Bob
</span></span></span></code></pre></div></div><p><strong>Explanation:</strong></p>
<ul>
<li><code>Person1</code> has a method <code>greet</code> that uses <code>this.name</code>.</li>
<li><code>bind(Person2)</code> <strong>creates a new function</strong> <code>greetPerson2</code> where <code>this</code> is permanently set to Person2.</li>
<li>Calling <code>greetPerson2()</code> uses <code>Person2</code>'s context, printing &quot;Hello, Bob&quot;.</li>
</ul>
<h3 id="object-oriented-programming-in-javascript"><a class="hash" href="#object-oriented-programming-in-javascript" aria-label="Subsection anchor">##</a>Object-Oriented Programming in JavaScript</h3>
<p>OOP is like building with Lego blocks: you create blueprints - <strong>classes or prototypes</strong> for objects that can inherit traits, making code reusable. It's for organizing bigger projects.</p>
<h4 id="prototypes">Prototypes</h4>
<p>Prototypes are like family trees—objects inherit methods (actions) from a parent prototype, saving space by sharing.</p>
<div data-pagefind-weight="0.5"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kd">function</span> <span class="nx">Person</span><span class="p">(</span><span class="nx">name</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">this</span><span class="p">.</span><span class="nx">name</span> <span class="o">=</span> <span class="nx">name</span> <span class="c1">// Unique to each person
</span></span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="nx">Person</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">greet</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="c1">// Shared action
</span></span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="s1">&#39;Hi, &#39;</span> <span class="o">+</span> <span class="k">this</span><span class="p">.</span><span class="nx">name</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="kd">let</span> <span class="nx">Nick</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Person</span><span class="p">(</span><span class="s1">&#39;Nick&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">Nick</span><span class="p">.</span><span class="nx">greet</span><span class="p">())</span> <span class="c1">// &#34;Hi, Nick&#34;
</span></span></span></code></pre></div></div><h3 id="arrow-functions-vs-normal-functions"><a class="hash" href="#arrow-functions-vs-normal-functions" aria-label="Subsection anchor">##</a>Arrow Functions vs Normal Functions</h3>
<p>Arrow functions are shorthand versions of normal functions, like quick notes vs full letters. The big difference: arrows <strong>don't have their own</strong> <code>this</code> — they borrow from surroundings, which is handy in some spots but not others.</p>
<div data-pagefind-weight="0.5"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kd">let</span> <span class="nx">obj</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">value</span><span class="o">:</span> <span class="mi">10</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nx">normal</span><span class="o">:</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">setTimeout</span><span class="p">(</span><span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">value</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span> <span class="mi">100</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="nx">arrow</span><span class="o">:</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">setTimeout</span><span class="p">(()</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">value</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span> <span class="mi">100</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">obj</span><span class="p">.</span><span class="nx">normal</span><span class="p">())</span> <span class="c1">// Undefined — wrong &#39;this&#39; context
</span></span></span><span class="line"><span class="cl"><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">obj</span><span class="p">.</span><span class="nx">arrow</span><span class="p">())</span> <span class="c1">// 10—borrows obj&#39;s &#39;this&#39;
</span></span></span></code></pre></div></div><h3 id="promises"><a class="hash" href="#promises" aria-label="Subsection anchor">##</a>Promises</h3>
<p>Promises are like &quot;I Owe You&quot; for code that takes time (async) — they promise a result later, either success (resolve) or fail (reject). Chain them with <code>.then()</code> for the next steps.</p>
<div data-pagefind-weight="0.5"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kd">let</span> <span class="nx">promise</span> <span class="o">=</span> <span class="k">new</span> <span class="nb">Promise</span><span class="p">((</span><span class="nx">resolve</span><span class="p">,</span> <span class="nx">reject</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">&#39;thinking...&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="nx">setTimeout</span><span class="p">(()</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="nx">resolve</span><span class="p">(</span><span class="s1">&#39;Done!&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span> <span class="mi">2000</span><span class="p">)</span> <span class="c1">// Wait 2 seconds
</span></span></span><span class="line"><span class="cl"><span class="p">})</span>
</span></span><span class="line"><span class="cl"><span class="nx">promise</span><span class="p">.</span><span class="nx">then</span><span class="p">((</span><span class="nx">result</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">result</span><span class="p">))</span> <span class="c1">// &#34;Done!&#34;
</span></span></span></code></pre></div></div><h2 id="summary"><a class="hash" href="#summary" aria-label="Section anchor">#</a>Summary</h2>
<ul>
<li>Scope: Fences variables; global everywhere, function/local hidden; prevents messes.</li>
<li>Closures: Functions remember outer stuff; like private backpacks; useful for states.</li>
<li><code>this</code> Keyword: Points to current object; changes with call; watch in events.</li>
<li>OOP: Blueprints with prototypes/classes; inherit to reuse; methods are actions.</li>
<li>Arrow vs Normal: Arrows short, share <code>this</code>; good for quick anon funcs.</li>
<li>Promises: Handle waits; resolve/reject; chain for steps.</li>
</ul>
]]></content:encoded></item><item><title>Fundamental Introduction to Web Development</title><link>https://blog.shatlykabdullayev.com/articles/fundamental-introduction-to-web-development/</link><guid>https://blog.shatlykabdullayev.com/articles/fundamental-introduction-to-web-development/</guid><pubDate>Wed, 09 Apr 2025 15:16:36 +0000</pubDate><description>Understanding how a browser works is essential. This guide focuses primarily on browser-based development</description><content:encoded><![CDATA[<h2 id="networking-fundamentals"><a class="hash" href="#networking-fundamentals" aria-label="Section anchor">#</a>Networking Fundamentals</h2>
<h3 id="internet"><a class="hash" href="#internet" aria-label="Subsection anchor">##</a>Internet</h3>
<p>The <strong>Internet</strong> is a global network of computers used to exchange data.<br>
It provides access to information, services, and communication across the world.</p>
<h3 id="server"><a class="hash" href="#server" aria-label="Subsection anchor">##</a>Server</h3>
<p>A <strong>server</strong> is a machine that provides services to other programs or devices, known as <strong>clients</strong>.<br>
Its role is to share data, resources, and distribute workloads.</p>
<p><strong>Types of servers:</strong></p>
<ul>
<li>Web servers</li>
<li>Database servers</li>
<li>DNS servers</li>
</ul>
<h3 id="web-server"><a class="hash" href="#web-server" aria-label="Subsection anchor">##</a>Web Server</h3>
<p>A <strong>web server</strong> accepts HTTP requests from clients (browsers) and sends back HTTP responses containing HTML pages, images, files, and other resources.</p>
<h3 id="domain--ip-address"><a class="hash" href="#domain--ip-address" aria-label="Subsection anchor">##</a>Domain &amp; IP Address</h3>
<p>A <strong>domain</strong> is a memorable, human-friendly address used to access websites. Without domains, you’d have to remember complex IP addresses.</p>
<p>An <strong>IP address</strong> is a unique numerical identifier assigned to every device connected to the internet.<br>
It works like a postal address, helping devices find each other and exchange information.</p>
<blockquote>
<p>IP addresses are organized hierarchically (country → region → device) to optimize routing speed.</p>
</blockquote>
<h3 id="dns--dns-lookup"><a class="hash" href="#dns--dns-lookup" aria-label="Subsection anchor">##</a>DNS &amp; DNS Lookup</h3>
<p><strong>DNS</strong> (Domain Name System) — acts like the internet’s phonebook, translating domain names into IP addresses.</p>
<p>For example, using the IP <a href="http://142.250.190.78/" target="_blank" rel="noopener">142.250.190.78</a> or the domain <a href="https://google.com" target="_blank" rel="noopener">google.com</a> will take you to the same website — Google’s homepage.</p>
<p><strong>DNS lookup</strong> is the process of finding the IP address of a server using its domain name (e.g., <code>example.com</code> → <code>93.184.216.34</code>).</p>
<p><img src="/static/google-ip.png" alt="Google IP address example" loading="lazy" decoding="async"></p>
<h5 id="how-it-works">How it works</h5>
<ol>
<li><strong>DNS Request:</strong> The browser sends a request to a DNS server to get the IP address of the domain.</li>
<li><strong>Caching:</strong> Once fetched, the IP address is stored in the browser’s cache to speed up future visits.</li>
<li><strong>Multiple Hosts:</strong> If a webpage loads resources from multiple domains (e.g., fonts, images, or scripts), the browser performs a DNS lookup for each domain.</li>
</ol>
<p><strong>Real-world example:</strong><br>
If your webpage loads Google Fonts, the browser will perform a DNS lookup not only for your site’s domain but also for <code>fonts.googleapis.com</code>.</p>
<h3 id="cdn--content-delivery-network"><a class="hash" href="#cdn--content-delivery-network" aria-label="Subsection anchor">##</a>CDN — Content Delivery Network</h3>
<p>A CDN is a network of servers distributed globally that stores copies of website content (pages, images, videos) and delivers them from the closest server to the user.</p>
<p><strong>Benefits:</strong></p>
<ul>
<li>Faster load times</li>
<li>Reduced server load</li>
<li>Better reliability</li>
</ul>
<p><strong>Real-world example:</strong><br>
Netflix uses CDNs to stream video from a nearby server, so you don’t have to wait for data to travel halfway across the world.</p>
<h2 id="browser--introduction"><a class="hash" href="#browser--introduction" aria-label="Section anchor">#</a>Browser — Introduction</h2>
<p>A browser is software that allows a user to access information on the internet via the <a href="https://en.wikipedia.org/wiki/World_Wide_Web" target="_blank" rel="noopener">World Wide Web</a>.</p>
<p>In modern web development, knowing how browsers operate can make your websites faster, more accessible, and more reliable.</p>
<h3 id="how-the-browser-loads-a-web-page"><a class="hash" href="#how-the-browser-loads-a-web-page" aria-label="Subsection anchor">##</a>How the Browser Loads a Web Page</h3>
<p>Navigation is the first step in loading a web page.</p>
<p><img src="/static/browser-navigation.png" alt="pc server interaction" loading="lazy" decoding="async"></p>
<p>When you type a <code>URL</code> into the browser's address bar, you’re directing your browser to connect to a specific <strong>web server</strong>.</p>
<p>The server processes your request and sends a response containing files like <code>HTML</code>, <code>CSS</code>, and <code>JavaScript</code>, along with media such as images and videos. If everything is fine, the server responds with a <strong>200 OK</strong> status code.</p>
<blockquote>
<p>The first request from a browser to a web server is always a <strong>GET</strong> request — a common interview question for junior developers.</p>
</blockquote>
<h3 id="request-response-parsing-rendering"><a class="hash" href="#request-response-parsing-rendering" aria-label="Subsection anchor">##</a>Request, Response, Parsing, Rendering</h3>
<h4 id="request">Request</h4>
<p>The browser sends an HTTP/HTTPS <strong>GET request</strong> to the server for the page’s content.</p>
<h4 id="response">Response</h4>
<p>The server (or CDN) returns data — HTML, CSS, JS, images — which the browser processes.</p>
<h4 id="parsing">Parsing</h4>
<p>Parsing is converting the HTML into a format the browser can understand — the <strong>DOM (Document Object Model)</strong>.</p>
<ul>
<li><strong>CSS</strong> is parsed into <strong>CSSOM (CSS Object Model)</strong>.</li>
<li><strong>JavaScript</strong> without <code>async</code> or <code>defer</code> stops HTML parsing until the script loads and runs.</li>
<li><strong>Render tree</strong> combines DOM + CSSOM for display.</li>
<li>Non-blocking resources (images, videos) load in parallel.</li>
</ul>
<p>The browser also builds an <strong>Accessibility Tree</strong>, which is essential for assistive technologies like screen readers.</p>
<h3 id="rendering"><a class="hash" href="#rendering" aria-label="Subsection anchor">##</a>Rendering</h3>
<p>Rendering is turning HTML, CSS, and JavaScript into a visual webpage.</p>
<ol>
<li><strong>Styles:</strong> DOM and CSSOM merge into a render tree of visible elements.</li>
<li><strong>Layout:</strong> Browser calculates size and position (box model: content, padding, border, margin).</li>
<li><strong>Painting:</strong> Browser draws pixels — text, images, colors.</li>
<li><strong>Interactivity:</strong> JavaScript loads, enabling scroll, clicks, and animations.</li>
</ol>
<h2 id="tti--time-to-interactive"><a class="hash" href="#tti--time-to-interactive" aria-label="Section anchor">#</a>TTI — Time To Interactive</h2>
<p><strong>TTI (Time To Interactive)</strong> measures how long it takes from the first request (starting with DNS lookup) until the page becomes fully interactive.</p>
<ul>
<li>Shorter TTI = better user experience.</li>
<li>Test your site’s TTI with <a href="https://pagespeed.web.dev/" target="_blank" rel="noopener">PageSpeed Insights</a>.</li>
</ul>
<h2 id="summary"><a class="hash" href="#summary" aria-label="Section anchor">#</a>Summary</h2>
<ul>
<li><strong>Domain &amp; IP:</strong> Human-friendly name + unique numeric address for devices.</li>
<li><strong>DNS Lookup:</strong> Translates domain names to IP addresses; caching speeds up repeat visits.</li>
<li><strong>CDN:</strong> Speeds up content delivery using global servers.</li>
<li><strong>Navigation:</strong> Entering a URL sends a GET request; server responds with page files.</li>
<li><strong>Request/Response:</strong> Browser requests data; server returns HTML, CSS, JS, and media.</li>
<li><strong>Parsing:</strong> HTML → DOM, CSS → CSSOM, combined into a render tree.</li>
<li><strong>Rendering:</strong> Calculates styles, layout, and draws the page.</li>
<li><strong>TTI:</strong> Time until a page is fully usable.</li>
</ul>
]]></content:encoded></item></channel></rss>