<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet type="text/xsl" href="atom.xsl"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <id>https://blog.0xniko.dev/</id>
    <title>Niko Blog Blog</title>
    <updated>2025-01-11T00:00:00.000Z</updated>
    <generator>https://github.com/jpmonette/feed</generator>
    <link rel="alternate" href="https://blog.0xniko.dev/"/>
    <subtitle>Niko Blog Blog</subtitle>
    <icon>https://blog.0xniko.dev/img/logo.jpg</icon>
    <entry>
        <title type="html"><![CDATA[Applied AI Series - RAG Better Results with Re-ranking]]></title>
        <id>https://blog.0xniko.dev/2025/01/11/rag-re-ranking-evolution</id>
        <link href="https://blog.0xniko.dev/2025/01/11/rag-re-ranking-evolution"/>
        <updated>2025-01-11T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Re-ranking in Retrieval-Augmented Generation (RAG) refines the documents retrieved in response to a user query, ensuring that only the most relevant and contextually appropriate ones are passed to the generation model. This step enhances response accuracy, handles ambiguity, and improves overall result quality by prioritizing the best matches for the query, ultimately leading to more precise and coherent AI-generated answers.]]></summary>
        <content type="html"><![CDATA[<p>Re-ranking in Retrieval-Augmented Generation (RAG) refines the documents retrieved in response to a user query, ensuring that only the most relevant and contextually appropriate ones are passed to the generation model. This step enhances response accuracy, handles ambiguity, and improves overall result quality by prioritizing the best matches for the query, ultimately leading to more precise and coherent AI-generated answers.</p>
<h2 class="anchor anchorWithStickyNavbar_GVoy" id="what-is-re-ranking-in-rag">What is Re-ranking in RAG?<a href="https://blog.0xniko.dev/2025/01/11/rag-re-ranking-evolution#what-is-re-ranking-in-rag" class="hash-link" aria-label="Direct link to What is Re-ranking in RAG?" title="Direct link to What is Re-ranking in RAG?">​</a></h2>
<!-- -->
<p>Re-ranking is the process of refining or reordering the list of documents or data retrieved during the retrieval phase of RAG. After a query is processed and relevant documents are retrieved, re-ranking evaluates these documents to determine which ones are most relevant to the user's question. The documents are then prioritized accordingly before being passed to the generation model for response crafting.</p>
<p>Essentially, re-ranking ensures that the most relevant, contextually appropriate documents are selected, improving the overall accuracy and quality of the generated response.</p>
<h2 class="anchor anchorWithStickyNavbar_GVoy" id="why-is-re-ranking-important">Why is Re-ranking Important?<a href="https://blog.0xniko.dev/2025/01/11/rag-re-ranking-evolution#why-is-re-ranking-important" class="hash-link" aria-label="Direct link to Why is Re-ranking Important?" title="Direct link to Why is Re-ranking Important?">​</a></h2>
<p>While retrieval systems like Elasticsearch or Dense Retriever can fetch a broad range of documents that are likely to be relevant to a query, not all retrieved documents will necessarily be the most informative or contextually aligned with the user’s intent. Here’s why re-ranking is crucial:</p>
<ul>
<li>
<p>Improves Response Quality: By selecting the best possible documents, re-ranking helps the AI model generate more accurate and meaningful responses.</p>
</li>
<li>
<p>Handles Ambiguity: Queries can sometimes be ambiguous, and not all retrieved documents will be equally relevant. Re-ranking allows the model to prioritize the best matches and address ambiguous or nuanced queries more effectively.</p>
</li>
<li>
<p>Contextual Relevance: Even when documents are contextually close, some might provide more precise information based on the specific needs of the query. Re-ranking ensures the AI assistant doesn't rely on documents that are less helpful or only tangentially related.</p>
</li>
<li>
<p>Reduces Information Overload: In large-scale information retrieval, you might retrieve dozens or hundreds of documents. Re-ranking streamlines the process by narrowing down the list to only the most relevant ones, making it easier for the LLM to generate an optimal answer.</p>
</li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_GVoy" id="how-does-re-ranking-work-in-a-rag-system">How Does Re-ranking Work in a RAG System?<a href="https://blog.0xniko.dev/2025/01/11/rag-re-ranking-evolution#how-does-re-ranking-work-in-a-rag-system" class="hash-link" aria-label="Direct link to How Does Re-ranking Work in a RAG System?" title="Direct link to How Does Re-ranking Work in a RAG System?">​</a></h2>
<p>To understand the role of re-ranking in RAG, let's break down the process:</p>
<ul>
<li>
<p>User Query: The user submits a query to the system.</p>
</li>
<li>
<p>Document Retrieval: A search or retrieval system is triggered to find relevant documents from a database or knowledge source. Initially, this could involve a broad set of results that may contain both highly relevant and less useful documents.</p>
</li>
<li>
<p>Re-ranking: Before passing the retrieved documents to the LLM for generation, the documents are re-ordered. This step typically involves evaluating factors such as:</p>
<ul>
<li>Semantic Relevance: How closely the content of a document matches the user's query.</li>
<li>Contextual Appropriateness: The document's ability to provide useful context for generating an accurate and comprehensive response.</li>
<li>Ranking Models: Machine learning models, such as those based on BERT or similar architectures, are often employed to predict the relevance of each document.</li>
</ul>
</li>
<li>
<p>Generation: After re-ranking, the top documents are selected and passed to the LLM, which processes the information and generates a contextualized response.</p>
</li>
<li>
<p>Final Response: The user receives a coherent and contextually relevant answer, based on the documents prioritized by the re-ranking phase.</p>
</li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_GVoy" id="re-ranking-strategies">Re-ranking strategies<a href="https://blog.0xniko.dev/2025/01/11/rag-re-ranking-evolution#re-ranking-strategies" class="hash-link" aria-label="Direct link to Re-ranking strategies" title="Direct link to Re-ranking strategies">​</a></h2>
<div class="theme-admonition theme-admonition-tip admonition_SLCK alert alert--success"><div class="admonitionHeading_VYlH"><span class="admonitionIcon_TaVW"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>tip</div><div class="admonitionContent_HP_r"><p>To help you better understand the role of RAG (Retrieve and Generate) in an AI assistant system, let choosing the right re-ranker for a RAG (Retrieve and Generate) your system.</p></div></div>
<h3 class="anchor anchorWithStickyNavbar_GVoy" id="1-traditional-retrieval-based-re-rankers">1. Traditional Retrieval-Based Re-rankers<a href="https://blog.0xniko.dev/2025/01/11/rag-re-ranking-evolution#1-traditional-retrieval-based-re-rankers" class="hash-link" aria-label="Direct link to 1. Traditional Retrieval-Based Re-rankers" title="Direct link to 1. Traditional Retrieval-Based Re-rankers">​</a></h3>
<p>Traditional retrieval-based re-rankers rely on statistical models to rank the relevance of retrieved documents. These models typically analyze features such as term frequency, document length, and inverse document frequency to score documents. While they are computationally efficient and easy to implement, they often lack the semantic depth and contextual understanding of more advanced models.</p>
<h4 class="anchor anchorWithStickyNavbar_GVoy" id="key-techniques"><strong>Key Techniques:</strong><a href="https://blog.0xniko.dev/2025/01/11/rag-re-ranking-evolution#key-techniques" class="hash-link" aria-label="Direct link to key-techniques" title="Direct link to key-techniques">​</a></h4>
<ul>
<li>TF-IDF (Term Frequency-Inverse Document Frequency):<!-- -->
<ul>
<li>TF-IDF is one of the oldest and most widely used methods for ranking documents in information retrieval. It scores documents based on how frequently a term appears in the document (Term Frequency) and how rare or common the term is across the entire dataset (Inverse Document Frequency).</li>
<li>Pros: Simple and computationally inexpensive, widely understood.</li>
<li>Cons: Does not capture semantic relationships or context; struggles with synonyms and polysemy (words with multiple meanings).</li>
</ul>
</li>
<li>BM25 (Best Matching 25):<!-- -->
<ul>
<li>BM25 is an advanced probabilistic retrieval model that builds on TF-IDF. It scores documents based on term frequency and document length but introduces parameters like a "saturation" factor, which adjusts the impact of term frequency at higher values. BM25 is more flexible and often more effective than pure TF-IDF.</li>
<li>Pros: Robust performance in many standard retrieval tasks; works well for general-purpose search engines.</li>
<li>Cons: Like TF-IDF, it doesn’t account for deeper semantic meaning or context.</li>
</ul>
</li>
</ul>
<h4 class="anchor anchorWithStickyNavbar_GVoy" id="when-to-use"><strong>When to Use:</strong><a href="https://blog.0xniko.dev/2025/01/11/rag-re-ranking-evolution#when-to-use" class="hash-link" aria-label="Direct link to when-to-use" title="Direct link to when-to-use">​</a></h4>
<p>Traditional re-ranking techniques like TF-IDF and BM25 are useful in situations where speed and simplicity are paramount, and when the data does not require deep semantic analysis. These methods are typically a starting point before transitioning to more complex neural-based re-ranking approaches.</p>
<h3 class="anchor anchorWithStickyNavbar_GVoy" id="2-neural-based-re-rankers">2. Neural-based Re-rankers<a href="https://blog.0xniko.dev/2025/01/11/rag-re-ranking-evolution#2-neural-based-re-rankers" class="hash-link" aria-label="Direct link to 2. Neural-based Re-rankers" title="Direct link to 2. Neural-based Re-rankers">​</a></h3>
<p>Neural-based re-ranking models leverage deep learning techniques to rank documents based on their semantic relevance to a given query. These models go beyond surface-level keyword matching and instead consider the meanings, relationships, and context of both the query and the retrieved documents.</p>
<h4 class="anchor anchorWithStickyNavbar_GVoy" id="key-techniques-1"><strong>Key Techniques:</strong><a href="https://blog.0xniko.dev/2025/01/11/rag-re-ranking-evolution#key-techniques-1" class="hash-link" aria-label="Direct link to key-techniques-1" title="Direct link to key-techniques-1">​</a></h4>
<ul>
<li>
<p>Transformer-based Models (e.g., BERT, RoBERTa, ALBERT):</p>
<ul>
<li>Transformer-based models are pre-trained on vast amounts of text and can understand contextual relationships between words, sentences, and even entire paragraphs. Fine-tuning these models on a ranking dataset can produce highly accurate re-ranking systems that understand both the query and the retrieved document at a deeper level.</li>
<li>Pros: Great at handling context, synonyms, and ambiguous queries; captures semantic meaning effectively.</li>
<li>Cons: Requires significant computational resources for training and fine-tuning; can be slower than traditional models.</li>
</ul>
</li>
<li>
<p>BERT-based Re-rankers (Cross-Encoder):</p>
<ul>
<li>In a typical BERT-based re-ranker, the query and document are passed together as a pair to the model, which generates a relevance score based on both the query and the document's content. The output is a binary classification or relevance score.</li>
<li>Pros: Very effective in understanding the fine-grained relevance between a query and document.</li>
<li>Cons: Computationally expensive due to the pairwise processing (query + document), making it slower than traditional models.</li>
</ul>
</li>
<li>
<p>DPR (Dense Passage Retrieval):</p>
<ul>
<li>DPR is an end-to-end learning framework that uses two separate neural networks: one for encoding the query and another for encoding documents (passages). These networks are trained jointly so that the query embedding and the document embedding are close in vector space for relevant document-query pairs.</li>
<li>Pros: Extremely good at semantic matching between queries and documents; can outperform traditional methods in complex search tasks.</li>
<li>Cons: Like BERT, it can be resource-intensive, especially for large-scale datasets.</li>
</ul>
</li>
</ul>
<h4 class="anchor anchorWithStickyNavbar_GVoy" id="when-to-use-1"><strong>When to Use:</strong><a href="https://blog.0xniko.dev/2025/01/11/rag-re-ranking-evolution#when-to-use-1" class="hash-link" aria-label="Direct link to when-to-use-1" title="Direct link to when-to-use-1">​</a></h4>
<p>Neural-based re-rankers are ideal for more complex, context-rich queries, particularly where the interaction between the query and documents is nuanced. These models are highly beneficial when semantic understanding and contextual relevance are important, but the computational cost is higher.</p>
<h3 class="anchor anchorWithStickyNavbar_GVoy" id="3-learning-to-rank-ltr-models">3. Learning-to-Rank (LTR) Models<a href="https://blog.0xniko.dev/2025/01/11/rag-re-ranking-evolution#3-learning-to-rank-ltr-models" class="hash-link" aria-label="Direct link to 3. Learning-to-Rank (LTR) Models" title="Direct link to 3. Learning-to-Rank (LTR) Models">​</a></h3>
<p>Learning-to-Rank is a machine learning approach where models are trained specifically to rank documents according to a given query. LTR models use labeled training data to learn which features (such as term relevance, document quality, semantic similarity, etc.) contribute most to the relevance of a document to a specific query.</p>
<h4 class="anchor anchorWithStickyNavbar_GVoy" id="key-techniques-2"><strong>Key Techniques:</strong><a href="https://blog.0xniko.dev/2025/01/11/rag-re-ranking-evolution#key-techniques-2" class="hash-link" aria-label="Direct link to key-techniques-2" title="Direct link to key-techniques-2">​</a></h4>
<ul>
<li>
<p>Gradient Boosted Decision Trees (GBDT):</p>
<ul>
<li>GBDT algorithms, like XGBoost or LightGBM, are commonly used in LTR models for re-ranking. These algorithms build an ensemble of decision trees, with each tree focusing on correcting the errors made by the previous one. GBDT models are effective at handling multiple features for ranking and can be highly optimized.</li>
<li>Pros: Can handle a variety of features (e.g., term frequency, document quality, contextual features) and are highly interpretable.</li>
<li>Cons: Requires careful feature engineering; not as effective as deep learning models in capturing semantic context.</li>
</ul>
</li>
<li>
<p>Neural Learning-to-Rank (NLR):</p>
<ul>
<li>NLR approaches use deep neural networks to learn the ranking function directly from raw text. This approach can take into account a wider array of features beyond what is available to traditional models (e.g., word embeddings, attention scores, etc.).</li>
<li>Pros: Can potentially learn more complex relationships between query and document relevance.</li>
<li>Cons: Requires a large amount of labeled training data and significant computational resources.</li>
</ul>
</li>
<li>
<p>RankNet, LambdaMART, and ListNet:</p>
<ul>
<li>These are popular algorithms used in Learning-to-Rank systems, often based on pairwise or listwise ranking principles. RankNet, for instance, is a neural network model that learns to rank document pairs, whereas LambdaMART is an extension of MART (Multiple Additive Regression Trees) optimized for ranking tasks.</li>
<li>Pros: High performance when there is enough labeled data for training; good at combining multiple features.</li>
<li>Cons: Requires a large dataset for training, and fine-tuning can be complex.</li>
</ul>
</li>
</ul>
<h4 class="anchor anchorWithStickyNavbar_GVoy" id="when-to-use-2"><strong>When to Use:</strong><a href="https://blog.0xniko.dev/2025/01/11/rag-re-ranking-evolution#when-to-use-2" class="hash-link" aria-label="Direct link to when-to-use-2" title="Direct link to when-to-use-2">​</a></h4>
<p>Learning-to-Rank models are best for scenarios where you have labeled training data and want to tailor the re-ranking to a specific set of features that influence relevance. This approach is commonly used in search engines and personalized information retrieval systems.</p>
<h3 class="anchor anchorWithStickyNavbar_GVoy" id="4-hybrid-re-ranking-models">4. Hybrid Re-ranking Models<a href="https://blog.0xniko.dev/2025/01/11/rag-re-ranking-evolution#4-hybrid-re-ranking-models" class="hash-link" aria-label="Direct link to 4. Hybrid Re-ranking Models" title="Direct link to 4. Hybrid Re-ranking Models">​</a></h3>
<p>Hybrid models combine the strengths of traditional information retrieval techniques and neural-based models to achieve optimal performance. These systems often use a multi-step process, where an initial retrieval phase is followed by a neural re-ranking phase that refines the results.</p>
<h4 class="anchor anchorWithStickyNavbar_GVoy" id="key-techniques-3"><strong>Key Techniques:</strong><a href="https://blog.0xniko.dev/2025/01/11/rag-re-ranking-evolution#key-techniques-3" class="hash-link" aria-label="Direct link to key-techniques-3" title="Direct link to key-techniques-3">​</a></h4>
<ul>
<li>
<p>Combining BM25 with BERT or RoBERTa:</p>
<ul>
<li>One common hybrid approach is to first retrieve a set of documents using traditional methods like BM25 or TF-IDF, and then pass these documents through a BERT-based re-ranker for semantic relevance evaluation. This hybrid model balances speed (BM25) with deep understanding (BERT).</li>
<li>Pros: Combines the efficiency of traditional methods with the power of modern NLP models, offering a balance of speed and accuracy.</li>
<li>Cons: Still requires careful design and resource management, especially when handling large-scale datasets.</li>
</ul>
</li>
<li>
<p>Feature Fusion (Traditional + Neural Features):</p>
<ul>
<li>In this approach, traditional features (like keyword overlap) are combined with neural network features (like contextual embeddings). These features are then input into a machine learning model (such as GBDT or a neural network) that ranks documents.</li>
<li>Pros: Enables the model to leverage the best of both worlds—semantic understanding and feature-rich analysis.</li>
<li>Cons: Feature engineering and model training can be complex and time-consuming.</li>
</ul>
</li>
</ul>
<h4 class="anchor anchorWithStickyNavbar_GVoy" id="when-to-use-3"><strong>When to Use:</strong><a href="https://blog.0xniko.dev/2025/01/11/rag-re-ranking-evolution#when-to-use-3" class="hash-link" aria-label="Direct link to when-to-use-3" title="Direct link to when-to-use-3">​</a></h4>
<p>Hybrid re-ranking models are ideal when you want to take advantage of both traditional efficiency and advanced semantic understanding. These models work well when you're balancing real-time performance with high-quality, nuanced ranking.</p>
<h2 class="anchor anchorWithStickyNavbar_GVoy" id="conclusion">Conclusion<a href="https://blog.0xniko.dev/2025/01/11/rag-re-ranking-evolution#conclusion" class="hash-link" aria-label="Direct link to Conclusion" title="Direct link to Conclusion">​</a></h2>
<p>Re-ranking is a critical component of the RAG framework, acting as a fine-tuner for the retrieval process. By ensuring that only the most relevant, contextually accurate documents are passed to the generation model, re-ranking directly enhances the quality and precision of the AI assistant’s responses.</p>
<p>Choosing the right re-ranker for a RAG system depends on your application's specific requirements, including:</p>
<ul>
<li>Speed: Traditional methods like BM25 are fast and simple.</li>
<li>Accuracy: Neural re-rankers (like BERT) offer deep semantic understanding but come with a higher computational cost.</li>
<li>Customization: Learning-to-Rank models can be tailored to specific features of the dataset and query patterns.</li>
<li>Hybrid Approaches: Hybrid re-rankers combine traditional and neural methods to balance efficiency and accuracy.</li>
</ul>
<p>By carefully considering these factors, you can select the most effective re-ranking strategy to optimize your RAG system and enhance the overall user experience.</p>
<p><strong>By carefully considering these factors, you can select the most effective re-ranking strategy to optimize your RAG system and enhance the overall user experience.</strong></p>
<h2 class="anchor anchorWithStickyNavbar_GVoy" id="references">References<a href="https://blog.0xniko.dev/2025/01/11/rag-re-ranking-evolution#references" class="hash-link" aria-label="Direct link to References" title="Direct link to References">​</a></h2>
<ul>
<li><a href="https://arxiv.org/abs/2005.11401" target="_blank" rel="noopener noreferrer">Retrieval-Augmented Generation (RAG) - A Survey</a></li>
<li><a href="https://aws.amazon.com/what-is/retrieval-augmented-generation/" target="_blank" rel="noopener noreferrer">What is Retrieval-Augmented Generation (RAG)?</a></li>
<li><a href="https://blogs.nvidia.com/blog/what-is-retrieval-augmented-generation/" target="_blank" rel="noopener noreferrer">RAG: A New Era of Language Model Integration</a></li>
<li><a href="https://learn.microsoft.com/en-us/azure/search/retrieval-augmented-generation-overview" target="_blank" rel="noopener noreferrer">Microsoft Azure: Overview of Retrieval-Augmented Generation</a></li>
<li><a href="https://arxiv.org/abs/2004.04906" target="_blank" rel="noopener noreferrer">Dense Passage Retrieval for Open-Domain Question Answering</a></li>
<li><a href="https://www.microsoft.com/en-us/research/wp-content/uploads/2007/01/RankNet-Technical-Report.pdf" target="_blank" rel="noopener noreferrer">Learning to Rank with Neural Networks: RankNet</a></li>
<li><a href="https://towardsdatascience.com/using-bert-for-re-ranking-information-retrieval-cf097d9a5899" target="_blank" rel="noopener noreferrer">BERT for Re-ranking: Understanding How Transformers Work in Information Retrieval</a></li>
<li><a href="https://en.wikipedia.org/wiki/BM25" target="_blank" rel="noopener noreferrer">BM25: Probabilistic Ranking Function</a></li>
<li><a href="https://xgboost.readthedocs.io/en/latest/" target="_blank" rel="noopener noreferrer">XGBoost: A Comprehensive Guide</a></li>
<li><a href="https://www.datacamp.com/community/blog/learning-to-rank" target="_blank" rel="noopener noreferrer">Introduction to Learning-to-Rank Algorithms</a></li>
</ul>]]></content>
        <author>
            <name>Niko</name>
            <uri>https://0xniko.dev</uri>
        </author>
        <category label="rag" term="rag"/>
        <category label="ai" term="ai"/>
        <category label="ai-series" term="ai-series"/>
        <category label="re-ranking" term="re-ranking"/>
        <category label="reranker" term="reranker"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Applied AI Series - RAG Speedup LLMs with Document chunking]]></title>
        <id>https://blog.0xniko.dev/2025/01/10/rag-document-chunking</id>
        <link href="https://blog.0xniko.dev/2025/01/10/rag-document-chunking"/>
        <updated>2025-01-10T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Document chunking is crucial for optimizing Retrieval-Augmented Generation (RAG) systems by breaking large documents into smaller, manageable pieces, which significantly speeds up retrieval and enhances the relevance of results. In RAG, where information retrieval is followed by text generation, chunking allows the system to search and process only the most relevant sections of content, improving both efficiency and accuracy. This approach ensures faster retrieval times, better handling of long-form documents, and more precise generation by focusing on contextually meaningful chunks rather than entire documents, ultimately enhancing the overall performance of LLMs in real-time applications.]]></summary>
        <content type="html"><![CDATA[<p>Document chunking is crucial for optimizing Retrieval-Augmented Generation (RAG) systems by breaking large documents into smaller, manageable pieces, which significantly speeds up retrieval and enhances the relevance of results. In RAG, where information retrieval is followed by text generation, chunking allows the system to search and process only the most relevant sections of content, improving both efficiency and accuracy. This approach ensures faster retrieval times, better handling of long-form documents, and more precise generation by focusing on contextually meaningful chunks rather than entire documents, ultimately enhancing the overall performance of LLMs in real-time applications.</p>
<h2 class="anchor anchorWithStickyNavbar_GVoy" id="what-is-document-chunking">What is Document Chunking?<a href="https://blog.0xniko.dev/2025/01/10/rag-document-chunking#what-is-document-chunking" class="hash-link" aria-label="Direct link to What is Document Chunking?" title="Direct link to What is Document Chunking?">​</a></h2>
<!-- -->
<p>Document chunking is the process of breaking down large documents into smaller, semantically meaningful sections or "chunks." These chunks typically range from paragraphs to sentences, allowing the RAG system to process information in smaller units without losing important context. Chunking helps optimize the retrieval phase of RAG by making it easier to index and search smaller parts of documents, rather than dealing with long, monolithic text.</p>
<h2 class="anchor anchorWithStickyNavbar_GVoy" id="why-is-document-chunking-important-for-rag">Why is Document Chunking Important for RAG?<a href="https://blog.0xniko.dev/2025/01/10/rag-document-chunking#why-is-document-chunking-important-for-rag" class="hash-link" aria-label="Direct link to Why is Document Chunking Important for RAG?" title="Direct link to Why is Document Chunking Important for RAG?">​</a></h2>
<ul>
<li>
<p>Faster Retrieval: By chunking documents, the retrieval system only needs to search smaller units of text, drastically reducing the time it takes to find relevant information.</p>
</li>
<li>
<p>Improved Contextual Relevance: Smaller chunks allow the system to focus on the most contextually relevant parts of a document, rather than irrelevant or tangential content, leading to more precise and meaningful responses.</p>
</li>
<li>
<p>Better Handling of Long-Form Content: Large documents or books are often too unwieldy for efficient processing in a single step. Document chunking allows RAG systems to handle long-form content by breaking it into digestible parts that can be indexed and retrieved effectively.</p>
</li>
<li>
<p>Scalability: Chunking makes it easier to scale a RAG system across large datasets, as each chunk can be indexed and queried independently, allowing the system to handle vast amounts of data more efficiently.</p>
</li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_GVoy" id="how-document-chunking-works-in-rag">How Document Chunking Works in RAG?<a href="https://blog.0xniko.dev/2025/01/10/rag-document-chunking#how-document-chunking-works-in-rag" class="hash-link" aria-label="Direct link to How Document Chunking Works in RAG?" title="Direct link to How Document Chunking Works in RAG?">​</a></h2>
<!-- -->
<ul>
<li>
<p>Input Document: A large document is split into smaller chunks, each containing a distinct section of relevant information (e.g., paragraphs, sections, or sentences).</p>
</li>
<li>
<p>Chunk Indexing: Each chunk is indexed for quick retrieval. Modern search engines like Elasticsearch or FAISS can index and search through these smaller units more efficiently than large, full documents.</p>
</li>
<li>
<p>Document Retrieval: When a query is made, the system retrieves the most relevant chunks rather than entire documents, significantly improving search speed and accuracy.</p>
</li>
<li>
<p>Generation: The retrieved chunks are passed to the generation model, which synthesizes the context from these smaller pieces to produce a coherent response.</p>
</li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_GVoy" id="how-document-chunking-speeds-up-llms">How Document Chunking Speeds Up LLMs<a href="https://blog.0xniko.dev/2025/01/10/rag-document-chunking#how-document-chunking-speeds-up-llms" class="hash-link" aria-label="Direct link to How Document Chunking Speeds Up LLMs" title="Direct link to How Document Chunking Speeds Up LLMs">​</a></h2>
<p>Document chunking accelerates the entire RAG pipeline in several key ways:</p>
<ul>
<li>Parallel Processing: Smaller chunks allow for parallelized retrieval and processing, enabling the system to scale efficiently across multiple documents and queries.</li>
<li>Reduced Token Count: By breaking down long documents, chunking reduces the number of tokens the LLM has to process at once, making it easier to generate faster responses.</li>
<li>Improved Search Accuracy: Smaller chunks allow for more focused and precise search results, reducing the time spent sifting through irrelevant data.</li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_GVoy" id="challenges-of-document-chunking">Challenges of Document Chunking<a href="https://blog.0xniko.dev/2025/01/10/rag-document-chunking#challenges-of-document-chunking" class="hash-link" aria-label="Direct link to Challenges of Document Chunking" title="Direct link to Challenges of Document Chunking">​</a></h2>
<div class="theme-admonition theme-admonition-tip admonition_SLCK alert alert--success"><div class="admonitionHeading_VYlH"><span class="admonitionIcon_TaVW"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>tip</div><div class="admonitionContent_HP_r"><p>As you consider integrating document chunking into your RAG system, think about your specific use case—whether you're building a customer support assistant, a research tool, or a knowledge management system. By experimenting with different chunking strategies, you can fine-tune your RAG pipeline to achieve optimal speed and accuracy.</p></div></div>
<p>While document chunking offers significant speedup, there are a few challenges to consider:</p>
<ul>
<li>Chunking Granularity: Deciding how small or large each chunk should be is crucial. Too small chunks may lose context, while too large chunks may not offer the desired speed benefits.</li>
<li>Semantic Integrity: Care must be taken to ensure that chunks retain meaningful and coherent information. Poor chunking can result in fragmented answers or loss of critical context.</li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_GVoy" id="popular-document-chunking-strategies-in-rag">Popular Document Chunking Strategies in RAG<a href="https://blog.0xniko.dev/2025/01/10/rag-document-chunking#popular-document-chunking-strategies-in-rag" class="hash-link" aria-label="Direct link to Popular Document Chunking Strategies in RAG" title="Direct link to Popular Document Chunking Strategies in RAG">​</a></h2>
<div class="theme-admonition theme-admonition-tip admonition_SLCK alert alert--success"><div class="admonitionHeading_VYlH"><span class="admonitionIcon_TaVW"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>tip</div><div class="admonitionContent_HP_r"><p>Selecting the right chunking strategy depends on the specific needs of your application, the structure of your documents, and the computational resources available. By tailoring the chunking strategy to the content and task, RAG systems can deliver significantly improved retrieval and generation performance.</p></div></div>
<h3 class="anchor anchorWithStickyNavbar_GVoy" id="1-fixed-length-chunking">1. <strong>Fixed-Length Chunking</strong><a href="https://blog.0xniko.dev/2025/01/10/rag-document-chunking#1-fixed-length-chunking" class="hash-link" aria-label="Direct link to 1-fixed-length-chunking" title="Direct link to 1-fixed-length-chunking">​</a></h3>
<ul>
<li><strong>Overview</strong>: This strategy divides a document into chunks of a pre-determined, fixed size. Typically, chunk sizes are measured by token counts (e.g., 512 tokens per chunk), which makes the process predictable and simple.</li>
<li><strong>Pros</strong>:<!-- -->
<ul>
<li><strong>Simplicity</strong>: Easy to implement, requiring minimal computation to break documents into chunks.</li>
<li><strong>Efficiency</strong>: Useful for fast retrieval when the context size is manageable and doesn't need to be overly granular.</li>
<li><strong>Uniformity</strong>: All chunks are of the same size, which can make processing predictable and manageable.</li>
</ul>
</li>
<li><strong>Cons</strong>:<!-- -->
<ul>
<li><strong>Context Loss</strong>: Important information could be split across chunks, leading to the loss of context.</li>
<li><strong>Inflexibility</strong>: Fixed size might result in chunks that are too short or too long, depending on the document structure.</li>
</ul>
</li>
<li><strong>Best For</strong>: Use cases where speed is essential, and documents are relatively short and well-structured. Works best when retrieval tasks don’t require deep, nuanced understanding.</li>
</ul>
<h3 class="anchor anchorWithStickyNavbar_GVoy" id="2-document-specific-chunking">2. <strong>Document-Specific Chunking</strong><a href="https://blog.0xniko.dev/2025/01/10/rag-document-chunking#2-document-specific-chunking" class="hash-link" aria-label="Direct link to 2-document-specific-chunking" title="Direct link to 2-document-specific-chunking">​</a></h3>
<ul>
<li><strong>Overview</strong>: Document-specific chunking is a more flexible approach, where chunks are created based on the document's unique structure. This could involve splitting the document at natural boundaries such as paragraphs, sections, or headings. It ensures that chunks are aligned with the document's inherent organization.</li>
<li><strong>Pros</strong>:<!-- -->
<ul>
<li><strong>Context Preservation</strong>: By chunking at logical document boundaries (such as paragraphs or sections), it preserves contextual integrity within each chunk.</li>
<li><strong>Adaptability</strong>: More adaptable to documents with varying structures, allowing for more meaningful and coherent chunks.</li>
<li><strong>Improved Relevance</strong>: Often results in chunks that are more contextually relevant to user queries, improving retrieval accuracy.</li>
</ul>
</li>
<li><strong>Cons</strong>:<!-- -->
<ul>
<li><strong>Inconsistency</strong>: Chunk sizes may vary depending on the document structure, leading to chunks that may be smaller or larger than optimal.</li>
<li><strong>Complexity</strong>: The need to identify logical document boundaries (e.g., section headings, paragraph markers) adds some complexity compared to fixed-length chunking.</li>
</ul>
</li>
<li><strong>Best For</strong>: Longer documents with well-defined structures such as articles, reports, or research papers, where maintaining context within chunks is essential.</li>
</ul>
<h3 class="anchor anchorWithStickyNavbar_GVoy" id="3-semantic-chunking">3. <strong>Semantic Chunking</strong><a href="https://blog.0xniko.dev/2025/01/10/rag-document-chunking#3-semantic-chunking" class="hash-link" aria-label="Direct link to 3-semantic-chunking" title="Direct link to 3-semantic-chunking">​</a></h3>
<ul>
<li><strong>Overview</strong>: Semantic chunking leverages natural language processing (NLP) models to identify semantically meaningful boundaries within a document. This method groups text segments that share a common theme or topic, ensuring that the chunk reflects a coherent thought or piece of information, regardless of its physical size or paragraph breaks.</li>
<li><strong>Pros</strong>:<!-- -->
<ul>
<li><strong>Context-Aware</strong>: Ensures that chunks are semantically consistent, grouping together related ideas even if they are not in the same paragraph or section.</li>
<li><strong>Improved Retrieval</strong>: By focusing on the meaning and relevance of the content, semantic chunking leads to more accurate document retrieval and higher-quality generated responses.</li>
<li><strong>Flexible Size</strong>: Chunks can be of varying lengths based on the content's meaning rather than arbitrary size constraints.</li>
</ul>
</li>
<li><strong>Cons</strong>:<!-- -->
<ul>
<li><strong>Computationally Intensive</strong>: Requires advanced NLP models (e.g., BERT, GPT) to analyze the content and understand semantic relationships.</li>
<li><strong>Training Data Requirement</strong>: Effective semantic chunking often requires labeled data or a pre-trained model, which may require fine-tuning for optimal performance.</li>
</ul>
</li>
<li><strong>Best For</strong>: Complex or long-form documents where semantic meaning is critical for accurately answering queries, such as academic papers, technical documentation, or nuanced content like legal texts.</li>
</ul>
<h3 class="anchor anchorWithStickyNavbar_GVoy" id="how-to-choose-the-right-chunking-strategy">How to Choose the Right Chunking Strategy?<a href="https://blog.0xniko.dev/2025/01/10/rag-document-chunking#how-to-choose-the-right-chunking-strategy" class="hash-link" aria-label="Direct link to How to Choose the Right Chunking Strategy?" title="Direct link to How to Choose the Right Chunking Strategy?">​</a></h3>
<ul>
<li><strong>Fixed-Length Chunking</strong>: Opt for this when the document is simple, short, and when retrieval speed is the main concern. Works well for standardized or structured content.</li>
<li><strong>Document-Specific Chunking</strong>: Ideal for documents with clear structural boundaries, such as reports, articles, or documentation where maintaining contextual relevance is important without relying on complex semantic models.</li>
<li><strong>Semantic Chunking</strong>: Choose this for complex, unstructured, or long documents where context, topic relevance, and meaning are paramount. Perfect for sophisticated tasks such as question answering, summarization, or complex search.</li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_GVoy" id="conclusion">Conclusion<a href="https://blog.0xniko.dev/2025/01/10/rag-document-chunking#conclusion" class="hash-link" aria-label="Direct link to Conclusion" title="Direct link to Conclusion">​</a></h2>
<p>Document chunking is a powerful technique that significantly enhances the efficiency of RAG systems, particularly when dealing with large-scale datasets. By breaking down documents into smaller, more manageable chunks, RAG can retrieve and generate more relevant, faster responses, ultimately improving user experience. As the demand for AI systems capable of handling vast amounts of information increases, document chunking will continue to be a vital strategy in optimizing performance.</p>
<p>Each chunking strategy plays a unique role in enhancing the performance of RAG-based systems:</p>
<ul>
<li><strong>Fixed-Length Chunking</strong> is best for speed and simplicity when context is not overly complex.</li>
<li><strong>Document-Specific Chunking</strong> provides a balanced approach for documents with natural structures, improving context while keeping chunk size manageable.</li>
<li><strong>Semantic Chunking</strong> is the most powerful for ensuring that the chunks are deeply relevant and contextually coherent, especially in complex documents.</li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_GVoy" id="references">References<a href="https://blog.0xniko.dev/2025/01/10/rag-document-chunking#references" class="hash-link" aria-label="Direct link to References" title="Direct link to References">​</a></h2>
<ul>
<li>
<p><a href="https://aws.amazon.com/what-is/retrieval-augmented-generation/" target="_blank" rel="noopener noreferrer">A Guide to Chunking Strategies for Retrieval Augmented Generation (RAG)</a></p>
</li>
<li>
<p><a href="https://learn.microsoft.com/en-us/azure/architecture/ai-ml/guide/rag/rag-chunking-phase" target="_blank" rel="noopener noreferrer">RAG chunking phase with MS Azure</a></p>
</li>
<li>
<p><a href="https://medium.com/@david.richards.tech/document-chunking-for-rag-ai-applications-04363d48fbf7" target="_blank" rel="noopener noreferrer">Document Chunking for AI RAG Applications</a></p>
</li>
<li>
<p><a href="https://unstructured.io/blog/chunking-for-rag-best-practices" target="_blank" rel="noopener noreferrer">Chunking for RAG: best practices</a></p>
</li>
</ul>]]></content>
        <author>
            <name>Niko</name>
            <uri>https://0xniko.dev</uri>
        </author>
        <category label="rag" term="rag"/>
        <category label="ai" term="ai"/>
        <category label="ai-series" term="ai-series"/>
        <category label="chunking" term="chunking"/>
        <category label="chunker" term="chunker"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Applied AI Series - What is RAG?]]></title>
        <id>https://blog.0xniko.dev/2024/09/13/migrate-personal-applied-ai-series-what-is-rag</id>
        <link href="https://blog.0xniko.dev/2024/09/13/migrate-personal-applied-ai-series-what-is-rag"/>
        <updated>2024-09-13T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[To help you better understand the role of RAG (Retrieve and Generate) in an AI assistant system, let’s explore a workflow diagram. This diagram will illustrate how RAG integrates with a Large Language Model (LLM) to enhance the AI assistant’s capabilities]]></summary>
        <content type="html"><![CDATA[<p>Welcome to the latest installment of our Applied AI Series, where we delve into cutting-edge technologies and explore how they are transforming industries and everyday tasks. In this edition, we’ll unravel the intricacies of RAG (Retrieve and Generate), a powerful framework that’s making waves in the field of artificial intelligence. Whether you're a tech enthusiast, a researcher, or someone curious about AI, this post will provide a clear understanding of RAG and its applications.</p>
<h2 class="anchor anchorWithStickyNavbar_GVoy" id="understanding-rag">Understanding RAG<a href="https://blog.0xniko.dev/2024/09/13/migrate-personal-applied-ai-series-what-is-rag#understanding-rag" class="hash-link" aria-label="Direct link to Understanding RAG" title="Direct link to Understanding RAG">​</a></h2>
<h3 class="anchor anchorWithStickyNavbar_GVoy" id="what-does-rag-stand-for">What Does RAG Stand For?<a href="https://blog.0xniko.dev/2024/09/13/migrate-personal-applied-ai-series-what-is-rag#what-does-rag-stand-for" class="hash-link" aria-label="Direct link to What Does RAG Stand For?" title="Direct link to What Does RAG Stand For?">​</a></h3>
<p>RAG stands for Retrieve and Generate. It’s an advanced approach in natural language processing (NLP) that combines two fundamental AI techniques:</p>
<ul>
<li>Retrieve: This involves searching through a large dataset or document repository to find information that is relevant to a given query or context.</li>
<li>Generate: After retrieving the relevant information, this component uses AI models to generate a coherent and contextually appropriate response based on the retrieved data.</li>
</ul>
<p>The synergy between these two components allows RAG systems to provide more accurate, relevant, and contextually rich responses compared to traditional methods that rely solely on retrieval or generation.</p>
<h3 class="anchor anchorWithStickyNavbar_GVoy" id="how-does-rag-work">How Does RAG Work?<a href="https://blog.0xniko.dev/2024/09/13/migrate-personal-applied-ai-series-what-is-rag#how-does-rag-work" class="hash-link" aria-label="Direct link to How Does RAG Work?" title="Direct link to How Does RAG Work?">​</a></h3>
<ul>
<li>
<p>Information Retrieval: When a user inputs a query, the RAG system first searches a database or knowledge base to identify relevant documents or pieces of information. This step ensures that the response is grounded in actual data and not just generated from scratch.</p>
</li>
<li>
<p>Text Generation: The retrieved information is then fed into a language model, which synthesizes this data to generate a response. This model, often based on advanced architectures like GPT (Generative Pre-trained Transformer), leverages its training to craft responses that are both informative and contextually appropriate.</p>
</li>
<li>
<p>Integration: The RAG framework integrates these two processes, ensuring that the generated content is not only relevant but also coherent and engaging.</p>
</li>
</ul>
<h3 class="anchor anchorWithStickyNavbar_GVoy" id="why-is-rag-important">Why is RAG Important?<a href="https://blog.0xniko.dev/2024/09/13/migrate-personal-applied-ai-series-what-is-rag#why-is-rag-important" class="hash-link" aria-label="Direct link to Why is RAG Important?" title="Direct link to Why is RAG Important?">​</a></h3>
<ul>
<li>
<p>Enhanced Accuracy: By retrieving specific information from a large dataset, RAG ensures that responses are based on factual data, reducing the likelihood of generating misleading or incorrect answers.</p>
</li>
<li>
<p>Contextual Relevance: RAG models excel at understanding the context of a query and providing answers that are not only relevant but also nuanced, addressing the complexities of natural language.</p>
</li>
<li>
<p>Scalability: RAG can handle vast amounts of data, making it ideal for applications like building knowledge bases, chatbots, and customer support systems where large-scale information retrieval and generation are crucial.</p>
</li>
<li>
<p>Improved UX: By combining retrieval with generation, RAG systems offer more engaging and informative interactions, enhancing user satisfaction and usability.</p>
</li>
</ul>
<h3 class="anchor anchorWithStickyNavbar_GVoy" id="applications-of-rag">Applications of RAG<a href="https://blog.0xniko.dev/2024/09/13/migrate-personal-applied-ai-series-what-is-rag#applications-of-rag" class="hash-link" aria-label="Direct link to Applications of RAG" title="Direct link to Applications of RAG">​</a></h3>
<ol>
<li>
<p>Knowledge Management
RAG is revolutionizing how organizations manage and access knowledge. By integrating a robust retrieval system with advanced text generation, companies can build comprehensive knowledge bases that are easy to navigate and provide users with precise information.</p>
</li>
<li>
<p>Customer Support
In customer support, RAG can be used to develop intelligent chatbots and virtual assistants that retrieve relevant information from support documents and generate helpful responses. This improves response accuracy and reduces the time needed to resolve customer queries.</p>
</li>
<li>
<p>Research and Development
For researchers and developers, RAG can assist in literature reviews and information synthesis by retrieving relevant academic papers and generating summaries or insights, streamlining the research process and saving valuable time.</p>
</li>
<li>
<p>Content Creation
RAG can also be used in content creation to generate articles, reports, or creative content based on specific topics or data sets, providing a more efficient and contextually rich writing process.</p>
</li>
</ol>
<h2 class="anchor anchorWithStickyNavbar_GVoy" id="understanding-rag-with-a-workflow-diagram">Understanding RAG with a Workflow Diagram<a href="https://blog.0xniko.dev/2024/09/13/migrate-personal-applied-ai-series-what-is-rag#understanding-rag-with-a-workflow-diagram" class="hash-link" aria-label="Direct link to Understanding RAG with a Workflow Diagram" title="Direct link to Understanding RAG with a Workflow Diagram">​</a></h2>
<div class="theme-admonition theme-admonition-tip admonition_SLCK alert alert--success"><div class="admonitionHeading_VYlH"><span class="admonitionIcon_TaVW"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>tip</div><div class="admonitionContent_HP_r"><p>To help you better understand the role of RAG (Retrieve and Generate) in an AI assistant system, let’s explore a workflow diagram. This diagram will illustrate how RAG integrates with a Large Language Model (LLM) to enhance the AI assistant’s capabilities.</p></div></div>
<!-- -->
<p>Workflows:</p>
<ol>
<li>
<p>User Query: The process begins when a user submits a query to the AI assistant. This could be a question, request for information, or any input requiring a response.</p>
</li>
<li>
<p>Retrieve Relevant Documents: The RAG system initiates the retrieval phase, where it searches through a vast database or knowledge base to find relevant documents or pieces of information related to the user’s query.</p>
</li>
<li>
<p>Search in Database: The retrieval system, often powered by tools like Elasticsearch, performs a search within the database to locate documents that match the query.</p>
</li>
<li>
<p>Retrieve Documents: Relevant documents are retrieved from the database based on the search results. These documents provide the necessary context and information needed for generating a response.</p>
</li>
<li>
<p>Generate Response: The retrieved documents are then fed into the text generation component of the RAG system.</p>
</li>
<li>
<p>LLM Processes Data: A Large Language Model (LLM), such as GPT, processes the retrieved data. The model uses its understanding of language and context to generate a coherent and relevant response.</p>
</li>
<li>
<p>Contextualized Response: The response generated by the LLM is contextualized using the information from the retrieved documents, ensuring that the answer is both accurate and contextually appropriate.</p>
</li>
<li>
<p>User Receives Answer: Finally, the AI assistant delivers the generated response back to the user, providing them with the information or answer they requested.</p>
</li>
</ol>
<h2 class="anchor anchorWithStickyNavbar_GVoy" id="references">References<a href="https://blog.0xniko.dev/2024/09/13/migrate-personal-applied-ai-series-what-is-rag#references" class="hash-link" aria-label="Direct link to References" title="Direct link to References">​</a></h2>
<ul>
<li><a href="https://arxiv.org/abs/2005.11401" target="_blank" rel="noopener noreferrer">https://arxiv.org/abs/2005.11401</a></li>
<li><a href="https://aws.amazon.com/what-is/retrieval-augmented-generation/" target="_blank" rel="noopener noreferrer">https://aws.amazon.com/what-is/retrieval-augmented-generation/</a></li>
<li><a href="https://www.datacamp.com/blog/what-is-retrieval-augmented-generation-rag" target="_blank" rel="noopener noreferrer">https://www.datacamp.com/blog/what-is-retrieval-augmented-generation-rag</a></li>
<li><a href="https://learn.microsoft.com/en-us/azure/search/retrieval-augmented-generation-overview" target="_blank" rel="noopener noreferrer">https://learn.microsoft.com/en-us/azure/search/retrieval-augmented-generation-overview</a></li>
<li><a href="https://blogs.nvidia.com/blog/what-is-retrieval-augmented-generation/" target="_blank" rel="noopener noreferrer">https://blogs.nvidia.com/blog/what-is-retrieval-augmented-generation/</a></li>
</ul>]]></content>
        <author>
            <name>Niko</name>
            <uri>https://0xniko.dev</uri>
        </author>
        <category label="rag" term="rag"/>
        <category label="ai" term="ai"/>
        <category label="ai-series" term="ai-series"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[From Jekyll to Docusaurus, I Migrated My Blog After 5 Years]]></title>
        <id>https://blog.0xniko.dev/2024/09/08/migrate-personal-blog-to-docusaurus-after-5-years-with-jekyll</id>
        <link href="https://blog.0xniko.dev/2024/09/08/migrate-personal-blog-to-docusaurus-after-5-years-with-jekyll"/>
        <updated>2024-09-08T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[After five years of running my engineering blog on Jekyll, I’ve decided to migrate to Docusaurus]]></summary>
        <content type="html"><![CDATA[<h2 class="anchor anchorWithStickyNavbar_GVoy" id="reflecting-on-5-years-with-jekyll-why-i-migrated-my-engineering-blog-to-docusaurus">Reflecting on 5 Years with Jekyll: Why I Migrated My Engineering Blog to Docusaurus<a href="https://blog.0xniko.dev/2024/09/08/migrate-personal-blog-to-docusaurus-after-5-years-with-jekyll#reflecting-on-5-years-with-jekyll-why-i-migrated-my-engineering-blog-to-docusaurus" class="hash-link" aria-label="Direct link to Reflecting on 5 Years with Jekyll: Why I Migrated My Engineering Blog to Docusaurus" title="Direct link to Reflecting on 5 Years with Jekyll: Why I Migrated My Engineering Blog to Docusaurus">​</a></h2>
<p>After five years of running my engineering blog on Jekyll, I’ve decided to migrate to Docusaurus. This decision came after extensive evaluation of my blogging needs and the capabilities of various platforms. In this post, I’ll share the reasons behind the migration, the benefits I’ve experienced, and the improvements I’ve seen with Docusaurus.</p>
<h3 class="anchor anchorWithStickyNavbar_GVoy" id="why-leave-jekyll-after-5-years">Why Leave Jekyll After 5 Years?<a href="https://blog.0xniko.dev/2024/09/08/migrate-personal-blog-to-docusaurus-after-5-years-with-jekyll#why-leave-jekyll-after-5-years" class="hash-link" aria-label="Direct link to Why Leave Jekyll After 5 Years?" title="Direct link to Why Leave Jekyll After 5 Years?">​</a></h3>
<p>Jekyll has served me well over the years, but as my blog evolved, certain limitations became more apparent. Here’s why I chose to make the switch to Docusaurus:</p>
<ol>
<li>
<p><strong>User Experience Overhaul:</strong>
Jekyll provided a solid foundation, but its user interface started to feel outdated. Docusaurus offers a modern, sleek design that enhances the reader’s experience. The default theme and customizable options in Docusaurus are more aligned with current web standards, offering a better user experience.</p>
</li>
<li>
<p><strong>Enhanced Performance:</strong>
As my blog grew, I noticed performance issues with Jekyll. Docusaurus’s React-based architecture allows for faster page loads and more interactive features. This performance improvement is crucial for retaining readers and improving engagement.</p>
</li>
<li>
<p><strong>Better Content Management:</strong>
Jekyll’s content management is straightforward but can be limiting for complex needs. Docusaurus excels in handling structured content, especially for documentation and blog posts, with features like easy content versioning and search capabilities.</p>
</li>
<li>
<p><strong>Customization Flexibility:</strong>
Customizing Jekyll themes required a deep dive into Ruby and Liquid templates, which could be cumbersome. Docusaurus, built on React, allows for more flexible and modular customization. Integrating tools like Tailwind CSS has simplified the process of styling my site to match my vision.</p>
</li>
<li>
<p><strong>Streamlined Deployment and Automation:</strong>
While Jekyll’s deployment with GitHub Pages was functional, Docusaurus offers a more streamlined approach with automated build processes. I’ve set up GitHub Actions to handle the build and deployment seamlessly, which saves time and reduces manual intervention.</p>
</li>
</ol>
<h3 class="anchor anchorWithStickyNavbar_GVoy" id="migration-process-and-key-changes">Migration Process and Key Changes<a href="https://blog.0xniko.dev/2024/09/08/migrate-personal-blog-to-docusaurus-after-5-years-with-jekyll#migration-process-and-key-changes" class="hash-link" aria-label="Direct link to Migration Process and Key Changes" title="Direct link to Migration Process and Key Changes">​</a></h3>
<p>Here’s a closer look at the steps I took to migrate from Jekyll to Docusaurus and the changes that came with it:</p>
<h4 class="anchor anchorWithStickyNavbar_GVoy" id="1-initiating-docusaurus">1. <strong>Initiating Docusaurus</strong><a href="https://blog.0xniko.dev/2024/09/08/migrate-personal-blog-to-docusaurus-after-5-years-with-jekyll#1-initiating-docusaurus" class="hash-link" aria-label="Direct link to 1-initiating-docusaurus" title="Direct link to 1-initiating-docusaurus">​</a></h4>
<p>I began by setting up a new Docusaurus site with the <code>create-docusaurus</code> command:</p>
<div class="language-sh codeBlockContainer_Dsm5 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent__qvQ"><pre tabindex="0" class="prism-code language-sh codeBlock_TP_y thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_o52p"><span class="token-line" style="color:#393A34"><span class="token plain">npx create-docusaurus@latest my-blog classic</span><br></span></code></pre><div class="buttonGroup_pyGv"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_WfJE" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ImZj"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_OeyQ"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>This provided a fresh and modern foundation to build upon. The classic preset includes a ready-to-go blog setup that made the initial transition smoother.</p>
<h4 class="anchor anchorWithStickyNavbar_GVoy" id="2-configuring-the-new-site">2. <strong>Configuring the New Site</strong><a href="https://blog.0xniko.dev/2024/09/08/migrate-personal-blog-to-docusaurus-after-5-years-with-jekyll#2-configuring-the-new-site" class="hash-link" aria-label="Direct link to 2-configuring-the-new-site" title="Direct link to 2-configuring-the-new-site">​</a></h4>
<p>The <code>docusaurus.config.js</code> file was configured to reflect my previous blog’s settings, including site title and URL. The configuration options in Docusaurus are more intuitive and flexible compared to Jekyll’s <code>_config.yml</code>:</p>
<div class="language-js codeBlockContainer_Dsm5 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent__qvQ"><pre tabindex="0" class="prism-code language-js codeBlock_TP_y thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_o52p"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> config </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">title</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'Niko Blog'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">tagline</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'Niko typing...'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">url</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'https://blog.0xniko.dev'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">baseUrl</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'/'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">favicon</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'img/logo.jpg'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">onBrokenLinks</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'throw'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">onBrokenMarkdownLinks</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'warn'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">presets</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token string" style="color:#e3116c">'@docusaurus/preset-classic'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token literal-property property" style="color:#36acaa">docs</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">false</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token literal-property property" style="color:#36acaa">blog</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token literal-property property" style="color:#36acaa">routeBasePath</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'/'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token literal-property property" style="color:#36acaa">blogSidebarTitle</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'Recent posts'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token literal-property property" style="color:#36acaa">blogSidebarCount</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">3</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token literal-property property" style="color:#36acaa">showReadingTime</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token literal-property property" style="color:#36acaa">feedOptions</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token literal-property property" style="color:#36acaa">type</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token string" style="color:#e3116c">'rss'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'atom'</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token literal-property property" style="color:#36acaa">xslt</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token literal-property property" style="color:#36acaa">theme</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token literal-property property" style="color:#36acaa">customCss</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> require</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">resolve</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'./src/css/custom.css'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre><div class="buttonGroup_pyGv"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_WfJE" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ImZj"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_OeyQ"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h4 class="anchor anchorWithStickyNavbar_GVoy" id="3-migrating-content">3. <strong>Migrating Content</strong><a href="https://blog.0xniko.dev/2024/09/08/migrate-personal-blog-to-docusaurus-after-5-years-with-jekyll#3-migrating-content" class="hash-link" aria-label="Direct link to 3-migrating-content" title="Direct link to 3-migrating-content">​</a></h4>
<p>Migrating content from Jekyll involved converting Markdown files and adjusting formats. Docusaurus’s Markdown support is robust and easier to work with, making this process smoother.</p>
<h4 class="anchor anchorWithStickyNavbar_GVoy" id="4-customizing-the-look-and-feel">4. <strong>Customizing the Look and Feel</strong><a href="https://blog.0xniko.dev/2024/09/08/migrate-personal-blog-to-docusaurus-after-5-years-with-jekyll#4-customizing-the-look-and-feel" class="hash-link" aria-label="Direct link to 4-customizing-the-look-and-feel" title="Direct link to 4-customizing-the-look-and-feel">​</a></h4>
<p>Customizing Docusaurus was a breeze compared to Jekyll. I used Tailwind CSS for a modern, responsive design. The integration process is well-documented and straightforward. For details on theme customization, see the <a href="https://docusaurus.io/docs/styling-layout" target="_blank" rel="noopener noreferrer">Docusaurus styling guide</a>.</p>
<h4 class="anchor anchorWithStickyNavbar_GVoy" id="5-automating-deployment">5. <strong>Automating Deployment</strong><a href="https://blog.0xniko.dev/2024/09/08/migrate-personal-blog-to-docusaurus-after-5-years-with-jekyll#5-automating-deployment" class="hash-link" aria-label="Direct link to 5-automating-deployment" title="Direct link to 5-automating-deployment">​</a></h4>
<p>I set up GitHub Actions to automate the build and deployment process. The new workflow file in <code>.github/workflows/deploy.yml</code> ensures that any changes pushed to the <code>main</code> branch are automatically built and deployed:</p>
<div class="language-yaml codeBlockContainer_Dsm5 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent__qvQ"><pre tabindex="0" class="prism-code language-yaml codeBlock_TP_y thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_o52p"><span class="token-line" style="color:#393A34"><span class="token key atrule" style="color:#00a4db">name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> Build and Deploy Site</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">on</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">push</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">branches</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> main</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">permissions</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">contents</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> read</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">pages</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> write</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">id-token</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> write</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">concurrency</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">group</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"pages"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">cancel-in-progress</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean important" style="color:#36acaa">true</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">jobs</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">build</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">runs-on</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> ubuntu</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">latest</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">steps</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> Checkout code</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token key atrule" style="color:#00a4db">uses</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> actions/checkout@v3</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> Set up Node.js</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token key atrule" style="color:#00a4db">uses</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> actions/setup</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">node@v3</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token key atrule" style="color:#00a4db">with</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token key atrule" style="color:#00a4db">node-version</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"20"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> Setup tools</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token key atrule" style="color:#00a4db">run</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">|</span><span class="token scalar string" style="color:#e3116c"></span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">          npm i -g pnpm</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> Install dependencies</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token key atrule" style="color:#00a4db">run</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> pnpm install</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> Build Docusaurus site</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token key atrule" style="color:#00a4db">run</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> pnpm build</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> Upload artifact</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token key atrule" style="color:#00a4db">uses</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> actions/upload</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">pages</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">artifact@v3</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token key atrule" style="color:#00a4db">with</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token key atrule" style="color:#00a4db">path</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> ./build</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">deploy</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">environment</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token key atrule" style="color:#00a4db">name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> github</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">pages</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token key atrule" style="color:#00a4db">url</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> $</span><span class="token punctuation" style="color:#393A34">{</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> steps.deployment.outputs.page_url </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">runs-on</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> ubuntu</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">latest</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">needs</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> build</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">steps</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> Deploy to GitHub Pages</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token key atrule" style="color:#00a4db">id</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> deployment</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token key atrule" style="color:#00a4db">uses</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> actions/deploy</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">pages@v4</span><br></span></code></pre><div class="buttonGroup_pyGv"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_WfJE" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ImZj"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_OeyQ"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h3 class="anchor anchorWithStickyNavbar_GVoy" id="conclusion">Conclusion<a href="https://blog.0xniko.dev/2024/09/08/migrate-personal-blog-to-docusaurus-after-5-years-with-jekyll#conclusion" class="hash-link" aria-label="Direct link to Conclusion" title="Direct link to Conclusion">​</a></h3>
<p>Migrating from Jekyll to Docusaurus has revitalized my blog with modern features, improved performance, and greater flexibility. The transition has been a significant upgrade, aligning better with my current needs and future growth.</p>
<p>If you’re considering a similar move, I hope this guide provides valuable insights. Feel free to reach out with any questions or if you need help with your own migration.</p>
<p>Anyway too love Open Source like Jekyll.</p>
<h3 class="anchor anchorWithStickyNavbar_GVoy" id="references">References<a href="https://blog.0xniko.dev/2024/09/08/migrate-personal-blog-to-docusaurus-after-5-years-with-jekyll#references" class="hash-link" aria-label="Direct link to References" title="Direct link to References">​</a></h3>
<ul>
<li>
<p>I publish source code here: <a href="https://github.com/niko0xdev/0xblog" target="_blank" rel="noopener noreferrer">https://github.com/niko0xdev/0xblog</a></p>
</li>
<li>
<p>Docusaurus documents: <a href="https://docusaurus.io/docs/blog" target="_blank" rel="noopener noreferrer">https://docusaurus.io/docs/blog</a></p>
</li>
</ul>]]></content>
        <author>
            <name>Niko</name>
            <uri>https://0xniko.dev</uri>
        </author>
        <category label="blog" term="blog"/>
        <category label="Docusaurus" term="Docusaurus"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Javascript series - Service Worker and Caching strategies]]></title>
        <id>https://blog.0xniko.dev/2023/01/28/service-worker-caching-strategies</id>
        <link href="https://blog.0xniko.dev/2023/01/28/service-worker-caching-strategies"/>
        <updated>2023-01-28T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Service workers are a powerful tool for web development, providing developers with more control over the network and caching strategies of web applications]]></summary>
        <content type="html"><![CDATA[<div class="theme-admonition theme-admonition-tip admonition_SLCK alert alert--success"><div class="admonitionHeading_VYlH"><span class="admonitionIcon_TaVW"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>tip</div><div class="admonitionContent_HP_r"><blockquote>
<p>Service workers are a powerful tool for web development, providing developers with more control over the network and caching strategies of web applications</p>
</blockquote></div></div>
<h2 class="anchor anchorWithStickyNavbar_GVoy" id="what-is-service-workers">What is service workers?<a href="https://blog.0xniko.dev/2023/01/28/service-worker-caching-strategies#what-is-service-workers" class="hash-link" aria-label="Direct link to What is service workers?" title="Direct link to What is service workers?">​</a></h2>
<p><code>Service workers</code> are a game-changer for web development. They allow developers to create offline-capable web applications, improve performance, and even enable push notifications. But what exactly are they, and how do they work?</p>
<p>A service worker is a type of JavaScript worker that runs in the background, separate from the main browser thread. It has the ability to intercept network requests, access the browser's cache, and serve responses from the cache or the network, depending on the availability of the network and the resources being requested.</p>
<p>One of the main benefits of service workers is that they allow web applications to work offline. When a service worker is installed, it can cache the resources needed for the application to run, such as HTML, CSS, and JavaScript files. When the user navigates to the application while offline, the service worker can intercept the request and serve the cached resources, allowing the application to continue functioning as normal.</p>
<p>But service workers can do more than just provide offline capabilities. They can also be used to improve the performance of web applications by caching resources and reducing the number of network requests. For example, a service worker can cache images and other assets, so they are loaded from the cache instead of being downloaded from the network each time the user navigates to the page.</p>
<p>Another benefit of service workers is the ability to receive push notifications. Even when the browser is closed, a service worker can listen for push notifications and display them to the user, providing a more engaging and interactive experience.</p>
<p>It's important to note that service workers are only available on HTTPS connections, to ensure the security of the service worker and the resources it handles.</p>
<p>Caching is one of the key features of service workers and it is essential for creating offline-capable web applications. Service workers can intercept network requests and access the browser's cache, allowing developers to implement custom caching strategies that suit the specific needs of their application. Some popular caching strategies include "cache first", "network first", and "cache and network race" strategy. Developers can also choose to expire certain resources after a certain period of time so that they are only fetched from the network when they are deemed out-of-date.</p>
<h3 class="anchor anchorWithStickyNavbar_GVoy" id="how-to-install-a-service-worker">How to install a service worker?<a href="https://blog.0xniko.dev/2023/01/28/service-worker-caching-strategies#how-to-install-a-service-worker" class="hash-link" aria-label="Direct link to How to install a service worker?" title="Direct link to How to install a service worker?">​</a></h3>
<p>Installing a service worker is a multi-step process that involves registering the service worker file, and then having the service worker take control of a specific scope. Here is an example of how to install a service worker:</p>
<ul>
<li>
<p>Register the service worker: In your HTML file, you will need to register the service worker using the <code>navigator.serviceWorker.register()</code> method. This method takes the path to the service worker file as the first argument and an options object as the second argument. The scope property of the options object is used to specify the scope of the service worker.</p>
<div class="language-javascript codeBlockContainer_Dsm5 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent__qvQ"><pre tabindex="0" class="prism-code language-javascript codeBlock_TP_y thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_o52p"><span class="token-line" style="color:#393A34"><span class="token keyword control-flow" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"serviceWorker"</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">in</span><span class="token plain"> </span><span class="token dom variable" style="color:#36acaa">navigator</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token dom variable" style="color:#36acaa">navigator</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">serviceWorker</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">register</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/sw.js"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">scope</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"/"</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">then</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">registration</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Service worker registered: "</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> registration</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">scope</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">.</span><span class="token keyword control-flow" style="color:#00009f">catch</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">error</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Service worker registration failed: "</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> error</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre><div class="buttonGroup_pyGv"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_WfJE" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ImZj"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_OeyQ"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
</li>
<li>
<p>The service worker file: The service worker file is a JavaScript file that contains the code to run the service worker. It should contain at least the install and fetch event listeners, as well as any other code that is needed to implement the caching strategies, push notifications, etc.</p>
<div class="language-javascript codeBlockContainer_Dsm5 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent__qvQ"><pre tabindex="0" class="prism-code language-javascript codeBlock_TP_y thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_o52p"><span class="token-line" style="color:#393A34"><span class="token plain">self</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">addEventListener</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"install"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">event</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">//...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">self</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">addEventListener</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"fetch"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">event</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">//...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre><div class="buttonGroup_pyGv"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_WfJE" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ImZj"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_OeyQ"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
</li>
<li>
<p>Take control of the scope: Once the service worker is registered, it will start the installation process. The install event is fired and you can use it to cache the resources you need in order to make the web app work offline. Once the installation process is finished, the service worker will be in a "waiting" state. Once all the tabs of your web app are closed, the service worker will be activated and it will take control of the scope that you specified in the registration process.</p>
</li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_GVoy" id="caching-strategies-with-service-workers">Caching strategies with Service workers<a href="https://blog.0xniko.dev/2023/01/28/service-worker-caching-strategies#caching-strategies-with-service-workers" class="hash-link" aria-label="Direct link to Caching strategies with Service workers" title="Direct link to Caching strategies with Service workers">​</a></h2>
<h3 class="anchor anchorWithStickyNavbar_GVoy" id="1-stale-while-revalidate">1. Stale-while-revalidate<a href="https://blog.0xniko.dev/2023/01/28/service-worker-caching-strategies#1-stale-while-revalidate" class="hash-link" aria-label="Direct link to 1. Stale-while-revalidate" title="Direct link to 1. Stale-while-revalidate">​</a></h3>
<p><img decoding="async" loading="lazy" alt="Stale-while-revalidate" src="https://blog.0xniko.dev/assets/images/stale-while-revalidate-07df466683245ecc6c61e5b83bdf525a.avif" width="845" height="410" class="img_eDxn"></p>
<p><code>Stale-While-Revalidate</code> is a caching strategy that is commonly used with service workers. The idea behind this strategy is to serve a stale version of a resource from the cache while simultaneously checking for a newer version of the resource on the network. This strategy is particularly useful for resources that change frequently, such as API data.</p>
<p>Here's an example of how to implement the Stale-While-Revalidate strategy with a service worker:</p>
<div class="language-javascript codeBlockContainer_Dsm5 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent__qvQ"><pre tabindex="0" class="prism-code language-javascript codeBlock_TP_y thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_o52p"><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// Intercept fetch requests</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">self</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">addEventListener</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"fetch"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">event</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  event</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">respondWith</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    caches</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">open</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"my-cache"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">then</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">cache</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> cache</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">match</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">event</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">request</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">then</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">response</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> fetchPromise </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">fetch</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">event</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">request</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">then</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">networkResponse</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          cache</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">put</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">event</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">request</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> networkResponse</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">clone</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> networkResponse</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> response </span><span class="token operator" style="color:#393A34">||</span><span class="token plain"> fetchPromise</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre><div class="buttonGroup_pyGv"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_WfJE" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ImZj"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_OeyQ"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>In this example, the <code>fetch</code> event listener is used to intercept all network requests made by the web application. The <code>caches.match(event.request)</code> method is used to check if the requested resource is available in the cache. If it is, the cached version of the resource is returned immediately to the user and at the same time, the resource is requested again from the network using the <code>fetch()</code> method. Once the network request is finished, the new response is stored in the cache using the <code>cache.put(event.request, networkResponse.clone())</code> method and the next time the resource is requested, the updated version will be served.</p>
<p>It's important to note that the <code>Stale-While-Revalidate</code> strategy does not automatically update the cache when a new version of a resource is available on the network, but it ensures that stale resources will not be served to the user for too long.</p>
<h3 class="anchor anchorWithStickyNavbar_GVoy" id="2-cache-first">2. Cache-first<a href="https://blog.0xniko.dev/2023/01/28/service-worker-caching-strategies#2-cache-first" class="hash-link" aria-label="Direct link to 2. Cache-first" title="Direct link to 2. Cache-first">​</a></h3>
<p><img decoding="async" loading="lazy" alt="Cache first" src="https://blog.0xniko.dev/assets/images/cache-first-435b855441e18d0de2f0843691deab23.avif" width="845" height="417" class="img_eDxn"></p>
<p><code>Cache First</code> is a caching strategy that is commonly used with service workers. The idea behind this strategy is to serve resources from the cache whenever possible, and only fetch them from the network if they are not available in the cache. This strategy is particularly useful for resources that are not likely to change frequently, such as images or static files.</p>
<p>Example of how to implement the Cache First strategy with a service worker:</p>
<div class="language-javascript codeBlockContainer_Dsm5 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent__qvQ"><pre tabindex="0" class="prism-code language-javascript codeBlock_TP_y thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_o52p"><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// Install the service worker</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">self</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">addEventListener</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"install"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">event</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  event</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">waitUntil</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    caches</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">open</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"my-cache"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">then</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">cache</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> cache</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">addAll</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">[</span><span class="token string" style="color:#e3116c">"/css/styles.css"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"/js/main.js"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"/img/logo.jpg"</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// Intercept fetch requests</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">self</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">addEventListener</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"fetch"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">event</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  event</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">respondWith</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    caches</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">match</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">event</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">request</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">then</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">response</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token comment" style="color:#999988;font-style:italic">// If the resource is in the cache, return it</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token keyword control-flow" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">response</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> response</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token comment" style="color:#999988;font-style:italic">// Otherwise, fetch the resource from the network</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">fetch</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">event</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">request</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre><div class="buttonGroup_pyGv"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_WfJE" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ImZj"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_OeyQ"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>In this example, the service worker is first installed, and the <code>install</code> event listener is used to open a cache called "my-cache" and add all the resources that will be cached (CSS, JS, and image files).</p>
<p>The <code>fetch</code> event listener is then used to intercept all network requests made by the web application. The <code>caches.match(event.request)</code> method is used to check if the requested resource is available in the cache. If it is, the cached version of the resource is returned. If not, the resource is fetched from the network.</p>
<p>It's important to note that the Cache First strategy does not automatically update the cache when a new version of a resource is available on the network. If you want to update the cache with the latest version of a resource, you'll need to implement a separate mechanism to check for updates and update the cache accordingly.</p>
<p>In summary, the <code>Cache First</code> strategy is a simple yet powerful caching approach that allows you to serve resources from the cache whenever possible, reducing the number of network requests and improving the performance of your web application.</p>
<h3 class="anchor anchorWithStickyNavbar_GVoy" id="3-network-first">3. Network-first<a href="https://blog.0xniko.dev/2023/01/28/service-worker-caching-strategies#3-network-first" class="hash-link" aria-label="Direct link to 3. Network-first" title="Direct link to 3. Network-first">​</a></h3>
<p><img decoding="async" loading="lazy" alt="Cache first" src="https://blog.0xniko.dev/assets/images/network-first-278fef4a7ebda34384fec054845254fb.avif" width="845" height="410" class="img_eDxn"></p>
<p><code>Network first</code> is a caching strategy that prioritizes serving the most up-to-date version of a resource by first attempting to fetch it from the network, and then falling back to the cached version if the network request fails. This strategy is useful for resources that need to be as up-to-date as possible, such as real-time stock prices or live sports scores.</p>
<p>Here is an example of how to implement the network first strategy using a service worker:</p>
<div class="language-javascript codeBlockContainer_Dsm5 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent__qvQ"><pre tabindex="0" class="prism-code language-javascript codeBlock_TP_y thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_o52p"><span class="token-line" style="color:#393A34"><span class="token plain">self</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">addEventListener</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"fetch"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">event</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  event</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">respondWith</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">fetch</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">event</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">request</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">then</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">response</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token comment" style="color:#999988;font-style:italic">// If the request is successfull, update the cache and return the response</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        caches</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">open</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"my-cache"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">then</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">cache</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          cache</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">put</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">event</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">request</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> response</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">clone</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> response</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">.</span><span class="token keyword control-flow" style="color:#00009f">catch</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token comment" style="color:#999988;font-style:italic">// If the request fails, return the cached version of the resource</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> caches</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">match</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">event</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">request</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre><div class="buttonGroup_pyGv"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_WfJE" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ImZj"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_OeyQ"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>In this example, the service worker is listening for the fetch event and using the <code>fetch()</code> method to attempt to retrieve the requested resource from the network. If the request is successful, the response is cached using the <code>cache.put()</code> method and then returned to the browser. If the request fails, the service worker falls back to returning the cached version of the resource using the <code>caches.match()</code> method.</p>
<p>Please note that this is a basic example of how to implement the <code>Network first</code> strategy, for more complex scenario you may want to implement additional functionality such as handling errors and updating the cache.</p>
<h3 class="anchor anchorWithStickyNavbar_GVoy" id="4-network-only">4. Network-only<a href="https://blog.0xniko.dev/2023/01/28/service-worker-caching-strategies#4-network-only" class="hash-link" aria-label="Direct link to 4. Network-only" title="Direct link to 4. Network-only">​</a></h3>
<p><img decoding="async" loading="lazy" alt="Cache first" src="https://blog.0xniko.dev/assets/images/network-only-16c0a2df17e2d257b1c39eee39f77001.avif" width="845" height="288" class="img_eDxn"></p>
<p><code>Network only</code> is a caching strategy that only retrieves resources from the network and never serves them from the cache. This strategy is useful for resources that should never be cached, such as login pages or sensitive user data.</p>
<p>Here is an example of how to implement the <code>network only</code> strategy using a service worker:</p>
<div class="language-javascript codeBlockContainer_Dsm5 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent__qvQ"><pre tabindex="0" class="prism-code language-javascript codeBlock_TP_y thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_o52p"><span class="token-line" style="color:#393A34"><span class="token plain">self</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">addEventListener</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"fetch"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">event</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  event</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">respondWith</span><span class="token punctuation" style="color:#393A34">(</span><span class="token function" style="color:#d73a49">fetch</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">event</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">request</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre><div class="buttonGroup_pyGv"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_WfJE" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ImZj"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_OeyQ"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>In this example, the service worker is listening for the fetch event and using the <code>fetch()</code> method to retrieve the requested resource directly from the network. Since no caching is involved, the service worker will always serve the most up-to-date version of the resource.</p>
<p>It's important to note that if you are using the <code>Network only</code> strategy, you should also handle the case when there is no internet connection available.</p>
<div class="language-javascript codeBlockContainer_Dsm5 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent__qvQ"><pre tabindex="0" class="prism-code language-javascript codeBlock_TP_y thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_o52p"><span class="token-line" style="color:#393A34"><span class="token plain">self</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">addEventListener</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"fetch"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">event</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  event</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">respondWith</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">fetch</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">event</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">request</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token keyword control-flow" style="color:#00009f">catch</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">Response</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">"You are offline, please check your internet connection."</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre><div class="buttonGroup_pyGv"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_WfJE" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ImZj"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_OeyQ"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>In this example, if the network request fails, the service worker will return a response with a message indicating that the user is offline.</p>
<p>Please note that this is a basic example of how to implement the <code>Network only</code> strategy, for more complex scenario you may want to implement additional functionality such as handling errors and redirecting the user to a different page.</p>
<h3 class="anchor anchorWithStickyNavbar_GVoy" id="5-cache-only">5. Cache-only<a href="https://blog.0xniko.dev/2023/01/28/service-worker-caching-strategies#5-cache-only" class="hash-link" aria-label="Direct link to 5. Cache-only" title="Direct link to 5. Cache-only">​</a></h3>
<p><img decoding="async" loading="lazy" alt="Cache first" src="https://blog.0xniko.dev/assets/images/cache-only-981b86238400e16e3b51de8534f9a5c8.avif" width="845" height="287" class="img_eDxn"></p>
<p><code>Cache only</code> is a caching strategy that only serves resources from the cache and never retrieves them from the network. This strategy is useful for resources that don't change often and can be cached for a long time, such as images or static assets.</p>
<p>Here is an example of how to implement the <code>cache only</code> strategy using a service worker:</p>
<div class="language-javascript codeBlockContainer_Dsm5 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent__qvQ"><pre tabindex="0" class="prism-code language-javascript codeBlock_TP_y thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_o52p"><span class="token-line" style="color:#393A34"><span class="token plain">self</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">addEventListener</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"fetch"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">event</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  event</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">respondWith</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">caches</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">match</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">event</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">request</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre><div class="buttonGroup_pyGv"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_WfJE" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ImZj"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_OeyQ"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>In this example, the service worker is listening for the fetch event and using the <code>caches.match()</code> method to retrieve the requested resource from the cache. If the resource is not found in the cache, the browser will receive a response with a <code>status</code> of <code>undefined</code>, which means that the resource is not available.</p>
<p>It's important to note that if you are using the <code>Cache only</code> strategy, you should pre-cache the resources that you want to be available offline.</p>
<div class="language-javascript codeBlockContainer_Dsm5 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent__qvQ"><pre tabindex="0" class="prism-code language-javascript codeBlock_TP_y thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_o52p"><span class="token-line" style="color:#393A34"><span class="token plain">self</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">addEventListener</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"install"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">event</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  event</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">waitUntil</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    caches</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">open</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"my-cache"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">then</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">cache</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> cache</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">addAll</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">"/styles/main.css"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">"/scripts/main.js"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">"/images/logo.jpg"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre><div class="buttonGroup_pyGv"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_WfJE" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ImZj"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_OeyQ"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>In this example, the service worker is listening for the install event, and using the <code>caches.open()</code> method to open the cache and the <code>cache.addAll()</code> method to add the resources that should be available offline.</p>
<p>Please note that this is a basic example of how to implement the <code>Cache only</code> strategy, for more complex scenario you may want to implement additional functionality such as handling errors and updating the cache.</p>
<h2 class="anchor anchorWithStickyNavbar_GVoy" id="summary">Summary<a href="https://blog.0xniko.dev/2023/01/28/service-worker-caching-strategies#summary" class="hash-link" aria-label="Direct link to Summary" title="Direct link to Summary">​</a></h2>
<p>Service workers are a powerful tool for handling caching in web applications. They allow you to control how resources are retrieved and served to the browser, even when the user is offline.
Each of these strategies have their own use cases, and it's important to choose the right one for your application.</p>
<p>It's also important to note that service workers can be used for other purposes than caching such as push notifications, background sync, and more.</p>
<h2 class="anchor anchorWithStickyNavbar_GVoy" id="references">References<a href="https://blog.0xniko.dev/2023/01/28/service-worker-caching-strategies#references" class="hash-link" aria-label="Direct link to References" title="Direct link to References">​</a></h2>
<ul>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API/Using_Service_Workers" target="_blank" rel="noopener noreferrer">Service Workers</a></li>
<li><a href="https://developer.chrome.com/docs/workbox/modules/workbox-strategies/" target="_blank" rel="noopener noreferrer">Workbox-strategies</a></li>
</ul>]]></content>
        <author>
            <name>Niko</name>
            <uri>https://0xniko.dev</uri>
        </author>
        <category label="javascript" term="javascript"/>
        <category label="service worker" term="service worker"/>
        <category label="sw" term="sw"/>
        <category label="workbox" term="workbox"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Javascript series - Understanding array Map and Reduce]]></title>
        <id>https://blog.0xniko.dev/2023/01/27/array-map-reduce-with-javascript</id>
        <link href="https://blog.0xniko.dev/2023/01/27/array-map-reduce-with-javascript"/>
        <updated>2023-01-27T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Understanding Map and Reduce These Powerful Array Methods in JavaScript]]></summary>
        <content type="html"><![CDATA[<p>JavaScript provides a number of built-in array methods that can be used to manipulate arrays in a variety of ways. Two of the most powerful and commonly used methods are <code>map</code> and <code>reduce</code>. In this section, we will explore what these methods do, and how to use them to perform complex operations on arrays of data in JavaScript.</p>
<div class="theme-admonition theme-admonition-tip admonition_SLCK alert alert--success"><div class="admonitionHeading_VYlH"><span class="admonitionIcon_TaVW"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>tip</div><div class="admonitionContent_HP_r"><blockquote>
<p>Map and Reduce: Understanding and Implementing These Powerful Array Methods in JavaScript</p>
</blockquote></div></div>
<h2 class="anchor anchorWithStickyNavbar_GVoy" id="array-map-method">Array <code>map</code> method<a href="https://blog.0xniko.dev/2023/01/27/array-map-reduce-with-javascript#array-map-method" class="hash-link" aria-label="Direct link to array-map-method" title="Direct link to array-map-method">​</a></h2>
<p>The <code>map</code> method is used to create a new array that is the result of applying a given function to each element of the original array. The basic syntax for using the <code>map</code> method is as follows:</p>
<div class="language-javascript codeBlockContainer_Dsm5 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent__qvQ"><pre tabindex="0" class="prism-code language-javascript codeBlock_TP_y thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_o52p"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> newArray </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> oldArray</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">map</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">element</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> index</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> array</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// Function to apply to each element</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre><div class="buttonGroup_pyGv"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_WfJE" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ImZj"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_OeyQ"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>Example of using the <code>map</code> method to square each element of an array:</p>
<div class="language-javascript codeBlockContainer_Dsm5 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent__qvQ"><pre tabindex="0" class="prism-code language-javascript codeBlock_TP_y thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_o52p"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> numbers </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">2</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">3</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">4</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">5</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> squares </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> numbers</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">map</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">x</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> x </span><span class="token operator" style="color:#393A34">*</span><span class="token plain"> x</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">squares</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// [1, 4, 9, 16, 25]</span><br></span></code></pre><div class="buttonGroup_pyGv"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_WfJE" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ImZj"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_OeyQ"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h2 class="anchor anchorWithStickyNavbar_GVoy" id="array-reduce-method">Array <code>reduce</code> method<a href="https://blog.0xniko.dev/2023/01/27/array-map-reduce-with-javascript#array-reduce-method" class="hash-link" aria-label="Direct link to array-reduce-method" title="Direct link to array-reduce-method">​</a></h2>
<p>The <code>reduce</code> method is used to reduce an array to a single value by applying a given function to each element of the array, and accumulating the result. The basic syntax for using the <code>reduce</code> method is as follows:</p>
<div class="language-javascript codeBlockContainer_Dsm5 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent__qvQ"><pre tabindex="0" class="prism-code language-javascript codeBlock_TP_y thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_o52p"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> result </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> array</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">reduce</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">accumulator</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> element</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> index</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> array</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// Function to apply to each element</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> initialValue</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre><div class="buttonGroup_pyGv"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_WfJE" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ImZj"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_OeyQ"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>Example of using the reduce method to sum the elements of an array:</p>
<div class="language-javascript codeBlockContainer_Dsm5 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent__qvQ"><pre tabindex="0" class="prism-code language-javascript codeBlock_TP_y thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_o52p"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> numbers </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">2</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">3</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">4</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">5</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> sum </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> numbers</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">reduce</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">a</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> b</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> a </span><span class="token operator" style="color:#393A34">+</span><span class="token plain"> b</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">sum</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// 15</span><br></span></code></pre><div class="buttonGroup_pyGv"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_WfJE" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ImZj"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_OeyQ"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>It is worth noting that the <code>reduce</code> method can also be used to perform more complex operations on arrays, such as counting the occurrences of elements, grouping elements by a certain property, or flattening a nested array.</p>
<h2 class="anchor anchorWithStickyNavbar_GVoy" id="summary">Summary<a href="https://blog.0xniko.dev/2023/01/27/array-map-reduce-with-javascript#summary" class="hash-link" aria-label="Direct link to Summary" title="Direct link to Summary">​</a></h2>
<p>In conclusion, <code>map</code> and <code>reduce</code> are two powerful array methods in JavaScript that enable developers to perform complex operations on arrays of data. By using these methods, developers can write more readable and performant code, and avoid having to write long and complex loops. It's always good to keep in mind that they are not the only method to do something and there are other alternatives. But the map and reduce method are great tools to have in your toolbox.</p>
<h2 class="anchor anchorWithStickyNavbar_GVoy" id="references">References<a href="https://blog.0xniko.dev/2023/01/27/array-map-reduce-with-javascript#references" class="hash-link" aria-label="Direct link to References" title="Direct link to References">​</a></h2>
<ul>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map" target="_blank" rel="noopener noreferrer">Array map</a></li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce" target="_blank" rel="noopener noreferrer">Array reduce</a></li>
</ul>]]></content>
        <author>
            <name>Niko</name>
            <uri>https://0xniko.dev</uri>
        </author>
        <category label="javascript" term="javascript"/>
        <category label="array" term="array"/>
        <category label="map" term="map"/>
        <category label="reduce" term="reduce"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Microservice monitoring - Distributed Tracing]]></title>
        <id>https://blog.0xniko.dev/2021/06/18/microservice-monitoring-distributed-tracing</id>
        <link href="https://blog.0xniko.dev/2021/06/18/microservice-monitoring-distributed-tracing"/>
        <updated>2021-06-18T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Monitoring containerized microservices with distributed tracing.]]></summary>
        <content type="html"><![CDATA[<p><a href="https://blog.0xniko.dev/assets/files/distributed-trace-diagram-5cfef08d5756002ad70592e842ad5aa6.png" target="_blank"><img decoding="async" loading="lazy" alt="distributed-trace-diagram.png" src="https://blog.0xniko.dev/assets/images/distributed-trace-diagram-5cfef08d5756002ad70592e842ad5aa6.png" width="1200" height="633" class="img_eDxn"></a></p>
<h2 class="anchor anchorWithStickyNavbar_GVoy" id="what-is-distributed-tracing">What is Distributed Tracing?<a href="https://blog.0xniko.dev/2021/06/18/microservice-monitoring-distributed-tracing#what-is-distributed-tracing" class="hash-link" aria-label="Direct link to What is Distributed Tracing?" title="Direct link to What is Distributed Tracing?">​</a></h2>
<p>Distributed tracing, also called distributed request tracing, is a method used to profile and monitor applications, especially those built using a microservices architecture. Distributed tracing helps pinpoint where failures occur and what causes poor performance.</p>
<p>Distributed tracing is the capability for a tracing solution to track and observe service requests as they flow through distributed systems by collecting data as the requests go from one service to another. The trace data helps you understand the flow of requests through your microservices environment and pinpoint where failures or performance issues are occurring in the system—and why.</p>
<p>For instance, a request might pass through multiple services and traverse back and forth through various microservices to reach completion. The microservices or functions could be located in multiple containers, serverless environments, virtual machines, different cloud providers, on-premises, or any combination of these.</p>
<h2 class="anchor anchorWithStickyNavbar_GVoy" id="who-uses-distributed-tracing">Who Uses Distributed Tracing?<a href="https://blog.0xniko.dev/2021/06/18/microservice-monitoring-distributed-tracing#who-uses-distributed-tracing" class="hash-link" aria-label="Direct link to Who Uses Distributed Tracing?" title="Direct link to Who Uses Distributed Tracing?">​</a></h2>
<p>IT and DevOps teams can use distributed tracing to monitor applications. Distributed tracing is particularly well-suited to debugging and monitoring modern distributed software architectures, such as microservices.</p>
<p>Developers can use distributed tracing to help debug and optimize their code.</p>
<h2 class="anchor anchorWithStickyNavbar_GVoy" id="why-does-your-business-need-distributed-tracing">Why Does Your Business Need Distributed Tracing?<a href="https://blog.0xniko.dev/2021/06/18/microservice-monitoring-distributed-tracing#why-does-your-business-need-distributed-tracing" class="hash-link" aria-label="Direct link to Why Does Your Business Need Distributed Tracing?" title="Direct link to Why Does Your Business Need Distributed Tracing?">​</a></h2>
<p>As new technologies and practices— cloud, microservices, containers, serverless functions, DevOps, site reliability engineering (SRE), and more—increase velocity and reduce the friction of getting software from code to production, they also introduce new challenges:</p>
<ul>
<li>More points of failure within the application stack</li>
<li>Increased mean time to resolution (MTTR) due to the complexity of the application environment</li>
<li>Less time to innovate because more time is needed to diagnose problems</li>
</ul>
<p>For example, a slow-running request might be impacting the experience of a set of customers. That request is distributed across multiple microservices and serverless functions. Several different teams own and monitor the various services that are involved in the request, and none have reported any performance issues with their microservices. Without a way to view the performance of the entire request across the different services, it’s nearly impossible to pinpoint where and why the high latency is occurring and which team should address the issue.</p>
<p>As part of an end-to-end observability strategy, distributed tracing addresses the challenges of modern application environments. By deeply understanding the performance of every service—both upstream and downstream—your software teams can more effectively and quickly:</p>
<ul>
<li>Identify and resolve issues to minimize the impact on the customer experience and business outcomes</li>
<li>Measure overall system health and understand the effect of changes on the customer experience</li>
<li>Prioritize high-value areas for improvement to optimize digital customer experiences</li>
<li>Innovate continuously with confidence to outperform the competition</li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_GVoy" id="how-does-distributed-tracing-work">How Does Distributed Tracing Work?<a href="https://blog.0xniko.dev/2021/06/18/microservice-monitoring-distributed-tracing#how-does-distributed-tracing-work" class="hash-link" aria-label="Direct link to How Does Distributed Tracing Work?" title="Direct link to How Does Distributed Tracing Work?">​</a></h2>
<p>Distributed tracing starts with instrumenting your environment to enable data collection and correlation across the entire distributed system. After the data is collected, correlated, and analyzed, you can visualize it to see service dependencies, performance, and any anomalous events such as errors or unusual latency.</p>
<h3 class="anchor anchorWithStickyNavbar_GVoy" id="instrumentation">Instrumentation<a href="https://blog.0xniko.dev/2021/06/18/microservice-monitoring-distributed-tracing#instrumentation" class="hash-link" aria-label="Direct link to Instrumentation" title="Direct link to Instrumentation">​</a></h3>
<p>Instrumenting your microservices environment means adding code to services to monitor and track trace data. You can also use open source tools and open instrumentation standards to instrument your environment. OpenTelemetry, part of the Cloud Native Computing Foundation (CNCF), is becoming the one standard for open source instrumentation and telemetry collection. Projects such as OpenCensus and Zipkin are also well established in the open source community. Some service meshes, such as Istio, also emit trace telemetry data.</p>
<h3 class="anchor anchorWithStickyNavbar_GVoy" id="trace-context">Trace context<a href="https://blog.0xniko.dev/2021/06/18/microservice-monitoring-distributed-tracing#trace-context" class="hash-link" aria-label="Direct link to Trace context" title="Direct link to Trace context">​</a></h3>
<p>To make the trace identifiable across all the different components in your applications and systems, distributed tracing requires trace context. This means assigning a unique ID to each request, assigning a unique ID to each step in a trace, encoding this contextual information, and passing (or propagating) the encoded context from one service to the next as the request makes its way through an application environment. This lets your distributed tracing tool correlate each step of a trace, in the correct order, along with other necessary information to monitor and track performance.</p>
<p><strong><a href="https://www.w3.org/TR/trace-context" target="_blank" rel="noopener noreferrer">W3C Trace Context</a></strong> is becoming the standard for propagating trace context across process boundaries. It lets all tracers and agents that conform to the standard participate in a trace, with trace data propagated from the root service all the way to the terminal service. New Relic supports the W3C Trace Context standard for distributed tracing.</p>
<p><a href="https://blog.0xniko.dev/assets/files/span_contenxt-321597f7fe97aac0f2eab13187c694d1.PNG" target="_blank"><img decoding="async" loading="lazy" alt="span_contenxt.PNG" src="https://blog.0xniko.dev/assets/images/span_contenxt-321597f7fe97aac0f2eab13187c694d1.PNG" width="834" height="429" class="img_eDxn"></a></p>
<p>The diagram in Figure 1 represents a sample trace. A trace is a collection of linked spans, which are named and timed operations that represent a unit of work in the request. A span that isn’t the child of any other span is the parent span, or root span, of the trace. The root span describes the end-to-end latency of the entire trace, with child spans representing sub-operations.</p>
<p>To put this in more concrete terms, consider the request flow of a system that you might encounter in the real world, a ridesharing app. When a user requests a ride, multiple actions begin to take place –– information is passed between services in order to authenticate and authorize the user, validate payment information, locate nearby drivers, and dispatch one of them to pick up the rider.</p>
<p>A simplified diagram of this system, and a trace of a request through it, appears in the following figure. As you can see, each operation generates a span to represent the work being done during its execution. These spans have implicit relationships (parent-child) both from the beginning of the entire request at the client, but also from individual services in the trace. Traces are composable in this way: a valid trace consists of valid sub-traces.</p>
<p><a href="https://blog.0xniko.dev/assets/files/logical_diagram-24cae5676c96585f6277e2cac0fc5094.PNG" target="_blank"><img decoding="async" loading="lazy" alt="logical_diagram.PNG" src="https://blog.0xniko.dev/assets/images/logical_diagram-24cae5676c96585f6277e2cac0fc5094.PNG" width="755" height="429" class="img_eDxn"></a>
<a href="https://blog.0xniko.dev/assets/files/service_traces-088497297f2c37cc334449c28d77b81b.PNG" target="_blank"><img decoding="async" loading="lazy" alt="service_traces.PNG" src="https://blog.0xniko.dev/assets/images/service_traces-088497297f2c37cc334449c28d77b81b.PNG" width="754" height="366" class="img_eDxn"></a></p>
<h3 class="anchor anchorWithStickyNavbar_GVoy" id="tracing-spans">Tracing spans<a href="https://blog.0xniko.dev/2021/06/18/microservice-monitoring-distributed-tracing#tracing-spans" class="hash-link" aria-label="Direct link to Tracing spans" title="Direct link to Tracing spans">​</a></h3>
<p><a href="https://blog.0xniko.dev/assets/files/spans-traces-a6ab430e4c996d4c0f4a24a5ce6b3100.png" target="_blank"><img decoding="async" loading="lazy" alt="distributed-trace.png" src="https://blog.0xniko.dev/assets/images/spans-traces-a6ab430e4c996d4c0f4a24a5ce6b3100.png" width="960" height="540" class="img_eDxn"></a></p>
<p>To clear about spans context, we using OpenTelemetry for this explain.</p>
<p>Each span in OpenTelemetry encapsulates several pieces of information, such as the name of the operation it represents, a start and end timestamp, events and attributes that occurred during the span, links to other spans, and the status of the operation. In Figure 1, the dashed lines connecting spans represent the context of the trace. The context (or trace context) contains several pieces of information that can be passed between functions inside a process or between processes over an RPC. In addition to the span context, identifiers that represent the parent trace and span, the context can contain other information about the process or request, like custom labels. As mentioned before, an important feature of spans is that they are able to encapsulate a host of information. Much of this information, such as the operation name and start/stop timestamps, is required — but some is optional. OpenTelemetry offers two data types, Attribute and Event, which are incredibly valuable as they help to contextualize what happens during the execution measured by a single span.</p>
<p>Attributes are key-value pairs that can be freely added to a span to help in analysis of the trace data. You can think of Attributes as data that you would like to eventually aggregate or use to filter your trace data, such as a customer identifier, process hostname, or anything else that fits your tracing needs. Events are time-stamped strings that can be attached to a span, with an optional set of Attributes that provide further description. OpenTelemetry additionally provides a set of semantic conventions of reserved attributes and events for operation or protocol specific information. Spans in OpenTelemetry are generated by the Tracer, an object that tracks the currently active span and allows you to create (or activate) new spans.</p>
<p>Tracer objects are configured with Propagator objects that support transferring the context across process boundaries. The exact mechanism for creating and registering a Tracer is dependent on your implementation and language, but you can generally expect there to be a global Tracer capable of providing a default tracer for your spans, and/or a Tracer provider capable of granting access to the tracer for your component. As spans are created and completed, the Tracer dispatches them to the OpenTelemetry SDK’s Exporter, which is responsible for sending your spans to a backend system for analysis.</p>
<h3 class="anchor anchorWithStickyNavbar_GVoy" id="tracing-metrics">Tracing metrics<a href="https://blog.0xniko.dev/2021/06/18/microservice-monitoring-distributed-tracing#tracing-metrics" class="hash-link" aria-label="Direct link to Tracing metrics" title="Direct link to Tracing metrics">​</a></h3>
<p>A single trace typically captures data about:</p>
<ul>
<li>Spans (service name, operation name, duration, and other metadata)</li>
<li>Errors</li>
<li>Duration of important operations within each service (such as internal method calls and functions)</li>
<li>Custom attributes</li>
</ul>
<h3 class="anchor anchorWithStickyNavbar_GVoy" id="analysis-and-visualization">Analysis and visualization<a href="https://blog.0xniko.dev/2021/06/18/microservice-monitoring-distributed-tracing#analysis-and-visualization" class="hash-link" aria-label="Direct link to Analysis and visualization" title="Direct link to Analysis and visualization">​</a></h3>
<p>Collecting trace data would be wasted if software teams didn’t have an easy way to analyze and visualize the data across complex architectures. A comprehensive observability platform allows your teams to see all of their telemetry and business data in one place. It also provides the context they need to quickly derive meaning and take the right action, and work with the data in ways that are meaningful to you and your business.</p>
<p>Popular analysis and visualization tools such as: ELK stack with Open distro, Jeager, Zipkin, ...</p>
<h2 class="anchor anchorWithStickyNavbar_GVoy" id="what-are-the-open-distributed-tracing-standards-opentracing-opencensus-opentelemetry">What are the open distributed tracing standards (OpenTracing, OpenCensus, OpenTelemetry)?<a href="https://blog.0xniko.dev/2021/06/18/microservice-monitoring-distributed-tracing#what-are-the-open-distributed-tracing-standards-opentracing-opencensus-opentelemetry" class="hash-link" aria-label="Direct link to What are the open distributed tracing standards (OpenTracing, OpenCensus, OpenTelemetry)?" title="Direct link to What are the open distributed tracing standards (OpenTracing, OpenCensus, OpenTelemetry)?">​</a></h2>
<p>OpenTracing and OpenCensus competed as open source distributed tracing projects that were recently merged into a single tool called Open Telemetry.</p>
<p>Hosted by the Cloud Native Computing Foundation (CNCF), OpenTracing attempts to provide a standardized API for tracing, enable developers to embed instrumentation in commonly used libraries or their own custom code without vendor lock-in. Though this provided much-desired flexibility, the API’s sole focus on tracing made it of limited use on its own and led to inconsistent implementations by developers and vendors.</p>
<p>OpenCensus was developed at Google and was based on its internal tracing platform. Once it was open sourced, Microsoft, along with other vendors and contributors, began directing the standard. OpenCensus is a set of multi-language libraries that collects metrics about application behavior, transferring that data to any backend analysis platform of the developer’s choosing. It can also trace messages, requests, and services from their source to their destinations. With no API available to embed OpenCensus into code, developers used community-built automatic instrumentation agents for the task.</p>
<p>Open Telemetry, which is managed by CNCF, merges the code bases of OpenTracing and OpenCensus, relying on the strengths of each. Currently in beta, OpenTelemetry offers “a single set of APIs, libraries, agents, and collector services” for capturing distributed traces and metrics from an application that can be analyzed using popular observability tools. In the near future, OpenTelemetry will add logging capability to its data capture support.</p>
<h3 class="anchor anchorWithStickyNavbar_GVoy" id="what-is-jaeger-or-zipkin-tracing">What is Jaeger or Zipkin tracing?<a href="https://blog.0xniko.dev/2021/06/18/microservice-monitoring-distributed-tracing#what-is-jaeger-or-zipkin-tracing" class="hash-link" aria-label="Direct link to What is Jaeger or Zipkin tracing?" title="Direct link to What is Jaeger or Zipkin tracing?">​</a></h3>
<p>Jaeger and Zipkin are two popular open-source request tracing tools, each with similar components: a collector, datastore, query API, and web user interface. Outgoing requests are traced along with the application. The collector then records and correlates the data between different traces and sends it to a database where it can be queried and analyzed through the UI.</p>
<p>Jaegar and Zipkin are differentiated by their architecture and programming language support — Jaeger is implemented in Go and Zipkin in Java. Zipkin supports virtually every programming language with dedicated libraries for Java, Javascript, C, C++, C#, Python, Go, Scala, and others. Jaeger’s supported-language list is shorter: C#, Java, Node.js, Python, and Go.</p>
<h3 class="anchor anchorWithStickyNavbar_GVoy" id="what-is-a-log-in-kafka">What is a log in Kafka?<a href="https://blog.0xniko.dev/2021/06/18/microservice-monitoring-distributed-tracing#what-is-a-log-in-kafka" class="hash-link" aria-label="Direct link to What is a log in Kafka?" title="Direct link to What is a log in Kafka?">​</a></h3>
<p>Kafka is a distributed streaming platform, providing a high-throughput, low-latency platform for handling real-time data feeds, often used in microservice architectures. It’s used to process streams of records in real time, publish and subscribe to those record streams in a manner similar to a message queue, and store them in a “fault-tolerant durable way.”</p>
<p>Kafka uses “topics” — a category or feed name to which records are published — to abstract streams of records. For each topic, Kafka maintains a partitioned log, an ordered, continually appended sequence of records that can serve as an external commit log for a distributed system.</p>
<h3 class="anchor anchorWithStickyNavbar_GVoy" id="open-distro-for-tracing-with-elk-stack">Open distro for tracing with ELK stack<a href="https://blog.0xniko.dev/2021/06/18/microservice-monitoring-distributed-tracing#open-distro-for-tracing-with-elk-stack" class="hash-link" aria-label="Direct link to Open distro for tracing with ELK stack" title="Direct link to Open distro for tracing with ELK stack">​</a></h3>
<p><a href="https://blog.0xniko.dev/assets/files/ta-kibana-trace-5f678216735e55a05c44cee9489310e0.png" target="_blank"><img decoding="async" loading="lazy" alt="distributed-trace.png" src="https://blog.0xniko.dev/assets/images/ta-kibana-trace-5f678216735e55a05c44cee9489310e0.png" width="2168" height="1330" class="img_eDxn"></a></p>
<p>Trace Analytics provides a way to ingest and visualize OpenTelemetry data in Open Distro for Elasticsearch. This data can help you find and fix performance problems in distributed applications.</p>
<p>A single operation, such as a user clicking a button, can trigger an extended series of events. The front end might call a back end service, which calls another service, which queries a database, processes the data, and sends it to the original service, which sends a confirmation to the front end.</p>
<p>Trace Analytics can help you visualize this flow of events and identify performance problems.</p>
<p>More details: <a href="https://opendistro.github.io/for-elasticsearch-docs/docs/trace/" target="_blank" rel="noopener noreferrer">https://opendistro.github.io/for-elasticsearch-docs/docs/trace/</a></p>
<p><strong><em>References:</em></strong></p>
<ul>
<li><em><a href="https://opendistro.github.io/for-elasticsearch-docs/docs/trace/" target="_blank" rel="noopener noreferrer">https://opendistro.github.io/for-elasticsearch-docs/docs/trace/</a></em></li>
<li><em><a href="https://newrelic.com/resources/ebooks/quick-introduction-distributed-tracing" target="_blank" rel="noopener noreferrer">https://newrelic.com/resources/ebooks/quick-introduction-distributed-tracing</a></em></li>
<li><em><a href="https://opentracing.io/docs/overview/what-is-tracing/" target="_blank" rel="noopener noreferrer">https://opentracing.io/docs/overview/what-is-tracing/</a></em></li>
</ul>]]></content>
        <author>
            <name>Niko</name>
            <uri>https://0xniko.dev</uri>
        </author>
        <category label="microservices" term="microservices"/>
        <category label="microservice" term="microservice"/>
        <category label="logs" term="logs"/>
        <category label="logging" term="logging"/>
        <category label="traces" term="traces"/>
        <category label="tracing" term="tracing"/>
        <category label="monitors" term="monitors"/>
        <category label="monitoing" term="monitoing"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Microservice monitoring - Application Logs]]></title>
        <id>https://blog.0xniko.dev/2020/10/31/microservice-monitoring-application-logs</id>
        <link href="https://blog.0xniko.dev/2020/10/31/microservice-monitoring-application-logs"/>
        <updated>2020-10-31T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Monitoring containerized microservices with application logs.]]></summary>
        <content type="html"><![CDATA[<h2 class="anchor anchorWithStickyNavbar_GVoy" id="correlate-requests-with-a-unique-id">Correlate Requests With a Unique ID<a href="https://blog.0xniko.dev/2020/10/31/microservice-monitoring-application-logs#correlate-requests-with-a-unique-id" class="hash-link" aria-label="Direct link to Correlate Requests With a Unique ID" title="Direct link to Correlate Requests With a Unique ID">​</a></h2>
<p>Think back to the request calling chain between Services A, B, and C that I talked about in the previous section. Following from this idea, it's a good practice to tag each call with a unique ID that identifies the request.</p>
<p>For example, let's say you're logging access and error logs for each service. If you find an error in Service B, it might be useful for you to know whether the error was caused by the request coming from Service A or the request sent to Service C.</p>
<p>Maybe the error is informative enough that you don't even need to reproduce it. But if that isn't the case, the correct way to reproduce the error is to know all possible requests in the services that are related to, say, Service B. When you have a correlation request ID, then you only need to look for that ID in the logs. And you'll get all logs from services that were part of the main request to the system. You'll also know which service the main request spends the most time in, if the service is using the cache, if a service is calling other services more than once, and a lot of other interesting details.</p>
<h2 class="anchor anchorWithStickyNavbar_GVoy" id="send-logs-to-a-centralized-location">Send Logs to a Centralized Location<a href="https://blog.0xniko.dev/2020/10/31/microservice-monitoring-application-logs#send-logs-to-a-centralized-location" class="hash-link" aria-label="Direct link to Send Logs to a Centralized Location" title="Direct link to Send Logs to a Centralized Location">​</a></h2>
<p>Let's assume that you're already adding all sorts of useful information to your logs. But it's essential to send logs to a centralized location.</p>
<p>Think about it. If you have to log in to each individual server to read logs, you'll spend more time trying to correlate problems than if you just had one location where you could access all logs. Also, systems usually get more complicated as time goes by, so the amount of microservices usually grows too. And to make things even more complicated, services could be hosted on different servers or providers.</p>
<p>Centralized logging is becoming the norm, especially if you're working with cloud, container, or hybrid environments because the servers could be terminated without any notice. For example, containers are terminated if there's an unexpected error, or the memory reaches 100 percent of its consumption capacity.</p>
<p>You could solve this problem by having agents pulling and pushing logs every five minutes or before servers get terminated. You could also configure a cronjob in the server, a sidecar container, or a shared file location where another process could centralize logs. Avoid the temptation of building a solution stack by yourself, aswhere to centralize logging is a well-known problem that's already solved.</p>
<p>Having logs from all of your services in one place makes it easy and efficient to correlate problems.</p>
<h3 class="anchor anchorWithStickyNavbar_GVoy" id="make-sure-log-aggregation-is-truly-centralized">Make sure log aggregation is truly centralized<a href="https://blog.0xniko.dev/2020/10/31/microservice-monitoring-application-logs#make-sure-log-aggregation-is-truly-centralized" class="hash-link" aria-label="Direct link to Make sure log aggregation is truly centralized" title="Direct link to Make sure log aggregation is truly centralized">​</a></h3>
<p>It’s not enough to aggregate some log data into one place (such as a public cloud vendor’s log manager, like CloudWatch) and aggregate other data somewhere else (like a third-party log management tool). Although this approach may seem like the way to go if some microservices run in one location and others run somewhere else, you need all of your log data in a single location if you want to analyze and store it effectively.</p>
<h3 class="anchor anchorWithStickyNavbar_GVoy" id="structure-your-log-data">Structure Your Log Data<a href="https://blog.0xniko.dev/2020/10/31/microservice-monitoring-application-logs#structure-your-log-data" class="hash-link" aria-label="Direct link to Structure Your Log Data" title="Direct link to Structure Your Log Data">​</a></h3>
<p>It's going to be almost impossible to have a defined format for log data; some logs might need more fields than others, and those that don't need all those excess fields will be wasting bytes. Microservice architecture addresses this issue by using different technology stacks, which impacts the log format of each service. One service might use a comma to separate fields, while others use pipes or spaces.</p>
<p>All of this can get pretty complicated. Make the process of parsing logs simpler by structuring your log data into a standard format like JavaScript Object Notation (JSON). JSON allows you to have multiple levels for your data so that, when necessary, you can get more semantic info in a single log event.</p>
<p>Parsing is also more straightforward than dealing with particular log formats. With structured data, the format of logs is standard, even though logs could have different fields. You'll also be able to create searches in the centralized location like looking for logs that have an "http_code" of 500 and above. Use structured logging to have a standard but flexible format in your microservices logs.</p>
<h3 class="anchor anchorWithStickyNavbar_GVoy" id="add-context-to-every-request">Add Context to Every Request<a href="https://blog.0xniko.dev/2020/10/31/microservice-monitoring-application-logs#add-context-to-every-request" class="hash-link" aria-label="Direct link to Add Context to Every Request" title="Direct link to Add Context to Every Request">​</a></h3>
<p>I don't know about you, but when something goes wrong, I want to know everything! Having enough information about an issue provides you with important context for the request. Knowing what could have caused the problem is essential, and having the right context will help you to understand what's happening more quickly. But adding context to logs could become a repetitive task in code because there's going to be common data like date and time that you'll need in each log event. So in code, logging will look simpler because you'll only be logging the message and other unique areas.</p>
<p>You might want to log all the data you can get. But let me give you some specific fields that could help you figure out what you really need to log.</p>
<ul>
<li>Date and time. It doesn't have to be UTC as long as the timezone is the same for everyone that needs to look at the logs.</li>
<li>Stack errors. You could pass the exception object as a parameter to the logging library.</li>
<li>The service name or code, so that you can differentiate which logs are from which microservice.</li>
<li>The function, class, or file name where the error occurred so that you don't have to guess where the problem is.</li>
<li>External service interaction names-you'll know which call to the DB was the one with the problem.</li>
<li>The IP address of the server and client request. This information will make it easy to spot an unhealthy server or identify a DDoS attack.</li>
<li>User-agent of the application so that you know which browsers or users are having issues.</li>
<li>HTTP code to get more semantics of the error. These codes will be useful to create alerts.</li>
<li>Contextualizing the request with logs will save you time when you need to troubleshoot problems in the system.</li>
</ul>
<h3 class="anchor anchorWithStickyNavbar_GVoy" id="collect-logs-to-persistent-storage">Collect Logs to Persistent Storage<a href="https://blog.0xniko.dev/2020/10/31/microservice-monitoring-application-logs#collect-logs-to-persistent-storage" class="hash-link" aria-label="Direct link to Collect Logs to Persistent Storage" title="Direct link to Collect Logs to Persistent Storage">​</a></h3>
<p>As noted above, microservices often run inside infrastructure—like a container—that lacks persistent storage. A basic and essential best practice in that case is to ensure that log data is written to somewhere where it will be stored persistently and remain available if the container shuts down.</p>
<p>You could do this by modifying source code or your container configurations to ensure that the logs are written to an external storage volume. An easier approach, however, is to run a logging agent that will collect data from the containerized microservice in real time and aggregate it within a reliable storage location.</p>
<p>This way, you kill two birds with one stone (or logging agent, as it were): You aggregate logs and move log data to persistent storage, all in one step.</p>
<h3 class="anchor anchorWithStickyNavbar_GVoy" id="log-useful-and-meaningful-data-to-avoid-regret">Log Useful and Meaningful Data to Avoid Regret<a href="https://blog.0xniko.dev/2020/10/31/microservice-monitoring-application-logs#log-useful-and-meaningful-data-to-avoid-regret" class="hash-link" aria-label="Direct link to Log Useful and Meaningful Data to Avoid Regret" title="Direct link to Log Useful and Meaningful Data to Avoid Regret">​</a></h3>
<p>These are just some ordinary things that help you log microservices. If you're just starting out with logging, these practices might not make much sense and seem useless. But once you've been using microservices for a while, they'll save you a lot of trouble. Just make sure you're always evaluating what you're logging. You'll have a better idea of what's important to log when you're troubleshooting and say to yourself "I wish I had X and Y information so I could spot these weird errors more easily."</p>
<p>Once you're logging enough data, it's time to automate things like alerts. You shouldn't have to spend a ton of time reading logs to spot problems. Automating alerts will also help you to be proactive and keep errors from spreading to all of your users.</p>
<p>Having a centralized logging location to make further analysis is a must in microservices. Adding enough context to logs will make the difference in identifying what log data is useful, and what data is useless.</p>
<h2 class="anchor anchorWithStickyNavbar_GVoy" id="logs-aggregations">Logs aggregations<a href="https://blog.0xniko.dev/2020/10/31/microservice-monitoring-application-logs#logs-aggregations" class="hash-link" aria-label="Direct link to Logs aggregations" title="Direct link to Logs aggregations">​</a></h2>
<h3 class="anchor anchorWithStickyNavbar_GVoy" id="use-custom-parsing">Use custom parsing<a href="https://blog.0xniko.dev/2020/10/31/microservice-monitoring-application-logs#use-custom-parsing" class="hash-link" aria-label="Direct link to Use custom parsing" title="Direct link to Use custom parsing">​</a></h3>
<p>Because microservices logs are often structured in multiple ways, trying to search through all of your data using generic regexes is typically not very effective. Instead, consider writing custom parsing rules that govern how your log analytics tool identifies relevant trends within log data, even if you are working with logs of varying types or structures.</p>
<h3 class="anchor anchorWithStickyNavbar_GVoy" id="make-logs-searchable">Make Logs Searchable<a href="https://blog.0xniko.dev/2020/10/31/microservice-monitoring-application-logs#make-logs-searchable" class="hash-link" aria-label="Direct link to Make Logs Searchable" title="Direct link to Make Logs Searchable">​</a></h3>
<p>Make sure all the fields available in the logs are searchable. For example, If you get ahold of the correlation ID, you can search all the logs based on that t to find out the request flow.</p>
<p><a href="https://blog.0xniko.dev/assets/files/elk-logs-d2a7ca4e3c54c93b63a6dadb5a6823d8.jpg" target="_blank"><img decoding="async" loading="lazy" alt="elk-logs.jpg" src="https://blog.0xniko.dev/assets/images/elk-logs-d2a7ca4e3c54c93b63a6dadb5a6823d8.jpg" width="1508" height="730" class="img_eDxn"></a></p>
<p>The amount of logs collected is usually very large. Therefore, we need to optimize the storage and especially ensure query performance. To do that we need to indexing logs data before putting it into durable storage.
For example, we use ELK to collect and process logs. We will index on Elasticsearch.</p>
<h3 class="anchor anchorWithStickyNavbar_GVoy" id="visualize-log-data">Visualize log data<a href="https://blog.0xniko.dev/2020/10/31/microservice-monitoring-application-logs#visualize-log-data" class="hash-link" aria-label="Direct link to Visualize log data" title="Direct link to Visualize log data">​</a></h3>
<p>When working in microservices-based applications, developers often need to examine the state of an application, as well as information on any issues, downtimes or latency. Teams can add dashboard features that provide a visual depiction of the information carried into the application logs.</p>
<p>Log visualization illustrates aggregated information for the services. This information may include, but is not limited to, requests, responses and size of responses. There are various log visualization tools available, such as Scalyr, Graylog, Kibana and Sematext.</p>
<h3 class="anchor anchorWithStickyNavbar_GVoy" id="data-partitioning-to-optimize-storage-cost">Data partitioning to optimize storage cost<a href="https://blog.0xniko.dev/2020/10/31/microservice-monitoring-application-logs#data-partitioning-to-optimize-storage-cost" class="hash-link" aria-label="Direct link to Data partitioning to optimize storage cost" title="Direct link to Data partitioning to optimize storage cost">​</a></h3>
<p><a href="https://blog.0xniko.dev/assets/files/data-partition-storage-e98d3d7aef98fbe57cda7f505a62fbf0.png" target="_blank"><img decoding="async" loading="lazy" alt="data-partition-storage.png" src="https://blog.0xniko.dev/assets/images/data-partition-storage-e98d3d7aef98fbe57cda7f505a62fbf0.png" width="810" height="366" class="img_eDxn"></a></p>
<p>With a huge amount of data from logs, the problem of optimizing storage costs is a big problem. According to the design pattern for big data storage, we will partition the data by query terms, including:</p>
<ul>
<li>Hot data: frequently queried data is usually new logs or realtime logs.</li>
<li>Warm data: are data types that are not frequently queried. Middle term query. Usually historical data will be used to access when needed.</li>
<li>Cold data: are data types that are almost not used for querying, but for the purpose of archiving and long-term storage.</li>
</ul>
<p>Because the cost for different types of hosting services is also different according to the query plan. So we need to set up plans to transfer logs data right for the purpose of use to optimize costs. For example, for Storage services for Hot data, the cost of the bandwitch will be quite low and the cost of storage and access speed will be quite high. In contrast to Storage services for Cold data, the cost for storage is quite low, but the cost of access will be more expensive and of course the access speed will be lower. The cost difference between Storage services for data types depends on the Query plan that needs corresponding hardware configuration.</p>
<p>Read more:</p>
<ul>
<li>
<p>AWS S3 storage plans: <a href="https://aws.amazon.com/s3/cost-optimization/" target="_blank" rel="noopener noreferrer">https://aws.amazon.com/s3/cost-optimization/</a></p>
</li>
<li>
<p>AWS Cold storage for Elastic search service: <a href="https://aws.amazon.com/blogs/big-data/introducing-cold-storage-for-amazon-elasticsearch-service/" target="_blank" rel="noopener noreferrer">https://aws.amazon.com/blogs/big-data/introducing-cold-storage-for-amazon-elasticsearch-service/</a></p>
</li>
<li>
<p>BMC blogs: <a href="https://www.bmc.com/blogs/cold-vs-hot-data-storage/" target="_blank" rel="noopener noreferrer">https://www.bmc.com/blogs/cold-vs-hot-data-storage/</a></p>
</li>
</ul>
<p><strong><em>References:</em></strong></p>
<ul>
<li><em><a href="https://www.logdna.com/blog/logging-for-monoliths-vs-microservices-logging" target="_blank" rel="noopener noreferrer">https://www.logdna.com/blog/logging-for-monoliths-vs-microservices-logging</a></em></li>
<li><em><a href="https://walkingtreetech.medium.com/logs-monitoring-in-microservices-using-elk-316bf9c049c4" target="_blank" rel="noopener noreferrer">https://walkingtreetech.medium.com/logs-monitoring-in-microservices-using-elk-316bf9c049c4</a></em></li>
</ul>]]></content>
        <author>
            <name>Niko</name>
            <uri>https://0xniko.dev</uri>
        </author>
        <category label="microservices" term="microservices"/>
        <category label="microservice" term="microservice"/>
        <category label="logs" term="logs"/>
        <category label="logging" term="logging"/>
        <category label="traces" term="traces"/>
        <category label="tracing" term="tracing"/>
        <category label="monitors" term="monitors"/>
        <category label="monitoing" term="monitoing"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Microservice monitoring - Resources Metrics]]></title>
        <id>https://blog.0xniko.dev/2020/10/30/microservice-monitoring-resources-metrics</id>
        <link href="https://blog.0xniko.dev/2020/10/30/microservice-monitoring-resources-metrics"/>
        <updated>2020-10-30T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Monitoring containerized microservices with resources metrics.]]></summary>
        <content type="html"><![CDATA[<blockquote>
<p>Logs are easy to integrate into your application, and they give you the ability to represent any type of data in the form of strings.</p>
<p>Metrics, on the other hand, are numerical representations of data. These are often used to count or measure a value and are aggregated over a period of time.</p>
</blockquote>
<p>Metrics give us insights into the historical and current state of a system. Since they are just numbers, we can also use them to perform statistical analysis and predictions about the system’s future behaviour.</p>
<p>Metrics contain low-resolution data. This may include a count of parameters (such as requests, errors, and so on) and measures of resources (such as CPU and memory utilization).</p>
<p><a href="https://blog.0xniko.dev/assets/files/grafana-dashboard-fbd8efc74fb562ead47ee28c9715642e.png" target="_blank"><img decoding="async" loading="lazy" alt="/img/clm/grafana-dashboard.png" src="https://blog.0xniko.dev/assets/images/grafana-dashboard-fbd8efc74fb562ead47ee28c9715642e.png" width="1920" height="979" class="img_eDxn"></a></p>
<h2 class="anchor anchorWithStickyNavbar_GVoy" id="the-cost-of-logs-and-metrics">The Cost of Logs and Metrics<a href="https://blog.0xniko.dev/2020/10/30/microservice-monitoring-resources-metrics#the-cost-of-logs-and-metrics" class="hash-link" aria-label="Direct link to The Cost of Logs and Metrics" title="Direct link to The Cost of Logs and Metrics">​</a></h2>
<p>Logs are expensive to store. The storage overhead of logs also increases over time and is directly proportional to the increase in traffic.</p>
<p>Metrics have a constant storage overhead. The cost of storage and retrieval of metrics does not increase too much with the increase in traffic. It is, however, dependent on the number of variables we emit with each metric.</p>
<h2 class="anchor anchorWithStickyNavbar_GVoy" id="types-of-metrics">Types of Metrics<a href="https://blog.0xniko.dev/2020/10/30/microservice-monitoring-resources-metrics#types-of-metrics" class="hash-link" aria-label="Direct link to Types of Metrics" title="Direct link to Types of Metrics">​</a></h2>
<h3 class="anchor anchorWithStickyNavbar_GVoy" id="golden-signals-are-an-effective-way-of-monitoring-the-overall-state-of-the-system-and-identifying-problems">Golden signals are an effective way of monitoring the overall state of the system and identifying problems<a href="https://blog.0xniko.dev/2020/10/30/microservice-monitoring-resources-metrics#golden-signals-are-an-effective-way-of-monitoring-the-overall-state-of-the-system-and-identifying-problems" class="hash-link" aria-label="Direct link to Golden signals are an effective way of monitoring the overall state of the system and identifying problems" title="Direct link to Golden signals are an effective way of monitoring the overall state of the system and identifying problems">​</a></h3>
<ul>
<li>Availability: State of your system measured from the perspective of clients (for example, the percentage of errors on total requests).</li>
<li>Health: State of your system measured using periodic pings.</li>
<li>Request Rate: Rate of incoming requests to the system.</li>
<li>Saturation: How free or loaded the system is (foe example, the queue depth or available memory).</li>
<li>Utilization: How busy the system is (for example, CPU load or memory usage). This is represented as a percentage.</li>
<li>Error Rate: Rate of errors being produced in the system.</li>
<li>Latency: Response time of the system, usually measured in the 95th or 99th percentile.</li>
</ul>
<h3 class="anchor anchorWithStickyNavbar_GVoy" id="resource-metrics">Resource metrics<a href="https://blog.0xniko.dev/2020/10/30/microservice-monitoring-resources-metrics#resource-metrics" class="hash-link" aria-label="Direct link to Resource metrics" title="Direct link to Resource metrics">​</a></h3>
<p>Resource metrics are almost always made available by default from the infrastructure provider (AWS CloudWatch or Kubernetes metrics) and are used to monitor infrastructure health.</p>
<ul>
<li><strong>CPU/Memory Utilization</strong>: Usage of the system’s core resources.</li>
<li><strong>Host Count</strong>: Number of hosts/pods that are running your system (used to detect availability issues due to pod crashes).</li>
<li><strong>Live Threads</strong>: Threads spawned in your service (used to detect issues in multi-threading).</li>
<li><strong>Heap Usage</strong>: Heap memory usage statistics (can help debug memory leaks).</li>
</ul>
<h3 class="anchor anchorWithStickyNavbar_GVoy" id="business-metrics">Business metrics<a href="https://blog.0xniko.dev/2020/10/30/microservice-monitoring-resources-metrics#business-metrics" class="hash-link" aria-label="Direct link to Business metrics" title="Direct link to Business metrics">​</a></h3>
<p>Business metrics can be used to monitor granular interaction with core APIs or functionality in your services.</p>
<ul>
<li><strong>Request Rate</strong>: Rate of requests to the APIs.</li>
<li><strong>Error Rate</strong>: Rate of errors being thrown by the APIs.</li>
<li><strong>Latency</strong>: Time taken to process requests by the APIs.</li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_GVoy" id="dashboards-and-alerts">Dashboards and Alerts<a href="https://blog.0xniko.dev/2020/10/30/microservice-monitoring-resources-metrics#dashboards-and-alerts" class="hash-link" aria-label="Direct link to Dashboards and Alerts" title="Direct link to Dashboards and Alerts">​</a></h2>
<p>Since metrics are stored in a time-series database, it’s more efficient and reliable to run queries against them for measuring the state of the system.</p>
<p>These queries can be used to build dashboards for representing the historical state of the system.</p>
<p>They can also be used to trigger alerts when there is an issue with the system (e.g. an increase in the number of errors observed or a sudden spike in CPU utilization).</p>
<p>Due to their numeric nature, we can also create complex mathematical queries (such as X% of errors in last Y minutes) to monitor system health.</p>
<p><strong><em>References:</em></strong></p>
<ul>
<li><em><a href="https://www.freecodecamp.org/news/microservice-observability-metrics" target="_blank" rel="noopener noreferrer">https://www.freecodecamp.org/news/microservice-observability-metrics</a></em></li>
</ul>]]></content>
        <author>
            <name>Niko</name>
            <uri>https://0xniko.dev</uri>
        </author>
        <category label="microservices" term="microservices"/>
        <category label="microservice" term="microservice"/>
        <category label="logs" term="logs"/>
        <category label="logging" term="logging"/>
        <category label="traces" term="traces"/>
        <category label="tracing" term="tracing"/>
        <category label="monitors" term="monitors"/>
        <category label="monitoing" term="monitoing"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Microservice monitoring - Log centralization]]></title>
        <id>https://blog.0xniko.dev/2020/10/19/microservice-monitoring-log-centralization</id>
        <link href="https://blog.0xniko.dev/2020/10/19/microservice-monitoring-log-centralization"/>
        <updated>2020-10-19T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Monitoring containerized microservices with a centralized logging architecture.]]></summary>
        <content type="html"><![CDATA[<h2 class="anchor anchorWithStickyNavbar_GVoy" id="problems">Problems<a href="https://blog.0xniko.dev/2020/10/19/microservice-monitoring-log-centralization#problems" class="hash-link" aria-label="Direct link to Problems" title="Direct link to Problems">​</a></h2>
<p>We all know importance of logging in applications but it is even more crucial in distributed systems. There are challenges of logging in microservices architectures.</p>
<p>As the amount of services in a microservice architecture rises, complexity naturally also rises. Bugs and individual service failures can be very tricky to deal with and having to spend hours digging deep to find the root of an unnamed error can be a daunting and unproductive task.And they get even more complicated when one or more services fail.</p>
<ul>
<li>Which service failed?</li>
<li>Why?</li>
<li>And under what circumstances?</li>
</ul>
<p>To effectively deal with the challenges of system errors, request chain breakdowns, or even simply to stay on top of your system architecture, logging is a vital tool. It is undeniable that it is the cornerstone of maintaining and debugging your app efficiently. All these questions are hard to answer if you don’t have good, meaningful logs.</p>
<h2 class="anchor anchorWithStickyNavbar_GVoy" id="why-we-need-a-centralized-log-management-clm-for-microservice-architecture">Why we need a Centralized Log Management (CLM) for microservice architecture?<a href="https://blog.0xniko.dev/2020/10/19/microservice-monitoring-log-centralization#why-we-need-a-centralized-log-management-clm-for-microservice-architecture" class="hash-link" aria-label="Direct link to Why we need a Centralized Log Management (CLM) for microservice architecture?" title="Direct link to Why we need a Centralized Log Management (CLM) for microservice architecture?">​</a></h2>
<p><img decoding="async" loading="lazy" alt="microservice architecture" src="https://blog.0xniko.dev/assets/images/microservices-architecture-19ab3d88d02a798c505f79463626314c.png" width="1244" height="683" class="img_eDxn"></p>
<p>In the microservice pattern, thousands of services operate independently and are distributed across many different infrastructures with each service having different types of logs. Therefore we need a central control of these logs synchronously and centrally manage them. Ensure that when any errors arise, we can trace them and offer a quick and thorough solution.</p>
<p>In order to ease this entire process, many solutions such as a Centralized Log Management (CLM) solution comes into the picture.</p>
<p>Monitoring containerized microservices with a centralized logging architecture.</p>
<h2 class="anchor anchorWithStickyNavbar_GVoy" id="the-clm-pillars-of-observability">The CLM Pillars of Observability<a href="https://blog.0xniko.dev/2020/10/19/microservice-monitoring-log-centralization#the-clm-pillars-of-observability" class="hash-link" aria-label="Direct link to The CLM Pillars of Observability" title="Direct link to The CLM Pillars of Observability">​</a></h2>
<p>Based on usage goals and lifecycle round, CLM divided logs data into 3 main categories:</p>
<ul>
<li>Metrics</li>
<li>Logs &amp; Events</li>
<li>Traces</li>
</ul>
<p><a href="https://blog.0xniko.dev/assets/files/three_pillars_observability-f51cc1be88e60cf4a737baf43befb1c2.png" target="_blank"><img decoding="async" loading="lazy" alt="three_pillars_observability.jpg" src="https://blog.0xniko.dev/assets/images/three_pillars_observability-f51cc1be88e60cf4a737baf43befb1c2.png" width="1001" height="936" class="img_eDxn"></a></p>
<h3 class="anchor anchorWithStickyNavbar_GVoy" id="1-metrics">1. Metrics<a href="https://blog.0xniko.dev/2020/10/19/microservice-monitoring-log-centralization#1-metrics" class="hash-link" aria-label="Direct link to 1. Metrics" title="Direct link to 1. Metrics">​</a></h3>
<p>Metrics probably represents the most valuable of the three monitoring tools because:</p>
<p>So many resources are designed to spit out various bits of health and performance information (and there are loads of tools to collect this information).
They are efficient.
They are frequently generated.
They are easily correlated across elements of your infrastructure.
Everything from operating systems to applications generate metrics which, at the least, are going to include a name, a time stamp and a field to represent some value. Since so many resources come ready to tell us about themselves, metrics is an obvious place to start when it comes to monitoring.</p>
<p>Most all metrics will enable you to tell if a resource is alive or dead, but if the target is valuable enough you’ll want to be able to ascertain what is actually wrong with the system or going wrong. As you can imagine, the latter will require detailed information about what is happening inside the system, so called white-box monitoring that relies on internal instrumentation. The more rudimentary black-box approach draws conclusions about the health of a system based on externally visible indicators (is it responding to any system calls?).</p>
<p>But perhaps the most important thing to understand about metrics is that last bullet about being able to correlate metrics across infrastructure components. Given the complex interdependencies common to IT environments today, the ability to stitch together metrics to get a bigger picture view is a real time saver. And it becomes even more critical as we move to cloud-native environments because of the dynamic nature of cloud infrastructure and the ever-changing relationship between that infrastructure and the applications.</p>
<p>An initial challenge of harnessing metrics is the variety of the information available and the number of tools needed to collect and make sense of that information. Then there is the question of how you store data in so many formats from so many resources. But the resultant upside more than makes up for the effort required to figure out how to harness the information.</p>
<p>It is also worth noting that, given there is no standard API for metric collection, many organizations use agents to collect data that is either pushed to a central location for analysis or pulled by that central resource. Gartner says agents frequently referenced by customers include push agents Collectd and Telegraf, while Prometheus is cited as a tool to pull information from targets.</p>
<h3 class="anchor anchorWithStickyNavbar_GVoy" id="2-logs--events">2. Logs &amp; Events<a href="https://blog.0xniko.dev/2020/10/19/microservice-monitoring-log-centralization#2-logs--events" class="hash-link" aria-label="Direct link to 2. Logs &amp; Events" title="Direct link to 2. Logs &amp; Events">​</a></h3>
<p>Logs are perhaps the second most important tool in the monitoring toolbox because virtually everything logs information about what they are doing at any given time. What’s more, logs tend to give more in-depth information about resources than metrics. So, if metrics showed the resource is dead, logs will help tell you why it died.</p>
<p>The problem with logs is there can be too much of a good thing. With everything in your environment tracking what they are doing and anxious to share that information, it is easy to see how that could result in a mountain of data. Instead of streamlining the monitoring process, you are simply creating a big new centralized haystack.</p>
<p>And like metrics, differences in log formats and the abundance of tools available to collect and make sense of logs, complicates the job of getting the most out of this rich trove of material. There are, however, a number of common tools used for collecting logs, such as syslog and open source tools such as Fluentd.</p>
<p>The trick to getting the most out of these tools is limiting what you collect to keep it manageable, and, where possible, to home in on common fields so you can more easily find the needles in the haystack.</p>
<h3 class="anchor anchorWithStickyNavbar_GVoy" id="3-traces">3. Traces<a href="https://blog.0xniko.dev/2020/10/19/microservice-monitoring-log-centralization#3-traces" class="hash-link" aria-label="Direct link to 3. Traces" title="Direct link to 3. Traces">​</a></h3>
<p>Last but not least in the monitoring triangle is application trace data, which “traces” information about specific application operations. With so many application interdependencies these days, these operations will typically involve hops through multiple services (so called spans).</p>
<p>Traces, then, add critical visibility into the health of an application end-to-end. They are, however, solely focused on the application layer and provide limited visibility into the health of the underlying infrastructure. So, even if you collect traces, you still need metrics to get the full story of your environment. APM tools feed trace information to a centralized metrics store, so traces provide a nice source of data for an app-centric view.</p>
<p>The need for the viewpoint that traces can provide is exacerbated in container-based microservice architectures that are nothing more than a collection of stitched together services. These environments can be addressed with something called distributed tracing.</p>
<p><strong><em>References:</em></strong></p>
<ul>
<li><em><a href="https://devops.com/metrics-logs-and-traces-the-golden-triangle-of-observability-in-monitoring" target="_blank" rel="noopener noreferrer">https://devops.com/metrics-logs-and-traces-the-golden-triangle-of-observability-in-monitoring</a></em></li>
</ul>]]></content>
        <author>
            <name>Niko</name>
            <uri>https://0xniko.dev</uri>
        </author>
        <category label="microservices" term="microservices"/>
        <category label="microservice" term="microservice"/>
        <category label="logs" term="logs"/>
        <category label="logging" term="logging"/>
        <category label="traces" term="traces"/>
        <category label="tracing" term="tracing"/>
        <category label="monitors" term="monitors"/>
        <category label="monitoing" term="monitoing"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Build quick report on nodejs server side with EJS template and ChartJS]]></title>
        <id>https://blog.0xniko.dev/2020/07/31/quick-report-pdf-with-nodejs-chartjs</id>
        <link href="https://blog.0xniko.dev/2020/07/31/quick-report-pdf-with-nodejs-chartjs"/>
        <updated>2020-07-31T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[NodeJS Quick PDF Report]]></summary>
        <content type="html"><![CDATA[<h2 class="anchor anchorWithStickyNavbar_GVoy" id="build-quick-report-on-nodejs-server-side-with-ejs-template-and-chartjs">Build quick report on nodejs server side with EJS template and ChartJS<a href="https://blog.0xniko.dev/2020/07/31/quick-report-pdf-with-nodejs-chartjs#build-quick-report-on-nodejs-server-side-with-ejs-template-and-chartjs" class="hash-link" aria-label="Direct link to Build quick report on nodejs server side with EJS template and ChartJS" title="Direct link to Build quick report on nodejs server side with EJS template and ChartJS">​</a></h2>
<p>Concepts:</p>
<ol>
<li>Define report template like as HTML view by EJS syntax</li>
<li>Draw chart by ChartJS into HTML view template</li>
<li>Using EJS engine to render HTML view from HTML template</li>
<li>Create new Chromium instance as headless browser using Puppeteer to render HTML template</li>
<li>Create PDF from headless browser view</li>
<li>Create report blob and free resources.</li>
</ol>
<h2 class="anchor anchorWithStickyNavbar_GVoy" id="install">Install<a href="https://blog.0xniko.dev/2020/07/31/quick-report-pdf-with-nodejs-chartjs#install" class="hash-link" aria-label="Direct link to Install" title="Direct link to Install">​</a></h2>
<p><a href="https://npmjs.org/package/nodejs-pdf-report" target="_blank" rel="noopener noreferrer"><img decoding="async" loading="lazy" src="https://nodei.co/npm/nodejs-pdf-report.png" alt="nodejs-pdf-report" class="img_eDxn"></a></p>
<div class="language-bash codeBlockContainer_Dsm5 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent__qvQ"><pre tabindex="0" class="prism-code language-bash codeBlock_TP_y thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_o52p"><span class="token-line" style="color:#393A34"><span class="token plain">npm install --save nodejs-pdf-report</span><br></span></code></pre><div class="buttonGroup_pyGv"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_WfJE" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ImZj"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_OeyQ"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h2 class="anchor anchorWithStickyNavbar_GVoy" id="supports">Supports<a href="https://blog.0xniko.dev/2020/07/31/quick-report-pdf-with-nodejs-chartjs#supports" class="hash-link" aria-label="Direct link to Supports" title="Direct link to Supports">​</a></h2>
<ul>
<li>Base html template with <a href="https://github.com/mde/ejs" target="_blank" rel="noopener noreferrer">EJS</a> engine.</li>
<li>Embeded <a href="https://www.chartjs.org/" target="_blank" rel="noopener noreferrer">Chart.js v2.9.3</a>.</li>
<li>Server side without browser.</li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_GVoy" id="examples">Examples<a href="https://blog.0xniko.dev/2020/07/31/quick-report-pdf-with-nodejs-chartjs#examples" class="hash-link" aria-label="Direct link to Examples" title="Direct link to Examples">​</a></h2>
<ul>
<li>Import from package</li>
</ul>
<div class="language-javascript codeBlockContainer_Dsm5 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent__qvQ"><pre tabindex="0" class="prism-code language-javascript codeBlock_TP_y thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_o52p"><span class="token-line" style="color:#393A34"><span class="token plain">   </span><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#393A34">{</span><span class="token imports"> </span><span class="token imports maybe-class-name">HtmlReport</span><span class="token imports punctuation" style="color:#393A34">,</span><span class="token imports"> </span><span class="token imports maybe-class-name">ReportOptions</span><span class="token imports"> </span><span class="token imports punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"nodejs-pdf-report"</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre><div class="buttonGroup_pyGv"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_WfJE" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ImZj"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_OeyQ"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<ul>
<li>Define configures</li>
</ul>
<div class="language-javascript codeBlockContainer_Dsm5 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent__qvQ"><pre tabindex="0" class="prism-code language-javascript codeBlock_TP_y thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_o52p"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">reportOptions</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token maybe-class-name">ReportOptions</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">title</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Test report with chartjs"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">useChartJs</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">pdfOptions</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">margin</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token literal-property property" style="color:#36acaa">top</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"100px"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token literal-property property" style="color:#36acaa">bottom</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"200px"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token literal-property property" style="color:#36acaa">right</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"30px"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token literal-property property" style="color:#36acaa">left</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"30px"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">template</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"template.ejs"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">headerTemplate</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"header-template.ejs"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">footerTemplate</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"footer-template.ejs"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">styles</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token string" style="color:#e3116c">"styles.css"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">scripts</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">"utils.js"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">"index.js"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">data</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">users</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token literal-property property" style="color:#36acaa">name</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Luong Phung"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token literal-property property" style="color:#36acaa">name</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Jasmine"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">title</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Test report with chartjs"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">author</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Luong Phung"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">time</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"2020"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre><div class="buttonGroup_pyGv"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_WfJE" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ImZj"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_OeyQ"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<ul>
<li>Create pdf file as buffer</li>
</ul>
<div class="language-javascript codeBlockContainer_Dsm5 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent__qvQ"><pre tabindex="0" class="prism-code language-javascript codeBlock_TP_y thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_o52p"><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> htmlReport </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">HtmlReport</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> reportPdf </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword control-flow" style="color:#00009f">await</span><span class="token plain"> htmlReport</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">createPdf</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">reportOptions</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> savePath </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> path</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">resolve</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"./chartjs_report.pdf"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  fs</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">writeFileSync</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">savePath</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> reportPdf</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"binary"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre><div class="buttonGroup_pyGv"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_WfJE" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ImZj"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_OeyQ"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<ul>
<li>Check you report file <em>"chartjs_report.pdf"</em></li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_GVoy" id="screens-shot">Screens shot<a href="https://blog.0xniko.dev/2020/07/31/quick-report-pdf-with-nodejs-chartjs#screens-shot" class="hash-link" aria-label="Direct link to Screens shot" title="Direct link to Screens shot">​</a></h2>
<p><img decoding="async" loading="lazy" src="https://raw.githubusercontent.com/krakenui/nodejs-pdf-report/master/screen-shots/output1.png" alt="output1.png" class="img_eDxn"></p>
<h2 class="anchor anchorWithStickyNavbar_GVoy" id="api-references">API references<a href="https://blog.0xniko.dev/2020/07/31/quick-report-pdf-with-nodejs-chartjs#api-references" class="hash-link" aria-label="Direct link to API references" title="Direct link to API references">​</a></h2>
<h3 class="anchor anchorWithStickyNavbar_GVoy" id="pdfoptions">PdfOptions<a href="https://blog.0xniko.dev/2020/07/31/quick-report-pdf-with-nodejs-chartjs#pdfoptions" class="hash-link" aria-label="Direct link to PdfOptions" title="Direct link to PdfOptions">​</a></h3>
<table><thead><tr><th>Name</th><th>type</th><th>default</th><th>Description</th></tr></thead><tbody><tr><td>scale</td><td>number</td><td>1</td><td>Scale of the webpage rendering</td></tr><tr><td>printBackground</td><td>boolean</td><td>false</td><td>Print background graphics.</td></tr><tr><td>landscape</td><td>boolean</td><td>false</td><td>Paper orientation</td></tr><tr><td>format</td><td>string</td><td>"A4"</td><td>Page format as : "Letter" "A0" ... "A4" ...</td></tr><tr><td>margin</td><td><code>{top, bottom, left, right}</code></td><td>0</td><td>Page margin as number of pixels</td></tr></tbody></table>
<h3 class="anchor anchorWithStickyNavbar_GVoy" id="reportoptions">ReportOptions<a href="https://blog.0xniko.dev/2020/07/31/quick-report-pdf-with-nodejs-chartjs#reportoptions" class="hash-link" aria-label="Direct link to ReportOptions" title="Direct link to ReportOptions">​</a></h3>
<table><thead><tr><th>Name</th><th>type</th><th>default</th><th>Description</th></tr></thead><tbody><tr><td>title</td><td>string</td><td>null</td><td>Pdf report title</td></tr><tr><td>useChartJs</td><td>boolean</td><td>false</td><td>Use chartjs as default</td></tr><tr><td>pdfOptions</td><td><a href="https://blog.0xniko.dev/#PdfOptions">PdfOptions</a></td><td>null</td><td>any</td></tr><tr><td>template</td><td>string</td><td>null</td><td>Template path</td></tr><tr><td>footerTemplate</td><td>string</td><td>null</td><td>Footer template path</td></tr><tr><td>headerTemplate</td><td>string</td><td>null</td><td>Header template path</td></tr><tr><td>styles</td><td>string[]</td><td>[]</td><td>Style paths</td></tr><tr><td>scripts</td><td>string[]</td><td>[]</td><td>Scripts paths</td></tr><tr><td>data</td><td>object</td><td></td><td>Report data</td></tr></tbody></table>
<h2 class="anchor anchorWithStickyNavbar_GVoy" id="4-references">4. References<a href="https://blog.0xniko.dev/2020/07/31/quick-report-pdf-with-nodejs-chartjs#4-references" class="hash-link" aria-label="Direct link to 4. References" title="Direct link to 4. References">​</a></h2>
<ul>
<li><a href="https://github.com/krakenui/nodejs-pdf-report" target="_blank" rel="noopener noreferrer">nodejs-pdf-report</a></li>
<li><a href="https://github.com/puppeteer/puppeteer" target="_blank" rel="noopener noreferrer">Puppeteer</a></li>
<li><a href="https://ejs.co/" target="_blank" rel="noopener noreferrer">EJS</a></li>
</ul>]]></content>
        <author>
            <name>Niko</name>
            <uri>https://0xniko.dev</uri>
        </author>
        <category label="nodejs" term="nodejs"/>
        <category label="report" term="report"/>
        <category label="pdf" term="pdf"/>
        <category label="backend" term="backend"/>
        <category label="chartjs" term="chartjs"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Using rxjs effective in javascript client side (browser)]]></title>
        <id>https://blog.0xniko.dev/2020/07/10/using-rxjs-effective-in-javascript-client-side</id>
        <link href="https://blog.0xniko.dev/2020/07/10/using-rxjs-effective-in-javascript-client-side"/>
        <updated>2020-07-10T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Using rxjs effective in javascript client side (browser)]]></summary>
        <content type="html"><![CDATA[<p>Using rxjs effective in javascript client side (browser)</p>
<h3 class="anchor anchorWithStickyNavbar_GVoy" id="1-supscription">1. Supscription<a href="https://blog.0xniko.dev/2020/07/10/using-rxjs-effective-in-javascript-client-side#1-supscription" class="hash-link" aria-label="Direct link to 1. Supscription" title="Direct link to 1. Supscription">​</a></h3>
<ul>
<li>Alway destroy subscription when component destroy. When subscription created by call 'subscribe', a listen will be created for handle event &amp; callback function. So, if these not destrioy, that still on memory, memory leak can occured. This solution, we will destroy them when these compeleted, suggest on component destroy; using 'unsubscribe' from subscription context.</li>
</ul>
<div class="language-javascript codeBlockContainer_Dsm5 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent__qvQ"><pre tabindex="0" class="prism-code language-javascript codeBlock_TP_y thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_o52p"><span class="token-line" style="color:#393A34"><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#393A34">{</span><span class="token imports"> </span><span class="token imports maybe-class-name">Subscription</span><span class="token imports"> </span><span class="token imports punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"rxjs"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword module" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">MyComponent</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">extends</span><span class="token plain"> </span><span class="token class-name">React</span><span class="token class-name punctuation" style="color:#393A34">.</span><span class="token class-name">Component</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">_mySerive</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token maybe-class-name">MyService</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">MyService</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">_subscriptions</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token maybe-class-name">Subscription</span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token function" style="color:#d73a49">constructor</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">props</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">super</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">props</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">this</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">state</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token literal-property property" style="color:#36acaa">userName</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Jasmine"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token literal-property property" style="color:#36acaa">userEmail</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"jasmine@mail.com"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token function" style="color:#d73a49">componentDidMount</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">this</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">_loadAsyncUserName</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token function" style="color:#d73a49">componentWillMount</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">this</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">_subscriptions</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">forEach</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">subscription</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> subscription</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">unsubscribe</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token function" style="color:#d73a49">_loadAsyncUserName</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token keyword" style="color:#00009f">this</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">_subscriptions</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">push</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token keyword" style="color:#00009f">this</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">_mySerive</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">getAsyncUserName</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">subscribe</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">fullName</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">              </span><span class="token keyword" style="color:#00009f">this</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">setState</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                  </span><span class="token literal-property property" style="color:#36acaa">userName</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> fullName</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">              </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token keyword" style="color:#00009f">this</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">_subscriptions</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">push</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token keyword" style="color:#00009f">this</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">_mySerive</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">getAsyncEmail</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">subscribe</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">email</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">              </span><span class="token keyword" style="color:#00009f">this</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">setState</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                  </span><span class="token literal-property property" style="color:#36acaa">userEmail</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> email</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">              </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token function" style="color:#d73a49">render</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> userName</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> userEmail </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">this</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">state</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&lt;</span><span class="token plain">div className</span><span class="token operator" style="color:#393A34">=</span><span class="token string" style="color:#e3116c">"my-component"</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token operator" style="color:#393A34">&lt;</span><span class="token plain">p</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain">userName</span><span class="token punctuation" style="color:#393A34">}</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token operator" style="color:#393A34">/</span><span class="token plain">p</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token operator" style="color:#393A34">&lt;</span><span class="token plain">p</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain">userEmail</span><span class="token punctuation" style="color:#393A34">}</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token operator" style="color:#393A34">/</span><span class="token plain">p</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token operator" style="color:#393A34">&lt;</span><span class="token operator" style="color:#393A34">/</span><span class="token plain">div</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre><div class="buttonGroup_pyGv"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_WfJE" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ImZj"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_OeyQ"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<ul>
<li>Handle error when subscription throw error, that assure this behavior without crash when error occured.</li>
</ul>
<div class="language-javascript codeBlockContainer_Dsm5 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent__qvQ"><pre tabindex="0" class="prism-code language-javascript codeBlock_TP_y thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_o52p"><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">this</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">_mySerive</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">getAsyncEmail</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">subscribe</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token parameter">email</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token keyword" style="color:#00009f">this</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">setState</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                </span><span class="token literal-property property" style="color:#36acaa">userEmail</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> email</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token parameter">error</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token function" style="color:#d73a49">handleError</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">error</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre><div class="buttonGroup_pyGv"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_WfJE" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ImZj"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_OeyQ"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h3 class="anchor anchorWithStickyNavbar_GVoy" id="2-concurency">2. Concurency<a href="https://blog.0xniko.dev/2020/07/10/using-rxjs-effective-in-javascript-client-side#2-concurency" class="hash-link" aria-label="Direct link to 2. Concurency" title="Direct link to 2. Concurency">​</a></h3>
<p>Using 'forkJoin' + 'concatMap/map' to control multiple async request before move them to next step.</p>
<div class="language-javascript codeBlockContainer_Dsm5 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent__qvQ"><pre tabindex="0" class="prism-code language-javascript codeBlock_TP_y thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_o52p"><span class="token-line" style="color:#393A34"><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#393A34">{</span><span class="token imports"> forkJoin </span><span class="token imports punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"rxjs"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#393A34">{</span><span class="token imports"> concatMap</span><span class="token imports punctuation" style="color:#393A34">,</span><span class="token imports"> map </span><span class="token imports punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"rxjs/operators"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">forkJoin</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">this</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">_mySerive</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">getAsyncUserName</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">this</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">_mySerive</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">getAsyncEmail</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">pipe</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">concatMap</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter punctuation" style="color:#393A34">[</span><span class="token parameter">userName</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> userEmail</span><span class="token parameter punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain">  </span><span class="token keyword" style="color:#00009f">this</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">_mySerivecheckUserInfoAsync</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">userName</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> userEmail</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">map</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">existUser</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token literal-property property" style="color:#36acaa">isExistUser</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> existUser </span><span class="token operator" style="color:#393A34">!=</span><span class="token plain"> </span><span class="token keyword null nil" style="color:#00009f">null</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token literal-property property" style="color:#36acaa">userName</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> existUser</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">userName</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token literal-property property" style="color:#36acaa">userEmail</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> existUser</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">userEmail</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span></code></pre><div class="buttonGroup_pyGv"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_WfJE" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ImZj"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_OeyQ"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h3 class="anchor anchorWithStickyNavbar_GVoy" id="3-synchronus-flow">3. Synchronus flow<a href="https://blog.0xniko.dev/2020/07/10/using-rxjs-effective-in-javascript-client-side#3-synchronus-flow" class="hash-link" aria-label="Direct link to 3. Synchronus flow" title="Direct link to 3. Synchronus flow">​</a></h3>
<p>Using 'forkJoin' + 'concatMap/map' to control multiple async request to synchronus flow, step by step.</p>
<div class="language-javascript codeBlockContainer_Dsm5 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent__qvQ"><pre tabindex="0" class="prism-code language-javascript codeBlock_TP_y thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_o52p"><span class="token-line" style="color:#393A34"><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#393A34">{</span><span class="token imports"> forkJoin </span><span class="token imports punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"rxjs"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#393A34">{</span><span class="token imports"> concatMap</span><span class="token imports punctuation" style="color:#393A34">,</span><span class="token imports"> map </span><span class="token imports punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"rxjs/operators"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">async</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">validateUserInfoAsync</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter punctuation" style="color:#393A34">[</span><span class="token parameter">userName</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> userEmail</span><span class="token parameter punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain">  </span><span class="token keyword" style="color:#00009f">this</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">_mySerive</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">checkUserInfoAsync</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">userName</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> userEmail</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">async</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">getAllHistory</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter punctuation" style="color:#393A34">{</span><span class="token parameter">userName</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> userEmail</span><span class="token parameter punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain">  </span><span class="token keyword" style="color:#00009f">this</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">_mySerive</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">getAllHistory</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">userName</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> userEmail</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">forkJoin</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">this</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">_mySerive</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">getAsyncUserName</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">this</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">_mySerive</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">getAsyncEmail</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">pipe</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// validate user</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">concatMap</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">validateUserInfoAsync</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// get all user credit history</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">concatMap</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">getAllHistory</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// map data</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">map</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter punctuation" style="color:#393A34">{</span><span class="token parameter">userName</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> userEmail</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> histories</span><span class="token parameter punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token literal-property property" style="color:#36acaa">userName</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> userName</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token literal-property property" style="color:#36acaa">userEmail</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> userEmail</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token literal-property property" style="color:#36acaa">histories</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> histories</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span></code></pre><div class="buttonGroup_pyGv"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_WfJE" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ImZj"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_OeyQ"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h3 class="anchor anchorWithStickyNavbar_GVoy" id="4-references">4. References<a href="https://blog.0xniko.dev/2020/07/10/using-rxjs-effective-in-javascript-client-side#4-references" class="hash-link" aria-label="Direct link to 4. References" title="Direct link to 4. References">​</a></h3>
<ul>
<li><a href="http://reactivex.io/rxjs/class/es6/Subscription.js~Subscription.html" target="_blank" rel="noopener noreferrer">RxJS Subscription</a></li>
<li><a href="http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-map" target="_blank" rel="noopener noreferrer">Rxjs Observable</a></li>
<li><a href="http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-concatMap" target="_blank" rel="noopener noreferrer">Rxjs ConcatMap</a></li>
</ul>]]></content>
        <author>
            <name>Niko</name>
            <uri>https://0xniko.dev</uri>
        </author>
        <category label="javascript" term="javascript"/>
        <category label="rxjs" term="rxjs"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Multi threading and development mistakes]]></title>
        <id>https://blog.0xniko.dev/2019/08/23/multi-thread-con-dao-hai-luoi</id>
        <link href="https://blog.0xniko.dev/2019/08/23/multi-thread-con-dao-hai-luoi"/>
        <updated>2019-08-23T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[What is multi threading helpful?]]></summary>
        <content type="html"><![CDATA[<p>Multi threading, or multi-threading is a programming method geared towards processing parallel concurrent tasks based on hardware design and specifically CPU.</p>
<div class="theme-admonition theme-admonition-tip admonition_SLCK alert alert--success"><div class="admonitionHeading_VYlH"><span class="admonitionIcon_TaVW"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>tip</div><div class="admonitionContent_HP_r"><p>In fact, developers often don't have much access to multithreading related processes, because they are complex and have many risks.</p><p>So what's so good about multithreading and what risks do we need to be aware of?</p></div></div>
<p>Let's go!!!</p>
<p>For example, you need to unzip idols information from <code>1000 zipped files</code>. Each file you take 10 minutes to decompress, for example:
<code>1000 * 10 = 10,000 minutes (~7 days)</code> to decompress all of this.</p>
<p>=&gt; but that's taking a long time, you want it in 1 day.</p>
<p>-&gt; ez, divided into <code>7 machines</code>, each machine <code>1000/7 files</code>.</p>
<p>But wait, I'm using an i7-8750H (just get it) right? My CPU basically has 12 Threads (real core).</p>
<p>=&gt; This means that this CPU can handle 12 tasks in parallel, in this case, files). That's it in theory, but actually those 12 threads still have to take care of OS tasks!</p>
<p><strong>This is the problem that multithreading will be used to solve.</strong></p>
<blockquote>
<p>Instead of using 1 thread to process all 1000 files, we use 7 threads to process these 1000 files. Since the theory is that the execution time will be reduced by 7 times, the reality depends on the memories as well. The CPU will then perform 7 parallel tasks for our app.</p>
</blockquote>
<p><em>That's good, 1 day is done!</em></p>
<p>Yup, then what's the risk?</p>
<p>But, if each file you create 1 Thread to use then =&gt; 1000 Threads, ooh, they will be loaded into RAM, for example each file is 1GB (idols are sure more)</p>
<p>=&gt; We need <code>1000 GB</code> for memory. The big problem.</p>
<p>Obviously this is not possible, assuming your PC has 16 GB of RAM, it will definitely crash the app because of an overflow error.</p>
<p>=&gt; When using multithreading we need to manage it, solution is instead of creating 1000 threads, we create 1 manager (pooling - thread pooling), it will execute 7 files at a time and only execute files. 8th when one of the files is completed.</p>
<p>It's roughly but 1 pool (~ connection pooling), it creates 7 swimming paths, it will let a guy in if there is a swimming pool that is free (no one is swimming, it must be dirty).</p>
<p>Above, is my sharing about a few aspects, some notes when using multi threading in programming!</p>
<p>Thanks for reading this far!!!</p>
<p>Refer with c# tuts:</p>
<ul>
<li><a href="https://www.tutorialspoint.com/csharp/csharp_multithreading.htm" target="_blank" rel="noopener noreferrer">https://www.tutorialspoint.com/csharp/csharp_multithreading.htm</a></li>
<li><a href="https://docs.microsoft.com/en-us/dotnet/api/system.threading.threadpool?view=netframework-4.8" target="_blank" rel="noopener noreferrer">https://docs.microsoft.com/en-us/dotnet/api/system.threading.threadpool?view=netframework-4.8</a>.</li>
</ul>]]></content>
        <author>
            <name>Niko</name>
            <uri>https://0xniko.dev</uri>
        </author>
        <category label="multi-thread" term="multi-thread"/>
        <category label="multi" term="multi"/>
        <category label="threading" term="threading"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Synchronous and asynchronous handling in javascript]]></title>
        <id>https://blog.0xniko.dev/2019/05/29/synchronous-and-asynchronous-in-javascript</id>
        <link href="https://blog.0xniko.dev/2019/05/29/synchronous-and-asynchronous-in-javascript"/>
        <updated>2019-05-29T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[synchronus/asynchronus vs multiple thread]]></summary>
        <content type="html"><![CDATA[<p>For web programmers, the concept of asynchronous (asynchronus) and synchronous (synchronus) is not too strange. However, there is a lot of confusion between synchronus/asynchronus and multiple threading. Let's analyze together!</p>
<h2 class="anchor anchorWithStickyNavbar_GVoy" id="whats-in-this-post">What's in this post?<a href="https://blog.0xniko.dev/2019/05/29/synchronous-and-asynchronous-in-javascript#whats-in-this-post" class="hash-link" aria-label="Direct link to What's in this post?" title="Direct link to What's in this post?">​</a></h2>
<div class="theme-admonition theme-admonition-tip admonition_SLCK alert alert--success"><div class="admonitionHeading_VYlH"><span class="admonitionIcon_TaVW"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>tip</div><div class="admonitionContent_HP_r"><ol>
<li>
<p>Understand the concept of synchronus/asynchronus.</p>
</li>
<li>
<p>Distinguish between synchronus/asynchronus and multiple thread multiple.
k</p>
</li>
<li>
<p>How is synchronus/asynchronus in javascript used?</p>
</li>
<li>
<p>Some common mistakes when using synchronus/asynchronus.</p>
</li>
</ol></div></div>
<h2 class="anchor anchorWithStickyNavbar_GVoy" id="what-is-synchronusasynchronus">What is synchronus/asynchronus?<a href="https://blog.0xniko.dev/2019/05/29/synchronous-and-asynchronous-in-javascript#what-is-synchronusasynchronus" class="hash-link" aria-label="Direct link to What is synchronus/asynchronus?" title="Direct link to What is synchronus/asynchronus?">​</a></h2>
<p>To understand these two concepts clearly, let's go from a real-life example, as follows: I load a news page for example, in which there is an image and the content of the article; and need to download the image from the server, but my file is quite heavy about <code>3Mb</code> plus my home network is a bit slow so it took me <code>5 minutes</code> to get the image.</p>
<p>According to the normal flow we will have 3 main actions as follows:</p>
<ol>
<li>
<p>Get file from server (5 minutes)</p>
</li>
<li>
<p>Show this picture on the screen</p>
</li>
<li>
<p>Next screen processing (maybe scroll content below, bla.bla...)</p>
</li>
</ol>
<p>If we execute sequentially <code>command 1</code> -&gt; <code>command 2</code> -&gt; <code>command 3</code> =&gt; at least <code>5 minutes</code>, we can scroll to read the content of the blog post.</p>
<p><em>This mechanism is called blocking</em></p>
<blockquote>
<p>Roughly blocking is a mechanism that freezes processes until they are unblocked. In this case the news page will be blocked until the image loads.</p>
</blockquote>]]></content>
        <author>
            <name>Niko</name>
            <uri>https://0xniko.dev</uri>
        </author>
        <category label="javascript" term="javascript"/>
        <category label="async" term="async"/>
        <category label="sync" term="sync"/>
    </entry>
</feed>