<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[ÇSTech - Medium]]></title>
        <description><![CDATA[Çiçeksepeti Tech - Medium]]></description>
        <link>https://medium.com/cstech?source=rss----a708e03ddc8a---4</link>
        <image>
            <url>https://cdn-images-1.medium.com/proxy/1*TGH72Nnw24QL3iV9IOm4VA.png</url>
            <title>ÇSTech - Medium</title>
            <link>https://medium.com/cstech?source=rss----a708e03ddc8a---4</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Fri, 13 Nov 2026 13:53:47 GMT</lastBuildDate>
        <atom:link href="https://medium.com/feed/cstech" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[Product Structure Transition: Seamless Migration from Legacy to New System]]></title>
            <link>https://medium.com/cstech/product-structure-transition-seamless-migration-from-legacy-to-new-system-5faad21bc7ca?source=rss----a708e03ddc8a---4</link>
            <guid isPermaLink="false">https://medium.com/p/5faad21bc7ca</guid>
            <category><![CDATA[e-commerce-solution]]></category>
            <category><![CDATA[product]]></category>
            <dc:creator><![CDATA[Anıl Terzi]]></dc:creator>
            <pubDate>Mon, 14 Apr 2025 07:26:03 GMT</pubDate>
            <atom:updated>2025-04-14T07:26:03.271Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*njmDLwI1SsZgaQiO" /></figure><h3>1. Introduction</h3><p>The major issues we encountered in our legacy system led us to initiate a transition to a new product structure. These issues included limitations in the product-seller relationship, data redundancy, management difficulties, constraints stemming from domain-specific design, and the risks associated with a shared database architecture. To address these problems, we launched a comprehensive migration project titled “New Product Structure.”</p><h3>2. Comparison of the Legacy and New Product Structures</h3><p>In our old system, a product could only be sold by a single seller. This meant that if multiple sellers wanted to offer the same product, it had to be duplicated in the system. In the new structure, this restriction was removed — allowing a single product to be sold by multiple sellers. This change introduced a more flexible sales model and enabled better stock and price management.</p><p>We also made significant improvements in product attributes and variant management. In the legacy system, tagging and customizable attributes were defined at the variant level, which led to unnecessary data duplication and management challenges. In the new structure, we elevated these attributes to the product level, thereby reducing redundancy and simplifying administration.</p><p>Another major change involved image management. Previously, images had to be defined per variant, which complicated the user experience, bloated the database, and caused storage inefficiencies. We centralized image management at the product level to resolve these issues.</p><p>Category-based product management was one of the most critical changes. With category-specific attributes, products were split based on these features. For example, in a category with a “color” attribute, each color was defined as a separate product. This approach allowed for easier management of product visuals and attributes while providing sellers with greater flexibility in listing products.</p><p>We also restructured our database. Previously, a shared legacy MSSQL database was used, exposing our system to issues caused by other domains. We moved to an isolated architecture using a MySQL database, eliminating this risk.</p><p>Significant changes were also made in integration management. While the old system relied on direct integration, the new system introduced an adapter layer. This allowed integrators to transition seamlessly without requiring any changes on their end.</p><p>Domain flexibility was another area of improvement. The legacy system was tightly coupled with the flower domain, making it difficult to adapt to the marketplace domain. The new structure was designed to accommodate the needs of both domains efficiently.</p><h3>3. Migration Project Details</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*AHUGG1xzcSjRI7lF" /></figure><p>The migration project was developed using .NET 8 and employed Hangfire for job management, with Redis used for Hangfire storage. The primary goal was to transform millions of product records from the legacy MSSQL database into the new structure.</p><p>The migration process consisted of two main phases. In the first phase, products were segmented based on category-specific attributes and transferred to the new schema. During this process, image migration and storage optimization were also conducted.</p><p>The second phase involved continuous synchronization. Changes in the legacy system were tracked using timestamps and replicated into the new system. A table-specific job system enabled low-latency synchronization.</p><p>Each table had a custom-designed job. Using a recurring job structure, continuous syncing was ensured. A retry mechanism was implemented for failure scenarios, and data was processed in chunks for performance optimization. Errors were logged in a structured table, allowing us to analyze and resolve issues observed during testing. Ensuring clean data in the new system was one of the most critical aspects of the migration.</p><p>Cross-domain interactions were another important topic. To update related domains such as promotions and advertising, a dedicated job system was developed. This ensured that changes in product structures were reflected across all dependent systems.</p><p>To minimize load on the production database, various optimization strategies were applied. A chunk-based processing model using IDs and timestamps was implemented, allowing for controlled, incremental data transfers. This significantly reduced the impact on the live environment.</p><h3>4. Transition and Go-Live Process</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*naibkNMwO8GbTGZE" /></figure><p>A go-live date was set and communicated to all relevant teams. Dependency analysis was conducted to determine which services could be transitioned independently. Services without dependencies were launched ahead of the migration; dependent services were migrated in sync.</p><p>As part of the versioning strategy, endpoint versioning was introduced in shared services. Separate endpoints were maintained for both legacy and new structures to ensure a seamless transition and reduce interdependencies.</p><p>Prior to the go-live, sellers and integrators were informed. Product creation and updates were temporarily halted, while critical operations like stock and price updates continued. Incoming price and stock update requests were queued and processed with minimal delay during the transition.</p><p>Throughout the migration, database synchronization and service transitions were carefully coordinated. User experience remained uninterrupted, with only minor downtime observed for product creation and updates.</p><p>Extensive quality assurance processes were followed, including high test coverage and rigorous testing procedures. Load and performance tests were conducted, ensuring the system was fully prepared for high-traffic scenarios, such as during special campaigns.</p><h3>5. Results and Gains</h3><p>This project provided invaluable experience in managing and executing large-scale transformations. Over several months, multiple teams collaborated across dozens of services in a coordinated effort.</p><p>The isolated database structure helped prevent external service outages from impacting our domain — addressing a major risk posed by the shared legacy database.</p><p>Adopting a Domain-Driven Design approach allowed us to clearly define domain rules and bounded contexts. Hundreds of business rules were documented, and the common language developed between analysts and engineers enabled smoother communication with business stakeholders.</p><p>We also made significant strides in documentation and knowledge management. Dozens of technical and analysis documents were prepared. Updated documentation for users and integrators made adoption easier. These documents are expected to significantly reduce the onboarding time for new team members.</p><p>The project also delivered technical and cost-related gains through data deduplication and storage optimization:</p><ul><li>Legacy shared database size reduced by 65%</li><li>Disk usage on storage systems dropped by 20%, reducing costs</li><li>Monthly database costs decreased noticeably</li></ul><p>Performance improvements were another key outcome:</p><ul><li>API response times improved by an average of 35%</li><li>Database query performance increased by 30%</li></ul><p>From a development and maintenance perspective, we now have a cleaner, more modern codebase:</p><ul><li>Code duplication significantly reduced</li><li>Full test coverage achieved across all systems</li><li>Average bug fix time shortened</li><li>Noticeable improvements in the development of new features</li></ul><p>Overall, the project was a success in both execution and outcome. There was no data loss, no system downtime, and no need for rollback.</p><p>This migration fostered confidence and experience for future large-scale projects. 95% of team members reported high satisfaction with the project and expressed greater readiness for similar challenges ahead.</p><p>With this article, we aimed to provide a detailed account of how to plan and execute a major system migration, the challenges encountered, and the successes achieved. We hope our insights will guide other teams undertaking similar transitions — both from a technical and organizational perspective.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=5faad21bc7ca" width="1" height="1" alt=""><hr><p><a href="https://medium.com/cstech/product-structure-transition-seamless-migration-from-legacy-to-new-system-5faad21bc7ca">Product Structure Transition: Seamless Migration from Legacy to New System</a> was originally published in <a href="https://medium.com/cstech">ÇSTech</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Ürün Yapısı Geçişi: Eski Sistemden Yeni Sisteme Kesintisiz Geçiş]]></title>
            <link>https://medium.com/cstech/%C3%BCr%C3%BCn-yap%C4%B1s%C4%B1-ge%C3%A7i%C5%9Fi-eski-sistemden-yeni-sisteme-kesintisiz-ge%C3%A7i%C5%9F-01760eb4e03e?source=rss----a708e03ddc8a---4</link>
            <guid isPermaLink="false">https://medium.com/p/01760eb4e03e</guid>
            <category><![CDATA[e-commerce-solution]]></category>
            <category><![CDATA[product]]></category>
            <dc:creator><![CDATA[Anıl Terzi]]></dc:creator>
            <pubDate>Mon, 14 Apr 2025 07:25:28 GMT</pubDate>
            <atom:updated>2025-04-14T07:25:28.642Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*ebgWVtMxZzXJCxZM" /></figure><p><strong>1. Giriş</strong></p><p>Eski sistemimizde karşılaştığımız temel sorunlar, bizi yeni bir ürün yapısına geçiş yapmaya yönlendirdi. Bu sorunlar arasında ürün-bayi ilişkisindeki kısıtlamalar, veri tekrarı ve yönetim zorlukları, domain özgü tasarımın getirdiği sınırlamalar ve ortak veritabanı kullanımının riskleri bulunuyordu. Bu sorunların çözümü için “Yeni Ürün Yapısı” adın verdiğimiz kapsamlı bir geçiş projesi başlattık.</p><p><strong>2. Eski ve Yeni Ürün Yapısının Karşılaştırması</strong></p><p>Eski sistemimizde, bir ürün sadece bir bayi tarafından satılabiliyordu. Bu durum, aynı ürünü farklı bayilerin satmak istemesi durumunda sisteme aynı ürünün tekrar eklenmesini gerektiriyordu. Yeni yapımızda bu kısıtlama kaldırıldı ve bir ürün birden fazla bayi tarafından satılabilir hale geldi. Bu değişiklik, daha esnek bir satış modeli ve daha iyi stok-fiyat yönetimi imkanı sağladı.</p><p>Ürün özellikleri ve varyant yönetimi konusunda da önemli değişiklikler yaptık. Eski sistemde tagleme ve kişiselleştirilebilir özellikler varyant seviyesinde tanımlanıyordu. Bu durum, veritabanında gereksiz veri tekrarına ve yönetim zorluklarına yol açıyordu. Yeni yapımızda bu özellikleri ürün seviyesine taşıdık, böylece veri tekrarını önleyerek yönetimi kolaylaştırdık.</p><p>Ürün görsellerinin yönetimi de önemli bir değişiklik alanıydı. Eski sistemde her varyant için ayrı görsel tanımlanması gerekiyordu. Bu durum, kullanıcılar için zorluk yaratıyor, veritabanında gereksiz veri oluşturuyor ve storage tarafında sorunlara yol açıyordu. Yeni yapımızda görselleri ürün seviyesine taşıdık, böylece bu sorunları çözdük.</p><p>Kategori bazlı ürün yönetimi, yeni yapımızın en önemli değişikliklerinden biriydi. Kategori bazlı tanımlanan ürün özellikleri ile birlikte, ürünler bu özelliklere göre parçalandı. Örneğin, renk özelliği olan bir kategoride, her renk ayrı bir ürün olarak tanımlandı. Bu yaklaşım, görsel ve ürün özelliklerinin kolay yönetilmesini sağladı ve bayilerin ürün satışında daha esnek olmasına olanak tanıdı.</p><p>Veritabanı yapımızda da önemli değişiklikler yaptık. Eski sistemde legacy MSSQL veritabanını ortak olarak kullanıyorduk. Bu durum, diğer domainlerde yaşanan sorunların bizim sistemimizi de etkileme riskini taşıyordu. Yeni yapımızda MySQL veritabanına geçiş yaparak izole bir yapı oluşturduk ve bu riski ortadan kaldırdık.</p><p>Entegrasyon yönetiminde de önemli değişiklikler yaptık. Eski sistemde doğrudan entegrasyon kullanıyorduk, yeni yapımızda ise adaptör katmanı ekledik. Bu değişiklik, geçiş sürecinde entegratörlerin hiçbir değişiklik yapmasına gerek kalmadan sorunsuz bir geçiş sağladı.</p><p>Domain esnekliği konusunda da önemli iyileştirmeler yaptık. Eski sistem çiçek domainine özel tasarlanmıştı ve marketplace domainine uyarlamada zorluklar yaşıyorduk. Yeni yapımız hem çiçek hem de marketplace domaininin ihtiyaçlarına cevap verebilecek şekilde tasarlandı.</p><p><strong>3. Migration Projesinin Detayları</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*_uDhY7-fJ6Yc_zgy" /></figure><p>Migration projemiz, .NET 8 tabanlı olarak geliştirildi ve job yönetimi için Hangfire kullanıldı. Hangfire storage olarak Redis tercih edildi. Projenin temel amacı, legacy MSSQL veritabanında bulunan milyonlarca ürün verisini yeni yapıya uygun şekilde dönüştürmekti.</p><p>Migration süreci iki ana aşamadan oluşuyor. İlk aşamada, ürünlerin kategori bazlı özelliklere göre parçalanması ve yeni tablo yapısına aktarılması gerçekleştirildi. Bu süreçte görsel transferi ve storage optimizasyonu da yapıldı.</p><p>İkinci aşamada ise sürekli senkronizasyon süreci başladı. Bu süreçte, legacy sistemdeki değişiklikler timestamp bazlı olarak takip edildi ve yeni sisteme aktarıldı. Tablo bazlı job sistemi sayesinde düşük latency ile senkronizasyon sağlandı.</p><p>Job sistemi, her tablo için özel olarak tasarlandı. Recurring job yapısı kullanılarak sürekli senkronizasyon sağlandı. Hata durumları için retry mekanizması eklendi ve performans optimizasyonu için veriler parçalı olarak işlendi. Hata alan jobların incelenmesi için hata senaryoları maddelere ayrılarak bir tabloya loglandı. Böylece migration sürecinde yaptığımız denemelerde yaşanan sorunları madde bazlı görerek gerekli veri düzenlemelerini sağladık. Yeni yapıya temiz bir veri ile geçişin en önemli kısımlarından biri buydu.</p><p>Çapraz domain etkileşimleri de önemli bir konuydu. Reklam ve indirim gibi diğer domainlerin güncellenmesi için ayrı bir job sistemi oluşturuldu. Bu sayede parçalanan ürünlerin diğer sistemlerdeki yansımaları da güncellendi.</p><p>Teknik çözümler ve optimizasyonlar kapsamında, canlıda bulunan veritabanı yükünü minimize etmek için çeşitli stratejiler geliştirildi. ID ve timest bazlı parçalı veri işleme yaklaşımı benimsendi. Bu sayede parçalamalar ve gelen güncellemeler parçalı bir şekilde eski veritabanından alınarak yeni veritabanına yansıtıldı. Eski ve canlıda aktif görev alan veritabanına getirilen yükün en alt seviyede tutulması amaçlandı.</p><p><strong>4. Geçiş Süreci ve Canlıya Alma</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*fcuM0j2VoDSgIPL_" /></figure><p>Geçiş süreci için bir tarih belirlendi ve tüm ilgili ekiplere bilgi verildi. Ekipler arasında bağımlılık analizi yapıldı ve bağımlılık olmayan servisler geçişten önce canlıya alındı. Bağımlılık olan servisler ise senkronize olarak canlıya alındı.</p><p>Versiyonlama stratejisi kapsamında, ortak servislerde endpoint versiyonlaması yapıldı. Eski ve yeni yapı için ayrı endpoint versiyonları oluşturuldu. Bu sayede kesintisiz geçiş sağlandı ve bağımlılık minimizasyonu sağlandı.</p><p>Geçiş öncesi son hazırlıklar kapsamında, bayi ve entegratörlere bilgilendirme yapıldı. Ürün açma ve güncelleme işlemleri geçici olarak durduruldu, ancak kritik işlemler olan fiyat ve stok güncellemeleri devam etti. Gelen fiyat ve stok istekleri geçiş esnasında kuyruk sisteminde toplanarak dakikalar seviyesinde gecikmeli olarak işlendi.</p><p>Geçiş süreci boyunca veritabanı senkronizasyonu ve servis geçişleri koordineli bir şekilde yönetildi. Kullanıcı deneyiminde kesintisizlik sağlandı, sadece ürün açma ve güncelleme işlemlerinde kısa süreli bir kesinti yaşandı.</p><p>Kalite ve test güvencesi kapsamında, yüksek test coverage oranları ve kapsamlı test süreçleri uygulandı. Yük testleri ve performans analizleri yapıldı. Yapılan yük testleri ve performans analizleri sayesinde live geçişinden sonra bir sürpriz ile karşılaşma durumu yaşanmadı. Özel gün gibi çok yük beklediğimiz senaryoları da bu yük testleri sayesinde deneme fırsatı bulduk ve gerekli aksiyonları bularak tüm senaryolara hazır halde geçiş sürecini tamamladık.</p><p><strong>5. Sonuçlar ve Kazanımlar</strong></p><p>Bu proje, ekip olarak büyük ölçekli projelerin nasıl yönetileceği ve planlanacağı konusunda önemli deneyimler kazanmamızı sağladı. Aylarca süren yoğun bir çalışma sürecinde, onlarca farklı servis üstünde tüm ekipler koordineli olarak çalıştı.</p><p>İzole edilmiş veritabanı yapısı sayesinde dış kaynaklı kesintilerin önüne geçtik. Geçiş öncesi ortak veritabanı kullanımından dolayı yaşanabilecek olası bir kesintinin önüne geçmiş olduk.</p><p>Domain-Driven Design yaklaşımını benimseyerek, domain kurallarını net bir şekilde belirledik ve bounded context’leri doğru şekilde tanımladık. Bu süreçte yüzlerce farklı domain kuralı belirlendi. Bounded contextler tanımlandı. Analist ve development ekiplerinin ortak dili sayesinde, iş birimleriyle daha iyi iletişim kurabildik.</p><p>Dokümantasyon ve bilgi yönetimi konusunda da önemli adımlar attık. Sayfalarca teknik dokümantasyon ve analiz dökümanları hazırlandı. Kullanıcılara ve entegratörlere verdiğimiz dokümanlar güncellenerek kullanım kolaylığı sağlandı Bu dokümantasyonlar sayesinde, yeni ekip üyelerinin domaine adaptasyon sürecinde gözle görülür derecede bir düşüş bekliyoruz.</p><p>Teknik ve maliyet kazanımları açısından, veri tekrarının önlenmesi ve storage optimizasyonu sayesinde önemli maliyet düşüşleri sağladık:</p><p>- Ortak kullanılan legacy veritabanı boyutu %65 azaldı</p><p>- Storage tarafında disk kullanımı %20 düştü ve maliyetleri azaldı.</p><p>- Aylık veritabanı maliyetleri belirli bir oranda azaldı.</p><p>Performans artışı da önemli kazanımlarından biri oldu:</p><p>- API yanıt süreleri ortalama %35 iyileşti</p><p>- Veritabanı sorgu performansı %30 arttı</p><p>Geliştirme ve bakım kolaylığı açısından, daha temiz ve modern bir kod base’e sahip olduk:</p><p>- Kod tekrarı ciddi oranda azaldı.</p><p>- Test coverage oranı olarak otomasyon testi yazılmayan sistemimiz kalmadı.</p><p>- Ortalama bug fix süremiz kısaldı</p><p>- Yeni özellik geliştirme sürecinde gözle görülür bir fark gözlemlendi.</p><p>Genel değerlendirmede, kesintisiz geçiş başarısı ve ekip olarak başarı duygusu öne çıktı. Geçiş sürecinde veri kaybı, sistem kesintisi yaşanmadı ve herhangi bir rollback ihtiyacı duyulmadı.</p><p>Bu proje, gelecek projeler için güven artışı ve tecrübe kazanımı sağladı. Ekip üyelerinin %95&#39;i projeden memnuniyetini belirtti ve benzer büyüklükteki projelerde çalışma konusunda kendilerini daha hazır hissettiklerini ifade ettiler.</p><p>Bu makalede, büyük ölçekli bir sistem geçişinin nasıl planlanıp yürütülebileceğini, karşılaşılan zorlukları ve elde edilen başarıları detaylı bir şekilde ele almayı amaçladık. Hem teknik hem de organizasyonel açıdan dikkat ettiğimiz ve yaşadığımız süreçlerin benzer geçiş süreçleri planlayan ekiplere yol gösterici olmasını umuyoruz.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=01760eb4e03e" width="1" height="1" alt=""><hr><p><a href="https://medium.com/cstech/%C3%BCr%C3%BCn-yap%C4%B1s%C4%B1-ge%C3%A7i%C5%9Fi-eski-sistemden-yeni-sisteme-kesintisiz-ge%C3%A7i%C5%9F-01760eb4e03e">Ürün Yapısı Geçişi: Eski Sistemden Yeni Sisteme Kesintisiz Geçiş</a> was originally published in <a href="https://medium.com/cstech">ÇSTech</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Writing Clean Code in JavaScript: Tips and Tricks]]></title>
            <link>https://medium.com/cstech/writing-clean-code-in-javascript-tips-and-tricks-fe8721456f66?source=rss----a708e03ddc8a---4</link>
            <guid isPermaLink="false">https://medium.com/p/fe8721456f66</guid>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[clean-code]]></category>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[coding]]></category>
            <dc:creator><![CDATA[Oguzhan Yuksel]]></dc:creator>
            <pubDate>Mon, 16 Dec 2024 11:02:23 GMT</pubDate>
            <atom:updated>2024-12-16T11:02:23.196Z</atom:updated>
            <content:encoded><![CDATA[<p>Clean code is the foundation of maintainable and scalable software. In this article, I’ll share practical tips and tricks for writing clean JavaScript code, based on techniques I rely on daily in my development process.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/640/1*VXAEycgOhRE4kR2kfsr_5A.jpeg" /><figcaption>Source: <a href="https://www.codeprinciples.com/2020/11/clean-code-introduction.html">https://www.codeprinciples.com/2020/11/clean-code-introduction.html</a></figcaption></figure><p>Initially, it might be complex to understand and hard to carry out. However, when you get used to it, you start to implement it autonomously.</p><p>These usages will make your code more readable, understandable, and reliable in the long term. Not only for other developers but especially also for you.</p><h3>1. Use Meaningful Variable and Function Names</h3><p>Always choose descriptive names that clearly reflect the purpose of the variable or function. Avoid vague names like a, b, or temp. The more meaningful the name, the easier it is for others (and yourself) to understand the code. For instance, instead of naming a variable x, name it something like totalPrice or itemCount to make its purpose obvious. Additionally, use camelCase for variable names and PascalCase for function and class names to follow common JavaScript conventions.</p><pre>// Bad<br>let a = 5;<br>function doSomething() {<br>  return a * 2;<br>}<br><br>// Good<br>let numberOfItems = 5;<br>function calculateTotalPrice() {<br>  return numberOfItems * 2;<br>}</pre><h4>Pros of Using Meaningful Names:</h4><ul><li><strong>Readability:</strong> Code is easier to understand and follow.</li><li><strong>Maintainability:</strong> Developers can update the code more efficiently.</li><li><strong>Reduced Comments:</strong> Fewer comments are needed to explain what variables or functions do.</li></ul><h4>Cons of Using Poor Names:</h4><ul><li><strong>Confusing Code:</strong> Vague names make the code harder to interpret.</li><li><strong>Increased Maintenance Costs:</strong> More time spent deciphering variable meanings.</li><li><strong>Error-Prone:</strong> Hard-to-understand code leads to mistakes during development.</li></ul><h3>2. Keep Functions Small and Focused</h3><p>Functions should perform a single task and ideally fit within a few lines of code. If a function grows too large or starts performing multiple tasks, consider refactoring it into smaller, more manageable functions. This improves the clarity of the code and enhances reusability. Smaller functions also make it easier to write unit tests.</p><p>However, it should not be forgotten that this is not 100% possible in some cases due to the complexity of the work. We can accept these as exceptions.</p><pre>// Bad<br>function processOrder(order) {<br>  processPayment(order);<br>  updateInventory(order);<br>  sendConfirmationEmail(order);<br>}<br><br>// Good<br>function processPayment(order) {<br>  // logic for payment<br>}<br><br>function updateInventory(order) {<br>  // logic for inventory<br>}<br><br>function sendConfirmationEmail(order) {<br>  // logic for email<br>}</pre><h4>Pros of Small, Focused Functions:</h4><ul><li><strong>Code Reusability:</strong> Functions can be reused in different parts of the project.</li><li><strong>Testability:</strong> Smaller functions are easier to test individually.</li><li><strong>Maintainability:</strong> Modular functions simplify debugging and updating.</li></ul><h4>Cons of Large, Unfocused Functions:</h4><ul><li><strong>Difficult Debugging:</strong> Larger functions are harder to trace for bugs.</li><li><strong>Complex Codebase:</strong> Mixed responsibilities lead to confusing and messy code.</li><li><strong>Low Reusability:</strong> Functions that try to do too much are less reusable.</li></ul><h3>3. Use Constants for Magic Numbers</h3><p>Avoid using hard-coded numbers, commonly known as <strong>“magic numbers”</strong> throughout your code. Instead, define them as constants with descriptive names. This improves readability and makes it easier to update values across the codebase.</p><p><strong>Additional Tip:</strong> You can create enum or constant files for overused values over the project rather than file-related constants.</p><pre>// Bad<br>let tax = price * 0.15;<br><br>// Good<br>const TAX_RATE = 0.15;<br>let tax = price * TAX_RATE;</pre><h4>Pros of Using Constants:</h4><ul><li><strong>Readability:</strong> Constants clearly describe the purpose of the value.</li><li><strong>Easy Updates:</strong> Changing the constant value updates it everywhere in the code.</li><li><strong>Reduced Errors:</strong> Prevents hard-to-find bugs caused by number misuse.</li></ul><h4>Cons of Using Magic Numbers:</h4><ul><li><strong>Confusing Logic:</strong> Direct numbers can be hard to interpret.</li><li><strong>Error-Prone:</strong> Changes require searching and updating multiple occurrences.</li><li><strong>Poor Documentation:</strong> Readers won’t know what a number represents without additional context.</li></ul><h3>4. Avoid Nested Loops and Conditionals</h3><p>If your code has deeply nested loops or conditionals, it’s a good idea to refactor it. Such nested structures are difficult to follow and increase the risk of bugs. You can often flatten the logic using helper functions, early returns, or array methods like .filter() and .map().</p><pre>// Bad<br>for (let i = 0; i &lt; items.length; i++) {<br>  for (let j = 0; j &lt; orders.length; j++) {<br>    if (items[i].id === orders[j].itemId) {<br>      processOrder(items[i]);<br>    }<br>  }<br>}<br><br>// Good<br>const itemOrders = orders.filter(order =&gt; items.some(item =&gt; item.id === order.itemId));<br>itemOrders.forEach(order =&gt; processOrder(order));</pre><h4>Pros of Avoiding Nested Structures:</h4><ul><li><strong>Better Readability:</strong> Code is cleaner and easier to follow.</li><li><strong>Lower Complexity:</strong> Fewer nested structures simplify the logic.</li><li><strong>Reduced Bug Risk:</strong> Less nested code means fewer opportunities for logic errors.</li></ul><h4>Cons of Using Nested Structures:</h4><ul><li><strong>Harder Maintenance:</strong> Deep nesting is difficult to modify or extend.</li><li><strong>Reduced Performance:</strong> Extra processing can slow down the program.</li><li><strong>Bug-Prone Logic:</strong> Complex nesting increases the risk of logic mistakes.</li></ul><h3>5. Use Arrow Functions for Simplicity</h3><p>Arrow functions offer a concise way to write functions, especially for callbacks or functions with a single expression. They also preserve the context of this, which can avoid common pitfalls in traditional function expressions.</p><blockquote>If the function is gold, the arrow function is a diamond.</blockquote><pre>// Bad<br>let numbers = [1, 2, 3];<br>let doubled = numbers.map(function(num) {<br>  return num * 2;<br>});<br><br>// Good<br>let doubled = numbers.map(num =&gt; num * 2);</pre><h4>Pros of Using Arrow Functions:</h4><ul><li><strong>Cleaner Syntax:</strong> Code looks simpler and more readable.</li><li><strong>Shorter Code:</strong> Fewer lines are needed for function declarations.</li><li><strong>No </strong><strong>this Binding Issues:</strong> Arrow functions inherit this from their enclosing context.</li></ul><h4>Cons of Misusing Arrow Functions:</h4><ul><li><strong>Limited Use Cases:</strong> Arrow functions are unsuitable for defining class methods or object methods.</li><li><strong>Overuse in Complex Logic:</strong> Using arrow functions in complex logic can reduce clarity.</li><li><strong>Not Hoisted:</strong> Unlike function declarations, arrow functions are not hoisted.</li></ul><h3>6. Use Template Literals Instead of String Concatenation</h3><p>Template literals allow you to embed expressions directly into strings, making the code more readable and less error-prone than string concatenation.</p><p>Additional information, if you do start to develop with linter, it will already be angry on every String Concatenation usage in case you don’t fix or turn off the warning.</p><pre>// Bad<br>let message = &#39;Hello &#39; + userName + &#39;, you have &#39; + itemCount + &#39; items in your cart.&#39;;<br><br>// Good<br>let message = `Hello ${userName}, you have ${itemCount} items in your cart.`;</pre><h4>Pros of Using Template Literals:</h4><ul><li><strong>Improved Readability:</strong> String construction is clearer and easier to follow.</li><li><strong>Dynamic Content:</strong> Easily embed variables and expressions.</li><li><strong>Reduced Errors:</strong> Less risk of missing spaces or incorrect syntax.</li></ul><h4>Cons of Using String Concatenation:</h4><ul><li><strong>Harder to Read:</strong> Concatenation creates long, hard-to-follow strings.</li><li><strong>Error-Prone:</strong> Easy to miss spaces or add incorrect punctuation.</li><li><strong>Poor Maintainability:</strong> Long strings are hard to adjust or update.</li></ul><h3>7. Commenting and Documentation</h3><p>While clean code should largely speak for itself, comments can be used to clarify non-obvious logic or complex algorithms. Use comments sparingly and focus on why something is being done, rather than what is being done.</p><pre>// Bad<br>let x = 5; // initialize x<br><br>// Good<br>// The following variable stores the price of the item after tax is applied<br>let priceWithTax = price * (1 + TAX_RATE);</pre><h4>Pros of Writing Clear Comments:</h4><ul><li><strong>Better Collaboration:</strong> Team members understand code intentions quickly.</li><li><strong>Reduced Learning Curve:</strong> New developers can grasp project logic faster.</li><li><strong>Easier Debugging:</strong> Proper comments can explain tricky logic or workarounds.</li></ul><h4>Cons of Poor or Excessive Comments:</h4><ul><li><strong>Cluttered Code:</strong> Too many comments make code harder to read.</li><li><strong>Outdated Information:</strong> Comments can become inaccurate over time if not updated.</li><li><strong>Reduced Focus:</strong> Over-commenting can shift focus from reading the actual code.</li></ul><h3>8. Use Destructuring</h3><p>Destructuring provides a shorthand syntax for extracting values from arrays or objects and assigning them to variables. It makes the code more concise and easier to read.</p><pre>// Bad<br>let person = { name: &#39;John&#39;, age: 30 };<br>let name = person.name;<br>let age = person.age;<br><br>// Good<br>let { name, age } = person;</pre><h4>Pros of Using Destructuring:</h4><ul><li><strong>Readable Code:</strong> Property extraction is clear and explicit.</li><li><strong>Reduced Boilerplate:</strong> Less repetitive code for variable declarations.</li><li><strong>Better Maintainability:</strong> Code updates are simpler when adding or removing properties.</li></ul><h4>Cons of Not Using Destructuring:</h4><ul><li><strong>Repetitive Code:</strong> Multiple variable declarations make code verbose.</li><li><strong>Harder to Follow:</strong> Readers may struggle to track property assignments.</li><li><strong>Increased Errors:</strong> Manually accessing properties is prone to typos and logical errors.</li></ul><h3>9. Use Proper Error Handling</h3><p>Effective error handling prevents your application from crashing and helps identify bugs faster. Use try...catch blocks, error messages, and logging to gracefully manage unexpected issues. Avoid using generic error messages like &quot;Something went wrong&quot;; instead, provide meaningful messages and log the specific error details for debugging. Additionally, consider creating custom error classes to handle various error types systematically.</p><pre>// Bad: No error handling<br>function fetchData(url) {<br>  const response = fetch(url); <br>  const data = response.json(); <br>  console.log(data); <br>}<br><br>// Good: Proper error handling<br>async function fetchData(url) {<br>  try {<br>    const response = await fetch(url); <br>    if (!response.ok) {<br>      throw new Error(`HTTP Error: ${response.status}`);<br>    }<br>    const data = await response.json(); <br>    console.log(data); <br>  } catch (error) {<br>    console.error(`Failed to fetch data: ${error.message}`);<br>  }<br>}</pre><h4>Pros of Proper Error Handling:</h4><ul><li><strong>Improved Debugging:</strong> Errors are easier to diagnose when detailed messages are logged.</li><li><strong>Better User Experience:</strong> Users are notified gracefully without application crashes.</li><li><strong>Enhanced Security:</strong> Proper handling prevents the display of sensitive system information to users.</li></ul><h4>Cons of Poor Error Handling:</h4><ul><li><strong>Hard-to-Debug Issues:</strong> Lack of clear messages can lead to extended troubleshooting.</li><li><strong>App Crashes:</strong> Unhandled exceptions may cause the application to stop working entirely.</li><li><strong>Security Risks:</strong> Revealing internal system details in public error messages can expose vulnerabilities.</li></ul><h3>10. Bonus: Consistent Formatting ( ESLint &amp; Prettier )</h3><p>Always follow a consistent code style, including indentation, spacing, and semicolon usage. Tools like <strong>Prettier</strong> or <strong>ESLint</strong> can help automate this and ensure consistency across your codebase.</p><pre>// Bad<br>function greet(name){<br>console.log(&#39;Hello, &#39; + name);<br>}<br><br>// Good<br>function greet(name) {<br>  console.log(`Hello, ${name}`);<br>}</pre><h4>Pros of Consistent Formatting:</h4><ul><li><strong>Professional Appearance:</strong> Well-formatted code looks professional.</li><li><strong>Better Collaboration:</strong> Consistency makes it easier for teams to work together.</li><li><strong>Faster Debugging:</strong> Standardized structure simplifies debugging and reading.</li></ul><h4>Cons of Inconsistent Formatting:</h4><ul><li><strong>Harder Collaboration:</strong> Inconsistent style leads to confusion among team members.</li><li><strong>Reduced Readability:</strong> Misaligned code is harder to understand.</li><li><strong>Longer Development Time:</strong> Developers waste time reformatting code manually.</li></ul><p>There are many more ways to write cleaner codes. But these are mostly used and experienced by many developers. You will encounter these examples a lot while browsing through Github repos.</p><p>However, it should not be forgotten that none of the above-mentioned items include an approach such as the <strong>‘it must be used like this’ </strong>topic. The complexity of the structure, the team’s project development habits, and the requirements of the task will determine the needs.</p><p>Until next time, take care! 👋</p><h3>Additional Part</h3><p>You can reach me through the channels below,</p><p><a href="https://www.linkedin.com/in/developeroguzyuksel/"><strong>LinkedIn</strong></a><strong> | </strong><a href="https://github.com/ooguzyuksel"><strong>GitHub</strong></a><strong> | </strong><a href="https://oguzhan-yuksel.vercel.app/"><strong>Personal Website</strong></a></p><p>Oğuzhan YÜKSEL</p><p>Frontend Developer at <a href="https://medium.com/u/ef0a84cf7f9d?source=post_page---user_mention--17969795fa73--------------------------------">ÇSTech</a></p><h3>📖 Useful Sources:</h3><p><a href="https://github.com/ryanmcdermott/clean-code-javascript">GitHub - ryanmcdermott/clean-code-javascript: Clean Code concepts adapted for JavaScript</a></p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2Fb9c5GmmS7ks%3Flist%3DPLWKjhJtqVAbkK24EaPurzMq0-kw5U9pJh&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3Db9c5GmmS7ks&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2Fb9c5GmmS7ks%2Fhqdefault.jpg&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/9a88c7a104271fb12d952fcd0372abb6/href">https://medium.com/media/9a88c7a104271fb12d952fcd0372abb6/href</a></iframe><p><a href="https://www.amazon.com/Clean-Code-JavaScript-reliable-maintainable/dp/1789957648">Clean Code in JavaScript</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=fe8721456f66" width="1" height="1" alt=""><hr><p><a href="https://medium.com/cstech/writing-clean-code-in-javascript-tips-and-tricks-fe8721456f66">Writing Clean Code in JavaScript: Tips and Tricks</a> was originally published in <a href="https://medium.com/cstech">ÇSTech</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[The Impact of Cultural Diversity on E-commerce Designs — Part 1]]></title>
            <link>https://medium.com/cstech/the-impact-of-cultural-diversity-on-e-commerce-designs-part-1-3397592b208f?source=rss----a708e03ddc8a---4</link>
            <guid isPermaLink="false">https://medium.com/p/3397592b208f</guid>
            <category><![CDATA[culture]]></category>
            <category><![CDATA[e-commerce-website-design]]></category>
            <category><![CDATA[e-commerce-ux]]></category>
            <category><![CDATA[ux-research]]></category>
            <category><![CDATA[culture-differences]]></category>
            <dc:creator><![CDATA[Elif Yardımcı]]></dc:creator>
            <pubDate>Fri, 29 Dec 2023 13:08:19 GMT</pubDate>
            <atom:updated>2023-12-29T13:08:18.919Z</atom:updated>
            <content:encoded><![CDATA[<h3>The Impact of Cultural Diversity on E-commerce Designs — Part 1</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*xCeG3lXKW_yoUBOTDlhKkA.gif" /></figure><p>As someone working in the e-commerce sector, my curiosity about understanding the diversity in the e-commerce experiences of users from different cultures has solidified with a desire to conduct thorough research. Through sharing the information obtained from this research, I will describe the impact of culture on the e-commerce sector.</p><p>To remain competitive, e-commerce companies today need to develop strategies for sustainability and growth in local and global markets. In this competitive environment, the designs and user experiences of e-commerce platforms should be adapted to the cultural context of the targeted geography. In this article series, we will emphasize the importance of cultural differences in e-commerce designs and look at how these interactions affect design.</p><p>As of January 2023, the 5.16 billion internet users worldwide constitute a significant part of global online shopping, with 56.5% of internet users aged 16 to 64 making online purchases weekly. [1] This statistic indicates that most individuals with internet access engage in online shopping, highlighting the expansion of user bases on e-commerce platforms and their coverage of a large segment of potential customers.</p><p>To make this large-scale e-commerce experience more effective, design factors, especially language and culture, should be considered. While 58.8% of global websites provide services in English, the question of how many in the global population can understand these English sites is crucial. Unfortunately, this ratio is quite low, as only 6% of the global population speaks English as their native language, and 75% do not speak English at all. [2] In this context, design processes should consider not only English but also other languages and cultures. Understanding cultural diversity and language differences will make the e-commerce experience more inclusive and effective on a global scale.</p><h4><strong>Connection Between Language and Culture</strong></h4><p>Language is a tool that provides information about a community’s values, beliefs, and habits. The words, expressions, and grammar rules used form a cultural identity by reflecting the worldview of that community. Therefore, communication in a language should be culturally appropriate for the culture in which the language is spoken.</p><p>E-commerce companies should pay attention not only to the grammatical rules of a language but also to the cultural context of that language when designing their platforms. It is essential to align many elements, from color choices to symbolism, page layout to content tone, with the cultural expectations of the target audience. For example, the symbolic meanings of colors used on an e-commerce site in an Asian country can vary based on cultural beliefs in that region. Similarly, the addressing style and content tone in a language should show respect for the target audience’s values.</p><p>In the upcoming sections of this article series, I will delve into specific topics by categorizing areas differentiated by culture and explore in detail the impacts of cultural differences on these elements.</p><p><strong>Color Usage: </strong>Colors play a significant role in intercultural communication as each culture attributes different symbolism to colors, triggering specific emotional responses. In this section, we will examine in detail the effects of color palettes used on e-commerce sites in cultural contexts. For instance, we will explore how a color may have positive connotations in one culture while being perceived differently in another.</p><p><strong>Page Layout: </strong>Page layout has a substantial impact on the usability of an e-commerce site. However, expectations for page layout may differ across cultures. In this section, we will analyze the effects of different cultures on page layout preferences. For example, we will identify differences between Eastern and Western cultures regarding page layout expectations.</p><p><strong>Site Content: </strong>Language and content tone significantly influence users’ interaction with a website. In this section, we will emphasize the necessity for the language used on e-commerce sites to be culturally sensitive. Additionally, we will discuss intercultural content strategies and user language expectations.</p><p><strong>Site Interaction: </strong>User experience is determined by site interaction. In this section, we will focus on how cultural factors affect the interaction of users with e-commerce sites. For example, by addressing the responses and expectations of users from different cultures to interactive elements, we will examine the interaction strategies of e-commerce sites.</p><p>With this article and the subsequent series, I aim to provide a resource for e-commerce companies to understand the relationships between these fundamental design elements and cultural diversity, enabling them to create more effective and user-friendly designs in intercultural markets.</p><h3>References</h3><p>[1] <a href="https://datareportal.com/global-digital-overview">https://datareportal.com/global-digital-overview</a></p><p>[2] <a href="https://www.shu.ac.uk/about-us/academic-departments/sheffield-business-school/alumni/articles/everyone-speaks-english-dont-they">https://www.shu.ac.uk/about-us/academic-departments/sheffield-business-school/alumni/articles/everyone-speaks-english-dont-they</a></p><p>[3]<a href="https://researchportal.murdoch.edu.au/esploro/outputs/doctoral/Usability-themes-in-high-and-low/991005543416607891">https://researchportal.murdoch.edu.au/esploro/outputs/doctoral/Usability-themes-in-high-and-low/991005543416607891</a></p><p>[4] <a href="https://www.researchgate.net/publication/278034641_Cross-Cultural_User_Experience_Design_Helping_Product_Designers_to_Consider_Cultural_Differences">https://www.researchgate.net/publication/278034641_Cross-Cultural_User_Experience_Design_Helping_Product_Designers_to_Consider_Cultural_Differences</a></p><p>[5] <a href="https://www.statista.com/statistics/262946/most-common-languages-on-the-internet/">https://www.statista.com/statistics/262946/most-common-languages-on-the-internet/</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=3397592b208f" width="1" height="1" alt=""><hr><p><a href="https://medium.com/cstech/the-impact-of-cultural-diversity-on-e-commerce-designs-part-1-3397592b208f">The Impact of Cultural Diversity on E-commerce Designs — Part 1</a> was originally published in <a href="https://medium.com/cstech">ÇSTech</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Accessibility Principles for Designers]]></title>
            <link>https://medium.com/cstech/tasar%C4%B1mc%C4%B1lar-i%C3%A7in-eri%C5%9Filebilirlik-i%CC%87lkeleri-df86e0603462?source=rss----a708e03ddc8a---4</link>
            <guid isPermaLink="false">https://medium.com/p/df86e0603462</guid>
            <category><![CDATA[accessibility]]></category>
            <category><![CDATA[product-design]]></category>
            <category><![CDATA[ui]]></category>
            <category><![CDATA[wcag]]></category>
            <category><![CDATA[ux]]></category>
            <dc:creator><![CDATA[Buğrahan Sezgin]]></dc:creator>
            <pubDate>Fri, 29 Dec 2023 09:03:36 GMT</pubDate>
            <atom:updated>2023-12-29T11:31:25.331Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*VgWQ0tLbOsm8BL019n2KdQ.jpeg" /><figcaption>Photo by <a href="https://unsplash.com/@sigmund?utm_content=creditCopyText&amp;utm_medium=referral&amp;utm_source=unsplash">Sigmund</a> on <a href="https://unsplash.com/photos/person-using-braille-writer-4MoIpDcSlr4?utm_content=creditCopyText&amp;utm_medium=referral&amp;utm_source=unsplash">Unsplash</a></figcaption></figure><p>The Web Content Accessibility Guidelines (<a href="https://www.w3.org/TR/WCAG21/">WCAG</a>), briefly, are a set of principles that must be adhered to for greater accessibility of all content on the web. Accessibility encompasses a variety of barriers, including visual, auditory, physical, speech, cognitive, language, learning, and neurological impairments.</p><p>According to the World Health Organization (WHO), <strong>16%</strong> of the world’s population experiences disability. Unfortunately, much of the content on the web is not adapted to this class. Therefore, with a decision by the European Union, by <strong>June 28, 2025</strong>, companies in all EU member countries must adapt their products/services to these accessibility standards.</p><p>As designers, there are some principles within the scope of accessibility standards that we need to follow. Let’s briefly examine these principles without going into too much detail and provide some guidance. (<em>I’m leaving the links to the relevant sources at the bottom.</em>)</p><h3>Pay attention to the contrast values of colors</h3><p>Ensure that the contrast between colors is measured to ensure the readability of content and text. You can use “contrast checker” plugins in Figma or perform the necessary measurements on WebAIM. The basic limits are:</p><ul><li>Must provide a minimum validity ratio of 4.5:1.</li><li>For large or bold fonts, a validity ratio of 3:1 is required.</li><li>Logos and graphic elements are not subject to these rules.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*IM9eSVQwdiQFz1NQt5CyOA.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/659/1*M2ePp4sPPeP247CNzLZUBA.png" /><figcaption>On the left: Contrast Checker for Figma. On the right: WebAIM Contrast Checker.</figcaption></figure><h3>Don’t rely solely on colors</h3><p>Using color alone to convey information can make your website’s content inaccessible to many people.</p><ul><li>Ensure that links are not changed only in color; underline them to indicate to the user that they are clickable.</li><li>In a scenario where an input field in a form is erroneous, don’t just turn the input’s border red; instead, make a structural change by thickening the border and support it with a subtext that specifies the cause of the error and how to resolve it, accompanied by an icon.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*z-zJwmgAe-J6b_mXEqVmNw.png" /><figcaption>Correct Usage of Error and Non-error States in Inputs</figcaption></figure><ul><li>Do not indicate a selected element solely through color; structural changes beyond color are also necessary for the appearance of the selected area. For example, you can add an underline beneath a navigation element to signify its selection.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*FRKT_7IhhCmNLuBZEZoYuw.png" /><figcaption>Representation of Menu Element in Navigation Independent of Color</figcaption></figure><blockquote>Note: After designing, it is generally advisable to review your design in black and white mode or share it with others in your vicinity. This way, you can identify any errors that may exist.</blockquote><h3>Ensure that interface elements are clear and distinct</h3><p>Users understand that interactive elements within the site contain interactions through their structure and the text they include. Therefore, ensure that interactive content elements are presented to the user in a clear and distinct manner.</p><ul><li>What makes a button a button is its form. Define a shape and create variations that will be consistent in structure. (If one button has a rounded border radius, the other should not have sharp corners.)</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ufLODaI_BEIQmtcdINF_7w.png" /><figcaption>Correct Usage of a Button</figcaption></figure><ul><li>Color the button and distinguish it from other elements. (Some button types like [ghost, outline, etc.] may resemble input types; separate them.)</li><li>The text of buttons/links should be specific rather than generic. For example, on an e-commerce website’s “My Orders” screen, use text like “Cancel My Order” instead of just “Cancel.”</li><li>Your form elements (inputs) should always have a title; do not rely solely on placeholder text (text inside an input when it’s empty).</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*8C0Nfo2cMBIQveh7e8bdEw.png" /><figcaption>Example of an Input Field with/without a Title</figcaption></figure><h3>Use alternative text for all non-text content</h3><p>Add clear and concise alternative text for all content that does not contain text, whether it’s visual, graphical, or lacks textual information. This will enable programs like screen readers to read this type of content to the user.</p><ul><li>Add alternative text for all non-text content, such as visuals, videos, and audio, to ensure accessibility for users who rely on alternative means to consume content, like screen readers.</li><li>There is no need for alternative text for elements that are purely decorative, such as separators or background decorations.</li></ul><h3>Ensure correct focus transitions using the “Tab” key on the keyboard</h3><p>Some users with motor skill disabilities may struggle to use a mouse, so they navigate websites using a keyboard.</p><ul><li>Clearly indicate focus states during navigation done with the “Tab” key.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/621/1*vIhVJWOvaSnlbubOr0taXA.png" /><figcaption>The button on the right represents the focused state when activated using the “Tab” key.</figcaption></figure><ul><li>Ensure that focus states logically progress according to the site hierarchy. For example, if the first element in the header at the top of the site is selected, pressing the “Tab” key on the keyboard should not jump directly to the “About Us” page in the footer; it should follow a logical sequence.</li></ul><h4>Useful Resources:</h4><p>WCAG EU Decision <a href="https://digital-strategy.ec.europa.eu/en/policies/web-accessibility-directive-standards-and-harmonisation">https://digital-strategy.ec.europa.eu/en/policies/web-accessibility-directive-standards-and-harmonisation</a><br>WCAG Principles <a href="https://www.w3.org/TR/WCAG21/">https://www.w3.org/TR/WCAG21/</a><br>WebAIM Contrast Checker <a href="https://webaim.org/resources/contrastchecker/">https://webaim.org/resources/contrastchecker/</a><br>Accessible Color Palette Generator: <a href="https://toolness.github.io/accessible-color-matrix/">https://toolness.github.io/accessible-color-matrix/</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=df86e0603462" width="1" height="1" alt=""><hr><p><a href="https://medium.com/cstech/tasar%C4%B1mc%C4%B1lar-i%C3%A7in-eri%C5%9Filebilirlik-i%CC%87lkeleri-df86e0603462">Accessibility Principles for Designers</a> was originally published in <a href="https://medium.com/cstech">ÇSTech</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Demystifying Kubernetes’ Vertical Pod Autoscaler (VPA): Optimizing Resource Management]]></title>
            <link>https://medium.com/cstech/demystifying-kubernetes-vertical-pod-autoscaler-vpa-optimizing-resource-management-afb32c09415b?source=rss----a708e03ddc8a---4</link>
            <guid isPermaLink="false">https://medium.com/p/afb32c09415b</guid>
            <category><![CDATA[vertical-pod-autoscaler]]></category>
            <category><![CDATA[vpa]]></category>
            <category><![CDATA[kubernetes]]></category>
            <category><![CDATA[autoscaling]]></category>
            <dc:creator><![CDATA[Ali Altoğ]]></dc:creator>
            <pubDate>Fri, 29 Dec 2023 09:00:38 GMT</pubDate>
            <atom:updated>2023-12-29T09:00:38.199Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/343/1*YWsRPD_DzUdKr2sOilPk-g.png" /></figure><h3>Introduction</h3><p>In the dynamic world of Kubernetes, efficiently managing resources is a challenge many DevOps engineers face. Enter the Vertical Pod Autoscaler (VPA), a powerful tool that dynamically adjusts resource requests for pods. In this article, we’ll delve into what VPA is, how it works, and why it’s a game-changer in optimizing resource management within Kubernetes clusters.</p><h3>What is VPA?</h3><p><strong>Vertical Pod Autoscaler (VPA)</strong> is a Kubernetes component designed to tackle the challenge of adjusting resource requests for running pods. Unlike the Horizontal Pod Autoscaler (HPA), which scales the number of pod replicas based on observed metrics, VPA focuses on modifying the resource allocations of individual pods.</p><p>VPA continuously monitors metrics like CPU and memory utilization, and based on this data, it automatically adjusts the resource requests for pods. This dynamic adaptation ensures that pods receive the right amount of resources to operate optimally, preventing both resource starvation and wastage.</p><h3>VPA Modes</h3><p>VPA operates in three distinct modes: <strong>Auto</strong>, <strong>Initial</strong>, and <strong>Recreate</strong>.</p><ul><li><strong>Auto Mode:</strong> In this mode, VPA dynamically adjusts resource requests for running pods. When it detects a need for changes, it gracefully evicts the pod, allowing Kubernetes to recreate it with updated resource requests.</li><li><strong>Initial Mode:</strong> Useful for setting initial resource requests when a pod is first created. VPA ensures that the pod starts with the appropriate resource allocations based on observed metrics.</li><li><strong>Recreate Mode:</strong> This mode is similar to Auto but more aggressive. It directly recreates pods without gradual adjustments, making it suitable for scenarios where immediate resource changes are critical.</li></ul><h3>Implementation</h3><p>Setting up VPA in your Kubernetes cluster involves a few key steps. Firstly, deploy the VPA components, including the <strong>admission controller</strong> and the <strong>VPA custom resource definition</strong>. Configure the VPA settings, specifying which pods to target and the metrics to consider for adjustments.</p><pre>git clone https://github.com/kubernetes/autoscaler.git<br>cd autoscaler/vertical-pod-autoscaler<br>./hack/vpa-process-yamls.sh print<br>./hack/vpa-up.sh<br>kubectl get pods -n kube-system | grep vpa</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/893/1*AmFcR8OcS2YCcr2gdmhzLg.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/574/1*o50hnUyMvfSDfsmYYbCOkw.png" /></figure><h3>Use Cases</h3><p>VPA shines in various scenarios, from optimizing resource usage in steady-state applications to handling sudden spikes in demand. Consider a scenario where a service experiences a sudden increase in traffic. VPA can dynamically adjust resource allocations to meet the demand, preventing performance degradation.</p><p>Let’s show it with an example:</p><pre>apiVersion: apps/v1<br>kind: Deployment<br>metadata:<br>  name: ubuntu-deployment<br>  namespace: test<br>spec:<br>  replicas: 1<br>  template:<br>    spec:<br>      containers:<br>        - name: ubuntu-container<br>          image: ubuntu:latest<br>          command:<br>            - sleep<br>            - &#39;604800&#39;<br>          resources:<br>            limits:<br>              cpu: 200m<br>              memory: 300Mi<br>            requests:<br>              cpu: 10m<br>              memory: 100Mi</pre><pre>apiVersion: autoscaling.k8s.io/v1<br>kind: VerticalPodAutoscaler<br>metadata:<br>  name: example-vpa-3<br>  namespace: test<br>spec:<br>  resourcePolicy:<br>    containerPolicies:<br>      - containerName: ubuntu-deployment<br>        controlledResources:<br>          - cpu<br>          - memory<br>        maxAllowed:<br>          cpu: 700m<br>          memory: 700Mi<br>        minAllowed:<br>          cpu: 5m<br>          memory: 50Mi<br>  targetRef:<br>    apiVersion: apps/v1<br>    kind: Deployment<br>    name: ubuntu-deployment<br>  updatePolicy:<br>    updateMode: Auto</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/710/1*vvu6OW4jZUJzfAAFMmBNMw.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/337/1*i0j5sEKxv4t69MXwFZhIVw.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*RAI2sGHukh_ab26cNBaTXw.png" /></figure><p>The VPA-Updater acts like a vigilant watcher for your app’s needs within Kubernetes. It keeps an eye on how your apps are doing, like checking a car’s performance during a race.</p><p>It looks at metrics, kind of like how we might check the speed and fuel usage in a race car. When it sees that your apps need more “juice” to run better, it helps increase their “fuel” (CPU and memory). And if it notices they’re using way too much “fuel” unnecessarily, it steps in to help cut back, making sure your system doesn’t waste resources.</p><p>In simple terms, this helper makes sure your apps have the right resources they need to perform at their best, just like a pit crew making quick adjustments to a racing car to keep it running smoothly on the track.</p><h3>Best Practices</h3><p>To make the most of VPA, consider these best practices:</p><ul><li>Regularly monitor VPA logs and metrics to ensure it’s effectively adjusting resources.</li><li>Fine-tune VPA parameters based on your application’s characteristics and usage patterns.</li><li>Test VPA in a staging environment before deploying it in production to understand its impact on your specific workloads.</li></ul><h3>Conclusion</h3><p>In the ever-evolving landscape of container orchestration, tools like VPA play a crucial role in ensuring optimal resource utilization. By dynamically adjusting pod resource requests, VPA contributes to improved application performance, efficient resource usage, and ultimately, a smoother Kubernetes experience. Incorporate VPA into your toolkit, and witness the difference it can make in the world of DevOps.</p><p><strong>Sources:</strong></p><p><a href="https://isitobservable.io/observability/kubernetes/how-to-autoscale-in-kubernetes-and-how-to-observe-scaling-decisions">https://isitobservable.io/observability/kubernetes/how-to-autoscale-in-kubernetes-and-how-to-observe-scaling-decisions</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=afb32c09415b" width="1" height="1" alt=""><hr><p><a href="https://medium.com/cstech/demystifying-kubernetes-vertical-pod-autoscaler-vpa-optimizing-resource-management-afb32c09415b">Demystifying Kubernetes’ Vertical Pod Autoscaler (VPA): Optimizing Resource Management</a> was originally published in <a href="https://medium.com/cstech">ÇSTech</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[PowerShell Komut Dosyalarını Görev Zamanlayıcıyla Otomatikleştirme]]></title>
            <link>https://medium.com/cstech/powershell-komut-dosyalar%C4%B1n%C4%B1-g%C3%B6rev-zamanlay%C4%B1c%C4%B1yla-otomatikle%C5%9Ftirme-0230d2dbae7b?source=rss----a708e03ddc8a---4</link>
            <guid isPermaLink="false">https://medium.com/p/0230d2dbae7b</guid>
            <category><![CDATA[autostart]]></category>
            <category><![CDATA[windows]]></category>
            <category><![CDATA[powershell]]></category>
            <category><![CDATA[task-management]]></category>
            <category><![CDATA[script]]></category>
            <dc:creator><![CDATA[Ozan Dilek]]></dc:creator>
            <pubDate>Wed, 29 Nov 2023 13:43:40 GMT</pubDate>
            <atom:updated>2023-11-29T13:43:40.783Z</atom:updated>
            <content:encoded><![CDATA[<h3>PowerShell Komutunu Görev Zamanlayıcı ile Otomatikleştirme</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*IyJl-XhHMGGROWi4nxyfHQ.png" /></figure><blockquote><strong>Ne İşe Yarar ?</strong></blockquote><p>Windows cihazlarda görev zamanlayıcısı ile bir programı veya PowerShell komutlarını belirli bir zamanda veya belirli koşullar karşılandığında otomatik olarak başlatmanıza yardımcı olacaktır.</p><blockquote><strong>Nasıl Çalışır ?</strong></blockquote><p><strong>“Windows + R”</strong> tuşlarına basıp açılan pencereye <strong>“taskschd.msc”</strong> yazarak Task Scheduler konsolunu açıyoruz.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*HpcfsSTbH_HU9ZqzEkpGRA.png" /></figure><p><strong>“Create Task”</strong> seçeneğine tıkladığınızda, yeni bir görev için ad ve açıklama girmeniz gerekecek. Programı yönetici ayrıcalıklarıyla çalıştırmak için <strong>“Run whether user is logged on or not”</strong> kutusunu işaretlemeniz gerekiyor. Örneğimizde, görevi bir hizmet hesabına atayarak, kullanıcının oturum açmış olup olmamasına bakılmaksızın görevi başlatmayı planlıyoruz.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*PupgUouZg4z7e9nsKkWJ-w.png" /></figure><p>Ardından <strong>“Triggers”</strong> sekmesine geçip <strong>“New”</strong> butonuna tıklıyoruz.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/590/1*rUOsF6qXGu895MntuVy6tA.png" /></figure><p><strong>“Schedule”</strong> seçeneğini seçtikten sonra sol taraftan <strong>“Daily”</strong> seçeneğini belirleyerek, görevin çalışmasını istediğimiz saati girmeli ve oluşturacağımız Trigger’ın <strong>“Enable”</strong> seçeneğini aktif hale getirmeliyiz.</p><p><strong>“Action”</strong> sekmesine gelerek, <strong>“New”</strong> butonuna tıklıyoruz.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/452/1*YIL4CBbQN4LJNHrREJMI3A.png" /></figure><p>Açılan pencerede <strong>“Action”</strong> sekmesini <strong>“Start a program”</strong> olarak belirliyoruz. Program/Script kısmına <strong>“powershell”</strong> yazıyor. <strong>Add Argument</strong> kısmına hazırlamış olduğumuz shell dosyasının yolunu belirtiyoruz. <br>Örn: [-File C:\script\pwshll.ps1]” <strong>“OK”</strong> Diyoruz.</p><p><strong>“Condition”</strong> sekmesine geçiyoruz.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/630/1*yKj7ZZwHR_CHyYU-okP2cA.png" /></figure><p>Power kısmında bulunan başlıklar seçili ise bunları kaldırmamız gerekmektedir.</p><p><strong>“Settings”</strong> sekmesininde bulunan ayarları değiştirmeden bırakıyoruz.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/608/1*u3sXlFnrh5nIUdZOBG0wEA.png" /></figure><p>Ayarlamaları bu şekilde tamamladığımız zaman <strong>“OK”</strong> diyerek çıkabiliriz. Karşımıza kullanıcı adı ve şifrenin sorulduğu ekran gelecektir. Bilgisayar üzerinde oturum açılmasa bile görevin çalışabilmesi için kullanıcı adı ve parola girerek <strong>“OK”</strong> diyoruz.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/506/1*XLNahnmYlqYf44MmZkY3sA.png" /></figure><p><strong>ÖNEMLİ: </strong>Bu komutun çalışabilmesi için <strong>“Hizmetler”</strong> kısmında bulunan servisin başlangıç türünün <strong>“Otomatik”</strong> olarak ayarlanmış olması gerekmektedir.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/518/1*RBUAcGM7tdxGDGTV3jYekQ.png" /></figure><p>Belirtilen aşamaları tamamladıktan sonra sorunsuz bir şekilde powershell komutlarınızı görev zamanlayıcısı ile otomatikleştirmiş olacaksınız.</p><p><strong><em>Bir sonraki içerikte görüşmek üzere.</em></strong></p><p><strong><em>Ozan Dilek</em></strong></p><p><a href="https://www.linkedin.com/in/ozan-dilek-7592b890/"><strong><em>Linkedin</em></strong></a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=0230d2dbae7b" width="1" height="1" alt=""><hr><p><a href="https://medium.com/cstech/powershell-komut-dosyalar%C4%B1n%C4%B1-g%C3%B6rev-zamanlay%C4%B1c%C4%B1yla-otomatikle%C5%9Ftirme-0230d2dbae7b">PowerShell Komut Dosyalarını Görev Zamanlayıcıyla Otomatikleştirme</a> was originally published in <a href="https://medium.com/cstech">ÇSTech</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Design Patterns Widely Used by JavaScript & React Developers]]></title>
            <link>https://medium.com/cstech/design-patterns-widely-used-by-javascript-react-developers-17969795fa73?source=rss----a708e03ddc8a---4</link>
            <guid isPermaLink="false">https://medium.com/p/17969795fa73</guid>
            <category><![CDATA[design-patterns]]></category>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[web-development]]></category>
            <category><![CDATA[react]]></category>
            <dc:creator><![CDATA[Oguzhan Yuksel]]></dc:creator>
            <pubDate>Wed, 08 Nov 2023 08:21:28 GMT</pubDate>
            <atom:updated>2023-11-08T08:21:28.492Z</atom:updated>
            <content:encoded><![CDATA[<p>Design patterns are crucial for software developers and architects, offering proven solutions to common development challenges. They provide reusable blueprints, promoting best practices and code organization, akin to tried-and-true recipes.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*nm9Cy0soXlwIxsid" /><figcaption>Photo by <a href="https://unsplash.com/@adrienolichon?utm_source=medium&amp;utm_medium=referral">Adrien Olichon</a> on <a href="https://unsplash.com/?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><p>In this article, we’ll explore design patterns in JavaScript and React, offering explanations and practical examples. Whether you’re new to design patterns or looking to enhance your skills, this guide will help you apply these invaluable concepts to your projects and improve your software development endeavors.</p><h4>Singleton Pattern:</h4><p>The Singleton pattern ensures that a class has only one instance and provides a global point of access to it. This is useful for scenarios where you want to maintain a single point of control, such as a configuration manager or a shared resource.</p><pre>class Singleton {<br>  constructor() {<br>    if (Singleton.instance) {<br>      return Singleton.instance;<br>    }<br>    Singleton.instance = this;<br>  }<br><br>  someMethod() {<br>    // Your code here<br>  }<br>}<br><br>const instance1 = new Singleton();<br>const instance2 = new Singleton();<br><br>console.log(instance1 === instance2); // true</pre><p>Singleton can only have one instance, and any subsequent attempts to create new instances will return the original instance.</p><h4>Proxy Pattern:</h4><p>The Proxy pattern provides a surrogate or placeholder for another object to control access to it. It can be used for various purposes, such as lazy loading of resources or access control.</p><pre>class RealImage {<br>  display() {<br>    console.log(&quot;Displaying the real image.&quot;);<br>  }<br>}<br><br>class ProxyImage {<br>  constructor() {<br>    this.realImage = new RealImage();<br>  }<br><br>  display() {<br>    console.log(&quot;Loading the image...&quot;);<br>    this.realImage.display();<br>  }<br>}<br><br>const image = new ProxyImage();<br>image.display();</pre><p>ProxyImage serves as a proxy for the RealImage. It controls access to the RealImage and can perform additional tasks, such as loading the image before displaying it.</p><h4>Factory Pattern:</h4><p>The Factory pattern is a creational pattern that abstracts the process of object creation, allowing the client code to be decoupled from the specific classes being instantiated.</p><pre>class Car {<br>  constructor(make, model) {<br>    this.make = make;<br>    this.model = model;<br>  }<br>}<br><br>class Bicycle {<br>  constructor(type) {<br>    this.type = type;<br>  }<br>}<br><br>class VehicleFactory {<br>  createVehicle(type, ...args) {<br>    if (type === &#39;car&#39;) {<br>      return new Car(...args);<br>    } else if (type === &#39;bicycle&#39;) {<br>      return new Bicycle(...args);<br>    } else {<br>      throw new Error(&quot;Unsupported vehicle type&quot;);<br>    }<br>  }<br>}<br><br>const factory = new VehicleFactory();<br>const car1 = factory.createVehicle(&#39;car&#39;, &#39;Toyota&#39;, &#39;Camry&#39;);<br>const bicycle1 = factory.createVehicle(&#39;bicycle&#39;, &#39;Mountain&#39;);<br><br>console.log(car1); // Car { make: &#39;Toyota&#39;, model: &#39;Camry&#39; }<br>console.log(bicycle1); // Bicycle { type: &#39;Mountain&#39; }</pre><p>The VehicleFactory abstracts the creation of Car or Bicycleobjects. This separation allows you to create different types of vehicles or change the creation logic without modifying the client code.</p><p>This class-based Factory Pattern still provides the abstraction for creating objects and allows you to maintain a consistent interface for object creation while using modern ES6 class syntax.</p><h4>Observer Pattern:</h4><p>The Observer pattern defines a one-to-many relationship between objects, so when one object changes state, all its dependents are notified and updated automatically.</p><pre>class Subject {<br>  constructor() {<br>    this.observers = [];<br>  }<br><br>  addObserver(observer) {<br>    this.observers.push(observer);<br>  }<br><br>  notify(message) {<br>    this.observers.forEach(observer =&gt; observer.update(message));<br>  }<br>}<br><br>class Observer {<br>  update(message) {<br>    console.log(`Received message: ${message}`);<br>  }<br>}<br><br>const subject = new Subject();<br>const observer1 = new Observer();<br>const observer2 = new Observer();<br><br>subject.addObserver(observer1);<br>subject.addObserver(observer2);<br><br>subject.notify(&quot;Hello, observers!&quot;);</pre><p>The Subject maintains a list of observers, and when it changes state (in this case, sends a message), all registered observers are notified.</p><p>This is the end of the topics about Javascript Design Patterns. Now let’s move on to the React Design Patterns which are more widely used nowadays.</p><h3>React Design Patterns</h3><h4>Container / Presentational Pattern</h4><p>The Container/Presentational pattern separates the logic (Container components) from the rendering (Presentational components). Container components handle data and state management, while Presentational components focus on rendering.</p><pre>// Container Arrow Function Component<br>import React, { useState } from &#39;react&#39;;<br>import Presentation from &#39;./Presentation&#39;;<br><br>const Container = () =&gt; {<br>  const [data, setData] = useState([]);<br><br>  // Logic and state management<br><br>  return &lt;Presentation data={data} /&gt;;<br>};<br><br>export default Container; // Export the Container component<br><br>// Presentational Component<br>const Presentation = ({ data }) =&gt; {<br>  // Rendering logic using data<br>};<br><br>export default Presentation; // Export the Presentation component</pre><p>Container components like Container handle data fetching and state management, while Presentational components like Presentation focus solely on rendering.</p><h4>Higher-Order Component (HOC) Pattern:</h4><p>A Higher-Order Component (HOC) is a function that takes a component and returns a new component with added behavior or props.</p><pre>import React from &#39;react&#39;;<br><br>const withLogger = WrappedComponent =&gt; {<br>  return class ComponentWithLogger extends React.Component {<br>    componentDidMount() {<br>      console.log(`Component ${WrappedComponent.name} has mounted.`);<br>    }<br><br>    render() {<br>      return &lt;WrappedComponent {...this.props} /&gt;;<br>    }<br>  };<br>};<br><br>const MyComponent = () =&gt; &lt;div&gt;My Component&lt;/div&gt;;<br>const MyComponentWithLogger = withLogger(MyComponent);</pre><p>Here, withLogger is a HOC that logs when a component is mounted. It enhances the MyComponent with additional behavior.</p><p>While HOCs were initially associated with class components, you can create and use HOCs with functional components using React hooks. In order not to make it too long, I will not give an example of functional component usage separately.</p><h4>Provider &amp; Compound Pattern:</h4><p>The Provider pattern, frequently utilized in conjunction with the Context API, is a powerful tool for managing shared data in React. It allows you to pass data or functionality down the component tree without the need for explicit prop drilling.</p><pre>import React, { createContext, useContext } from &#39;react&#39;;<br><br>const MyContext = createContext();<br><br>function MyProvider({ children }) {<br>  const value = { data: &#39;Some context data&#39; };<br>  return &lt;MyContext.Provider value={value}&gt;{children}&lt;/MyContext.Provider&gt;;<br>}<br><br>function ConsumerComponent() {<br>  const value = useContext(MyContext);<br>  return &lt;div&gt;{value.data}&lt;/div&gt;;<br>}</pre><p>The MyProvider component wraps its children with a context that provides shared data. Nested components like ConsumerComponent can easily access this data without the need for passing it explicitly through props. The Provider pattern simplifies data management and reduces the complexity of component communication.</p><p>There are many more design patterns available. You can use these examples as a starting point to discuss each design pattern’s purpose, benefits, and how they can be applied in JavaScript and React applications.</p><p><strong>PS: </strong>In the React world, Functional components have become increasingly popular, and they offer a clean and concise way to implement these patterns in modern React applications. Being eye familiar with those would help to understand and write better code.</p><p>Until next time, take care! 👋</p><h3>Additional Part</h3><p>You can reach me through the channels below,</p><p><strong>LinkedIn</strong>: <a href="https://www.linkedin.com/in/developeroguzyuksel/">https://www.linkedin.com/in/developeroguzyuksel/</a></p><p><strong>GitHub</strong>: <a href="https://github.com/ooguzyuksel">https://github.com/ooguzyuksel</a></p><p>Oğuzhan YÜKSEL</p><p>Frontend Developer <a href="https://medium.com/u/ef0a84cf7f9d">ÇSTech</a></p><h3>📖 References and Sources:</h3><ul><li><a href="https://javascriptpatterns.vercel.app/patterns">JavaScript Patterns Workshop | JavaScript Patterns</a></li><li><a href="https://addyosmani.com/learning-jsdp/">Learning JavaScript Design Patterns - The Examples</a></li><li><a href="https://www.patterns.dev/">Patterns.dev</a></li><li><a href="https://reactpatterns.com/">React Patterns</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=17969795fa73" width="1" height="1" alt=""><hr><p><a href="https://medium.com/cstech/design-patterns-widely-used-by-javascript-react-developers-17969795fa73">Design Patterns Widely Used by JavaScript &amp; React Developers</a> was originally published in <a href="https://medium.com/cstech">ÇSTech</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[JavaScript Modules: Strategies to Improve Code Quality and Efficiency]]></title>
            <link>https://medium.com/cstech/javascript-modules-e3ef549a9e33?source=rss----a708e03ddc8a---4</link>
            <guid isPermaLink="false">https://medium.com/p/e3ef549a9e33</guid>
            <category><![CDATA[commonjs]]></category>
            <category><![CDATA[modules]]></category>
            <category><![CDATA[es6]]></category>
            <category><![CDATA[javascript-modules]]></category>
            <category><![CDATA[javascript]]></category>
            <dc:creator><![CDATA[Büşra Özmen ]]></dc:creator>
            <pubDate>Wed, 08 Nov 2023 08:21:02 GMT</pubDate>
            <atom:updated>2023-11-08T08:21:02.818Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*fEpkqmC1-DvAD6w3SH7jxg.png" /><figcaption>designed by <a href="https://elifyardimci.medium.com/">Elif Yardımcı</a></figcaption></figure><p>JavaScript is one of the milestones of web development. It is used to increase interaction on websites and add dynamism to the websites. The size of JavaScript varies depending on the size of websites. Since the JavaScript used in large projects will be large, the code must be clean, readable, and reusable. JavaScript Modules are used for this. In this article, I will explain what the JavaScript Module concept is, why it is needed, what solutions have been developed, how it is used, and what advantages it offers.</p><h3>What is the concept of JavaScript Modules?</h3><p>JavaScript modules are used to split your code into smaller, more manageable pieces rather than keeping it in a single file and moving those pieces to other files or projects. Modules can contain functions, variables, and objects that perform specific functions. With modules, code complexity decreases, code readability and reusability increase significantly and repetition is minimized.</p><h3>Why are JavaScript Modules needed?</h3><p>When JavaScript first came out, people’s interaction scenarios on websites were limited. For this reason, JavaScript files were small and consisted of code fragments. But over time, websites grew and many more scenarios emerged. With these developments, JavaScript codes have also grown and become more complex. As the codes grew larger, it became harder for developers to keep track. This is where JavaScript modules came into play. Instead of writing all the codes in a single file, the codes began to be written in modules.</p><h3>Module Solutions</h3><p>When JavaScript modules first came into use, there was no official standard or structure. That’s why different developers created their own solutions. CommonJS, AMD(Asynchronous Module Definition), UMD(Universal Module Definition), and ES Modules are widely used JavaScript module systems. Now let’s examine these module systems.</p><h4>CommonJS</h4><p>CommonJS aims to provide a standard way of writing JavaScript, especially for server-side applications. It has been used especially in Node.js projects. It was developed in 2009 by Kevin Dangoor, who worked as a software engineer at Mozilla Corporation. The module.exports object is used to export the codes in a module. We can use the require method to import these codes in another file. These operations ensure the synchronous loading of modules. Now, let’s take a look at its usage.</p><pre>//user.js<br>function User(fullName, phone) {<br>  var returnObj = {<br>    fullName : fullName,<br>    phone : phone,<br>    contactInfo: &#39;Contact Info: &#39; + fullName + &#39; &#39; + phone<br>  }<br>  return returnObj<br>}<br><br>module.exports = User;</pre><pre>//main.js<br>const User = require(&#39;./user.js&#39;);<br>const person = User(&#39;James Bond&#39;, &#39;5555555555&#39;);<br><br>console.log(person.contactInfo) -&gt; Contact Info: James Bond 5555555555</pre><h4>AMD (Asynchronous Module Definition)</h4><p>AMD is a module system designed specifically for client-side applications. It was developed by James Burke, who worked at Mozilla Corporation, in 2011 (<a href="https://github.com/amdjs/amdjs-api">https://github.com/amdjs/amdjs-api</a>). Unlike CommonJS, modules are loaded asynchronously in AMD. It is a system adopted by the RequireJs library and is better in terms of performance and usability because it is loaded asynchronously. The define method is used to define modules. Let’s take a look at AMD’s usage.</p><pre>//user.js<br>define([], function() {<br><br>  return {<br>    fullName: function() {<br>      console.log(&#39;James Bond&#39;);<br>    },<br>    phone: function() {<br>      console.log(&#39;5555555555&#39;);<br>    }<br>  };<br>});</pre><pre>//main.js<br>define([&#39;user&#39;, &#39;otherUser&#39;], function(user, otherUser) {<br>  console.log(user.fullName()); -&gt; James Bond<br>});</pre><h4>UMD (Universal Module Definition)</h4><p>UMD is a universal module system that supports features from AMD and CommonJs, which can be used in both client-side and server-side applications. UMD controls the environment in which the module is run. It provides the flexibility to use it on both the client and server side. You can review this module system, developed in 2015, from Addy Osmani’s repository: <a href="https://github.com/umdjs/umd">https://github.com/umdjs/umd</a><br>Due to its syntax structure, I think it may cause complexity in projects.</p><pre>//user.js<br>(function (root, factory) {<br>  if (typeof define === &#39;function&#39; &amp;&amp; define.amd) {<br>      //for AMD<br>    define([], factory);<br>  } else if (typeof exports === &#39;object&#39;) {<br>      //for CommonJS<br>    module.exports = factory();<br>  } else {<br>    //for Browser<br>    root.User = factory();<br>  }<br>}(typeof self !== &#39;undefined&#39; ? self : this, function () {<br>  //Methods<br>  function contactInfo(fullName, phone){<br>    return &#39;Contact Info: &#39; + fullName + &#39; &#39; + phone;<br>  };<br>  //The part of the module to be exported<br>  return {<br>      contactInfo: contactInfo<br>  }<br>}));</pre><pre>//main.js<br>var User = require(&#39;./user&#39;);<br>var result = User.contactInfo(&#39;James Bond&#39;, &#39;5555555555&#39;);<br>console.log(result); -&gt; Contact Info: James Bond 5555555555</pre><h4>ES Modules</h4><p>ECMAScript (ES) Modules represent the entry of the JavaScript world into a more modern era. Module support was added to JavaScript with ECMAScript 6 (ES6) in 2015. It can be used in client-side and server-side applications and provides support for asynchronous module loading. Syntax of the ES Module is also much simpler than other module solutions. It manages the data flow between modules using the import and export keywords.</p><p>Among the solutions offered for modules, the current solution is ES Modules. However, it took quite a long time to reach this official solution. The different module systems created in this process have led to incompatibility and complexity in the JavaScript ecosystem.</p><p>Now, let’s take a look at the use of ES Modules.</p><pre>//user.js<br>export const user = (fullName, phone) =&gt; {<br>  var returnObj = {<br>    fullName : fullName,<br>    phone : phone,<br>    contactInfo: &#39;Contact Info: &#39; + fullName + &#39; &#39; + phone<br>  }<br>  return returnObj<br>}</pre><pre>//main.js<br>import { user } from &#39;./user.js&#39;<br>const person = user(&#39;James Bond&#39;, &#39;5555555555&#39;);<br><br>console.log(person.contactInfo) -&gt; Contact Info: James Bond 5555555555</pre><p>Since ES Modules are the current method used at the moment, I would like to discuss some terms and usage patterns related to import and export in subheadings.</p><p><strong>export default: </strong>We can export multiple functions, variables, or objects to a different file by using the ‘export’ keyword. In the example above, if there was an age calculation function in addition to the ‘user’ function, we could export it by adding the ‘export’ keyword to the beginning of this function in the same way. Additionally, we could export the two functions without using the ‘export’ keyword as follows: export {user, ageCalculate}While importing, we could also import two functions using the ‘import’ keyword: import {user, ageCalculate} from ‘./user.js’This usage method is very useful in cases where we want to transfer more than one function, variable or object. However, if we only want to export a single function in a file, the ‘export default’ keyword may be more useful. We can import the function we exported with ‘export default’ with a different name. In the example below, the results for ‘User’ and ‘Profile’ will be the same.</p><pre>//user.js<br>export default User = (fullName, phone) =&gt; {<br>  ......<br>}</pre><pre>//main.js<br>import User from &#39;./user.js&#39; <br>//or <br>import Profile from &#39;./user.js&#39;</pre><ul><li><strong>alias: </strong>When we want to change the name of a function while importing it, we can use the “as” keyword. This method is generally used to prevent functions with the same name from conflicting in different files.</li></ul><pre>import {user as person} from &#39;./user.js&#39;</pre><ul><li><strong>namespaces:</strong> We can use “* as” keywords to import all functions within a single object. We can import all the functions we export in a file with a single name.</li></ul><pre>import * as profile from &#39;/user.js&#39;<br>profile.ageCalculate();<br>profile.user();</pre><ul><li><strong>combine exports: </strong>When we need multiple modules in a single file, we can create a new file and import the modules we want to use there. When we need several modules in one file, we do not need to open a new file. However, when we need a lot of modules, we can collect the modules in a new file as in the example below. Then, we can write much cleaner code using this module directly. I use this method frequently and I think it increases the readability and reusability of the code.</li></ul><pre>// combine.js<br>import * as profile from &#39;user.js&#39;;<br>import * as calc from &#39;calc.js&#39;;<br>....</pre><pre>// main.js<br>import * as combine from &#39;combine.js&#39;<br><br>combine.profile.ageCalculate();</pre><ul><li><strong>dynamic import:</strong> We can use the dynamic import feature to import the module we want to use only when necessary. In this way, we can make the code more efficient and control the modules we need better. You can see an example of using dynamic import in the code block below.</li></ul><pre>//main.js<br>if(a == b) {<br>  const {user} = await import(&#39;./user.js&#39;);<br>  user(&#39;James Bond&#39;, &#39;5555555555&#39;);<br>}</pre><h3>The Advantages of Modules</h3><p>Let’s summarize the advantages I mentioned when talking about modules.📝</p><ul><li>Code Readability</li><li>Reusability</li><li>Ease of Teamwork</li><li>Ease of Debugging</li><li>Performance Improvements</li></ul><h3>Conclusion</h3><p>JavaScript modules are an essential part of modern web development. It is the preferred tool for developers to split code into small independent pieces and use these pieces as needed. They enable better organization and reuse of code in small and large-scale applications and make the development process more efficient.</p><p>The modules I use frequently make my development process easier. Thanks to modules, I think that making the code more readable and understandable is important for the sustainability of the project. For this reason, I recommend that every developer learn about modules and use them in their projects. 🤗<br>Best regards.</p><h3>Resources</h3><ul><li><a href="https://blog.logrocket.com/javascript-reference-guide-js-modules/">JavaScript Reference Guide: JS module ecosystem - LogRocket Blog</a></li><li><a href="https://www.freecodecamp.org/news/javascript-modules-a-beginner-s-guide-783f7d7a5fcc/">JavaScript Modules: A Beginner&#39;s Guide</a></li><li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules">JavaScript modules - JavaScript | MDN</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=e3ef549a9e33" width="1" height="1" alt=""><hr><p><a href="https://medium.com/cstech/javascript-modules-e3ef549a9e33">JavaScript Modules: Strategies to Improve Code Quality and Efficiency</a> was originally published in <a href="https://medium.com/cstech">ÇSTech</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Server-Side Rendering Evolved: Unlocking Faster TTFB and TTI with Streaming SSR]]></title>
            <link>https://medium.com/cstech/server-side-rendering-evolved-unlocking-faster-ttfb-and-tti-with-streaming-ssr-800735e37bad?source=rss----a708e03ddc8a---4</link>
            <guid isPermaLink="false">https://medium.com/p/800735e37bad</guid>
            <category><![CDATA[react]]></category>
            <category><![CDATA[web-performance]]></category>
            <category><![CDATA[nextjs]]></category>
            <category><![CDATA[server-side-rendering]]></category>
            <dc:creator><![CDATA[Oguzhan Sofuoglu]]></dc:creator>
            <pubDate>Fri, 03 Nov 2023 12:44:58 GMT</pubDate>
            <atom:updated>2023-11-03T12:44:58.847Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*C0BjOjYjnuKo0yimqbas8w.png" /><figcaption>Cover designed by <a href="https://medium.com/u/a59b94a9a014">Elif Yardımcı</a></figcaption></figure><p>Hi everyone!</p><p>In recent years, the web development world has witnessed the development of various server-oriented rendering models, in part following the widespread adoption of Single Page Applications (SPAs). In this article, we will discuss Streaming SSR, which aims to eliminate some of the disadvantages of Server Side Rendering (SSR), one of the most popular rendering patterns.</p><blockquote>To better comprehend the impact of these rendering patterns, we will also often refer to Web Vitals metrics such as TTFB, TTI, FPC or CLS. You can revisit these metrics for a more comprehensive understanding at this link: <a href="https://web.dev/articles/user-centric-performance-metrics">https://web.dev/articles/user-centric-performance-metrics</a></blockquote><p>So, what exactly is Streaming SSR, and how does it differentiate itself in the realm of web development? Let’s embark on a journey to explore this exciting new rendering pattern.</p><h4><strong>What is </strong>Server-Side Rendering (SSR)<strong>?</strong></h4><p>Server Side Rendering is one of the popular rendering patterns where web pages are initially rendered on the server before being sent to the client’s browser. In contrast to client-side rendering, where the browser handles most of the rendering work, SSR performs the rendering on the server.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/800/0*YeCRC1fFv5nOGrZ7" /><figcaption>The working mechanism of SSR [<a href="https://javascriptpatterns.vercel.app/patterns/rendering-patterns/server-side-rendering">Source</a>]</figcaption></figure><p>Here’s how it works:</p><ol><li>A request is sent from the client to the server.</li><li>On the server, HTML is generated. The server has the ability to create new HTML content for each request. This HTML is then sent to the browser. (<strong>TTFB point</strong>)</li><li>The browser parses and renders this HTML. At this point, we have a UI that can be displayed to the user, but the user cannot interact with it because we need JavaScript.</li><li>The browser sends a request to fetch the necessary JavaScript bundle and downloads it.</li><li>The browser executes the JavaScript and performs hydration. <strong>(TTI Point)</strong></li></ol><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*wYxwDKlTZlm5p9gPCxP-SA.png" /><figcaption>Web Vital Metrics for SSR [<a href="https://javascriptpatterns.vercel.app/patterns/rendering-patterns/server-side-rendering">Source</a>]</figcaption></figure><p>Some key benefits of Server-Side Rendering are:</p><ol><li><strong>Improved SEO</strong>: Search engines can easily crawl and index the content because the initial page load is fully rendered on the server. This can lead to better search engine rankings compared to purely client-side rendering, which search engines may have difficulty parsing.</li><li><strong>Accessibility:</strong> SSR can enhance accessibility because the initial HTML content is readily available, making it easier for screen readers and other assistive technologies to interpret the content.</li><li><strong>Better User Experience:</strong> Since users receive a fully rendered page, they can start consuming the content more quickly, providing a better user experience. Also no flicker UI issues or CLS problems.</li></ol><p><strong><em>Is everything about SSR so good? </em></strong>Unfortunately, no. Like any rendering pattern, SSR has strengths and weaknesses too. We will examine two potential drawbacks of Server-Side Rendering (SSR), which are <strong>Initial Waiting Time </strong>which is related<strong> </strong>Time to First Byte (TTFB) metric and <strong>The Interactive Delay </strong>which is related<strong> </strong>Time to Interactive (TTI) metric.</p><p><strong>TTFB — The Initial Waiting Time:</strong> One downside of SSR is the prolonged Time to First Byte (TTFB), which is the time it takes for the first byte to reach the user’s browser. This delay occurs because SSR involves rendering all HTML on the server, including bundling JavaScript, which requires waiting for essential data requests and executing rendering logic. As a result, users may experience a blank screen during the initial loading process, which can impact the user experience.</p><p><strong>TTI — The Interactive Delay:</strong> In the context of SSR, Time to Interactive (TTI) can be delayed. While the initial HTML may be visible, full interactivity is postponed as the browser loads and executes JavaScript. This delay can affect the overall user experience.</p><p>A new rendering pattern has entered our lives with React 18 to mitigate these two adverse effects: <strong>Streaming SSR</strong>.</p><h3>What is the Streaming SSR?</h3><p>Streaming SSR is a method that improves TTFB and TTI while performing server-side rendering. The logic behind streaming is that we have a concept called Node streams, which allows us to continuously transfer data in pieces.</p><p>In standard SSR, rendering all the HTML that makes up our page on the server and then transferring all the necessary JS for that HTML to the client via a bundle, as discussed in the previous section, revealed the disadvantages of TTFB and TTI. Streaming SSR provides a solution by rendering each component separately and creating JS bundles on a component-by-component basis, allowing us to stream everything in pieces (we called them chunks) that we will show on the page.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/800/0*jiYO-UiGVK2_0QTT" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/800/0*XKnwBY1S7NqSW5Bg" /><figcaption>Left: SSR | Right: Streaming SSR [<a href="https://javascriptpatterns.vercel.app/patterns/rendering-patterns/streaming-ssr">Source</a>]</figcaption></figure><p>Let’s try to understand how it works by examining it step by step:</p><ol><li>A request is sent from the client to the server.</li><li>The server now returns a mechanism for data transfer using node streams along with a basic HTML file to the browser. (This basic HTML file also contains the necessary data for SEO, so we don’t have any SEO disadvantage.)</li><li>The client receives this HTML and parses it just like it behaves in SSR. Node stream data flow also starts at this point.</li><li>The server transmits the UI of the completed rendering components and the necessary JS in chunks to the browser.</li><li>The browser executes and hydrates these chunks, making them ready.</li></ol><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*be4s9j9CGvJNUlPpdm26cg.png" /><figcaption>Web Vital metrics for Streaming SSR [<a href="https://javascriptpatterns.vercel.app/patterns/rendering-patterns/streaming-ssr">Source</a>]</figcaption></figure><p>One of the most notable benefits of this approach is the elimination of the need to wait for the entire server-rendered content to be generated. Consequently, the Time to First Byte (TTFB) is significantly reduced.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/800/0*J-4iAND-wXxj_8OY" /><figcaption>Web Vitals Comparision for SSR vs Streaming SSR [<a href="https://www.patterns.dev/posts/streaming-ssr">Source</a>]</figcaption></figure><p>Another noteworthy advantage pertains to the process of hydration. In traditional Server-Side Rendering (SSR), the entire execution of a substantial JavaScript bundle was required. This bundle encompassed code for all the elements on the page. However, with the new approach, we can selectively execute only the necessary code for a specific portion, leading to a vastly improved Time to Interactive (TTI).</p><p>As a result, the moment the hydration of the initial chunk is completed, the Time to Interactive (TTI) becomes nearly instantaneous. This signifies that the browser becomes interactive at this very point.</p><h3><strong>Streaming SSR Implementation w/NextJs 13</strong></h3><p>We have completed the theoretical part. Now let’s learn how to implement this new pattern with Next.js.</p><p>With NextJS 13, data fetching methods have changed a bit from previous versions. Now, with default server components, you can fetch data directly within a component without using any effect hooks or server-side props such as getServerSideProps.</p><p>For example, you can see a standard SSR page structure below:</p><pre><br>export default async function Page() {<br><br>  /**<br>   * To shorten the TTFB time, requests are optimized by parallelizing them.<br>   */<br>  const productsPromise = getProducts();<br>  const personsPromise = getPersons();<br>  const plansPromise = getPlans();<br><br>  const [productData, personsData, plansData] = await Promise.allSettled([<br>    productsPromise,<br>    personsPromise,<br>    plansPromise<br>  ]);<br><br>  return (<br>    &lt;div&gt;<br>      &lt;Products data={productData} /&gt;<br>      &lt;Persons data={personsData} /&gt;<br>      &lt;Plans data={plansData} /&gt;<br>    &lt;/div&gt;<br>  );<br>}</pre><p>In this structure, before the user can view the page, all requests must first be completed, and then all components on the page must be created on the server side using this data. The HTML and JS resulting from this process are sent to the browser.</p><h4><strong>So how do we implement streaming SSR in this structure?</strong></h4><ol><li><strong>Component-Specific Data Fetching</strong></li></ol><p>Each component should be in charge of getting its own data. The main idea is to separate the rendering of components and make sure that any component with its data ready can be shown on its own. So, we need to start splitting up our data requests for each component.</p><p>2. <strong>React Suspense</strong></p><p>We need to wrap Component with Suspense to tell React that this component can be rendered with streaming SSR.</p><p>We already knew the Suspense and were used for Code Splitting. With React 18, Suspense allows us to create streamable components. For more detail look at this <a href="https://react.dev/reference/react-dom/server/renderToReadableStream#streaming-more-content-as-it-loads">React Doc</a>.</p><p>Let’s look below implementation closely:</p><pre>export default function Page() {<br><br>  return (<br>    &lt;div&gt;<br>      &lt;Suspense fallback={&lt;Skeleton/&gt;}&gt;<br>        &lt;Persons /&gt;<br>      &lt;/Suspense&gt;<br>      &lt;Suspense fallback={&lt;Skeleton/&gt;}&gt;<br>        &lt;Plans /&gt;<br>      &lt;/Suspense&gt;<br>      &lt;Suspense fallback={&lt;Skeleton/&gt;}&gt;<br>        &lt;Products /&gt;<br>      &lt;/Suspense&gt;<br>    &lt;/div&gt;<br>  );<br>}</pre><p>In Streaming SSR, every component wrapped with Suspense completes its own rendering after completing its own fetching and is then <strong>streamed</strong> to the browser. This means that we don’t need to wait for all three requests to complete and the entire page rendering to finish, as we would in a standard SSR example. Also after the first hydration (it means TTI point) browser becomes user-interactive. So that the user doesn&#39;t have to wait for other components that are still rendering.</p><p>Another advantage of streaming is that you can even use it externally for a child component on your page. There is no limitation to this. Thus, you can apply this method even to the bottom child of nested components.</p><p>In addition to these, Next.js 13 also provides a Loading UI feature that relies on streaming. This helps improve the user experience by displaying skeletons or what you want to display in the content section of your page until the Time To First Byte (TTFB) is completed. This way, users can see a loading indicator or placeholders until the actual content is ready, enhancing the overall UX. For more details follow <a href="https://nextjs.org/docs/app/building-your-application/routing/loading-ui-and-streaming">the link</a>.</p><blockquote><strong>Also, I created a basic demo that includes standard SSR page, SSR + Loading UI page and Streaming SSR page.</strong></blockquote><blockquote><strong>You can review the </strong><a href="https://streaming-ssr-demo.vercel.app/"><strong>live demo</strong></a><strong> here and reach out source code </strong><a href="https://github.com/Ogzhnsfgl/streaming-ssr-demo"><strong>here.</strong></a></blockquote><h3>Conclusion</h3><p>In this article, we have dived into the fascinating world of Streaming Server-Side Rendering (SSR), an exciting new rendering pattern that has emerged in the ever-evolving landscape of web development.</p><p>Streaming SSR comes as a promising solution to address some of the longstanding challenges associated with traditional Server-Side Rendering (SSR), namely Time to First Byte (TTFB) and Time to Interactive (TTI) delays. In addition, streaming SSR brings brand new options to hybrid structures such as CSR + SSR, which we use to optimize performance. This is really exciting.</p><p>As <a href="https://medium.com/u/ef0a84cf7f9d">ÇSTech</a>, we closely follow and care about innovations such as Streaming SSR for a better UX and DX, and try to implement them in our current applications.</p><p>As I always say, you can always reach me at the addresses below for your questions or suggestions.</p><p>Until we meet again, stay in tech.</p><p><strong><em>Oğuzhan Sofuoğlu</em></strong></p><p><strong><em>Frontend Developer @</em></strong><a href="https://medium.com/u/ef0a84cf7f9d"><strong><em>ÇSTech</em></strong></a></p><p><a href="https://github.com/Ogzhnsfgl"><em>Github</em></a><em> | </em><a href="https://www.linkedin.com/in/oguzhan-sofuoglu/"><em>Linkedin</em></a><em> | </em><a href="http://osofuoglu.vercel.app/"><em>Personal Website</em></a></p><p><em>References:</em></p><ul><li><a href="https://javascriptpatterns.vercel.app/patterns/rendering-patterns/streaming-ssr">Streaming Server-Side Rendering | JavaScript Patterns</a></li><li><a href="https://www.patterns.dev/posts/streaming-ssr">Streaming Server-Side Rendering</a></li><li><a href="https://react.dev/blog/2021/12/17/react-conf-2021-recap#streaming-server-rendering-with-suspense">React Conf 2021 Recap - React</a></li><li><a href="https://nextjs.org/docs/app/building-your-application/routing/loading-ui-and-streaming">File-system conventions: loading.js | Next.js</a></li><li><a href="https://web.dev/articles/user-centric-performance-metrics">User-centric performance metrics | Articles | web.dev</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=800735e37bad" width="1" height="1" alt=""><hr><p><a href="https://medium.com/cstech/server-side-rendering-evolved-unlocking-faster-ttfb-and-tti-with-streaming-ssr-800735e37bad">Server-Side Rendering Evolved: Unlocking Faster TTFB and TTI with Streaming SSR</a> was originally published in <a href="https://medium.com/cstech">ÇSTech</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>