<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Manychat</title>
    <description>The latest articles on Forem by Manychat (@manychat).</description>
    <link>https://forem.com/manychat</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Forganization%2Fprofile_image%2F7074%2F76bab840-ef5b-41a9-bbed-d45ae3dca231.png</url>
      <title>Forem: Manychat</title>
      <link>https://forem.com/manychat</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/manychat"/>
    <language>en</language>
    <item>
      <title>Frontend Performance Patterns to speed up your Web App</title>
      <dc:creator>Manychat Engineering</dc:creator>
      <pubDate>Mon, 04 May 2026 10:53:16 +0000</pubDate>
      <link>https://forem.com/manychat/frontend-performance-patterns-to-speed-up-your-web-app-4d0i</link>
      <guid>https://forem.com/manychat/frontend-performance-patterns-to-speed-up-your-web-app-4d0i</guid>
      <description>&lt;h2&gt;
  
  
  How intentional loading decisions keep your app fast at scale.
&lt;/h2&gt;

&lt;p&gt;Frontend performance is not a late-stage cleanup task. It’s not tech debt. It’s a set of decisions we make every day while we code — what we load, when we load it, and how we render it. The answer depends on the importance of the code, its size, and when the user actually needs it.&lt;/p&gt;

&lt;p&gt;Get that wrong, and the browser pays for everything upfront — bytes, main thread, network — whether the user ever sees it or not.&lt;/p&gt;

&lt;p&gt;I’m &lt;a href="https://www.linkedin.com/in/lianansan/" rel="noopener noreferrer"&gt;Liana&lt;/a&gt;, a frontend engineer at &lt;a href="https://careers.manychat.com/team/engineering" rel="noopener noreferrer"&gt;Manychat&lt;/a&gt;. In this article we cover five patterns we use to get this right — four import strategies and compression — and how we measure whether it’s working.&lt;/p&gt;

&lt;h2&gt;
  
  
  Import Patterns
&lt;/h2&gt;

&lt;p&gt;Manychat uses 24 import patterns in practice, grouped into 7 categories — from static and dynamic to type, asset, style, re-exports, and legacy tooling. In practice, two dominate: static imports at 99.6% of the codebase, dynamic imports at 0.4%.&lt;/p&gt;

&lt;h4&gt;
  
  
  Pattern 1 — Static Imports
&lt;/h4&gt;

&lt;p&gt;Static imports are required for the first meaningful paint. Layout, router, core UI — everything that must exist before the user sees anything. If it’s there on first load, it’s a static import.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgbbcbfdpc2a7gmfb0y9r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgbbcbfdpc2a7gmfb0y9r.png" alt=" " width="492" height="510"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you look carefully at how static imports are ordered: Node.js plugins go on the top level — that’s how the formatter works. Then React core, then external packages. Then dependencies, modules, and other packages.&lt;/p&gt;

&lt;h4&gt;
  
  
  Pattern 2 — Dynamic imports
&lt;/h4&gt;

&lt;p&gt;0.4% of the codebase. Small number, high impact.&lt;br&gt;
You can see how they differ from static imports in the code — you need a separate file where you define a path and what needs to be imported on the lazy part:&lt;/p&gt;

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

&lt;p&gt;Where is it in the UI? Everywhere where there’s a very heavy screen. Each route becomes a separate chunk which is loaded only on navigation.&lt;/p&gt;

&lt;p&gt;A good example is the Flow Player page that you can access by creating an automation, sharing it from the CMS list, and handing the link to someone outside Manychat. It’s heavy. There’s no reason to pay for it on app load.&lt;/p&gt;

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

&lt;p&gt;What dynamic import does — it doesn’t pay for code until the user goes there.&lt;/p&gt;

&lt;h4&gt;
  
  
  Pattern 3 — Import on Interaction
&lt;/h4&gt;

&lt;p&gt;This is used for optional UI — modals, popovers, or similar things triggered by the user.&lt;/p&gt;

&lt;p&gt;We actually don’t use it in our codebase, but we use something very similar: import on render, which is lazy-loaded on mount, not on interaction. You can see this in our modals — all of them work exactly the same way. Why? Because our modals are very lightweight, and there’s no need for import-on-interaction specifically. All our modals render immediately inside Suspense — they just load their chunks lazily, avoiding the cost of features many users never open.&lt;/p&gt;

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

&lt;h4&gt;
  
  
  Pattern 4 — Import on Visibility
&lt;/h4&gt;

&lt;p&gt;The component loads when it enters the viewport. This avoids competing with the initial render and reduces the chunk size.&lt;/p&gt;

&lt;p&gt;A good example is infinite scroll in TikTok and Instagram automation. When you want to pick a post or reel, a modal opens — and if you have a lot of them, you get an infinite scroll. It avoids loading chunks the user hasn’t scrolled to yet. We have a reusable sentinel component that handles this across the app.&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Why not just one import pattern?&lt;/strong&gt;&lt;br&gt;
One pattern doesn’t fit all. Our goal is to make a right-sized chunk for what we want to load — because it’s bytes plus main thread plus network. We define them the same way we define error severity:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Critical&lt;/strong&gt; — load immediately (static)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Heavy&lt;/strong&gt; — load on navigation (dynamic)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Optional&lt;/strong&gt; — load on interaction&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Can we combine them?&lt;/strong&gt;&lt;br&gt;
Yes — in layers, not as one mega-pattern. And you don’t literally need every technique. That’s overengineering. Define what you want to optimize and why.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why don’t we use some patterns — hover/focus, prefetch, idle prefetch?&lt;/strong&gt;&lt;br&gt;
It’s always a question of cost and benefit, and we always run the risk around cache and CDN. Sometimes absence is a deliberate priority — not that we disagree with the idea.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Will it actually change performance?&lt;/strong&gt;&lt;br&gt;
Like other optimization patterns — it depends on what you measure and where it hurts. Treat them as targeted experiments. They’re useful when you want a specific interaction to feel immediate.&lt;/p&gt;

&lt;h4&gt;
  
  
  Compression pattern
&lt;/h4&gt;

&lt;p&gt;Imports decide what code loads and when — compression decides how much it weighs when it gets there. Where imports operate at the application bundle layer, compression operates at the origin server and CDN — how you finally deliver bytes to the client.&lt;/p&gt;

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

&lt;p&gt;At Manychat we use two compression utilities: Gzip and Brotli. Both shrink files before they travel over the network and decompress them transparently in the browser. Both are lossless encodings for text-like content (JS, CSS, HTML, JSON, SVG — not already-compressed binaries like most JPEG/PNG).&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy4zvsayaa1u91w3770tc.png" alt=" " width="800" height="360"&gt;&lt;/th&gt;
&lt;th&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fplm8y5fzljzj4ufrxo6z.png" alt=" " width="800" height="361"&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;You can check this in the network tab — go to JS files, look at response headers (look for content-encoding: br or gzip).&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Gzip is the classic one, supported by every browser. Brotli compresses better, is a little slower, but delivers smaller chunks. Browsers and CDNs pick the best mutually supported algorithm from Accept-Encoding — supporting both gives a good baseline with Gzip and better size where Brotli is available.&lt;/p&gt;

&lt;p&gt;Rule: prefer Brotli for static assets where supported; keep Gzip as fallback where needed.&lt;/p&gt;

&lt;h4&gt;
  
  
  How do we know the patterns are working?
&lt;/h4&gt;

&lt;p&gt;With user-centric metrics and repeatable team habits.&lt;/p&gt;

&lt;p&gt;We rely on Core Web Vitals — loading experience, responsiveness, and visual stability — via the &lt;a href="https://github.com/GoogleChrome/web-vitals" rel="noopener noreferrer"&gt;web vitals library&lt;/a&gt; from Google. When a user stays on a page long enough, an analytics event fires: app_metrics user_interactive_performance. The central place in the codebase is log_web_vitals.&lt;/p&gt;

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

&lt;p&gt;Beyond Core Web Vitals we track two more things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;INP (Interaction to Next Paint) — real-world interaction responsiveness&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Long Tasks — where the user can feel that the app is stuck&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both are collected only for logged-in users and visible in Grafana dashboards. For Flow Builder specifically — the heaviest part of Manyсhat — we track INP on both desktop and mobile. In an ideal world every major component would have its own dashboard. For now, we start where it hurts most.&lt;/p&gt;

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

&lt;p&gt;For audits and payload analysis we use &lt;a href="https://github.com/GoogleChrome/lighthouse" rel="noopener noreferrer"&gt;Lighthouse&lt;/a&gt; — a built-in Chrome tool that generates a detailed performance report for any page. It’s useful for catching issues before they reach real users.&lt;br&gt;
For day-to-day development we use browser DevTools — the network and performance tabs show what’s happening in real time while we code.&lt;/p&gt;




&lt;p&gt;Performance is not a one-time fix. Every import decision, every byte that travels over the wire — these are choices that compound over time. Get them right consistently, and users never notice. Get them wrong, and they leave.&lt;/p&gt;

&lt;p&gt;The patterns we covered — imports and compression — are not exotic optimizations. They’re the baseline. The metrics are what keep you honest: if you can’t see it, you can’t improve it.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If you want to learn more about how we build Manychat and who we’re currently looking for, check out &lt;a href="https://careers.manychat.com/" rel="noopener noreferrer"&gt;Manychat Careers&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>frontend</category>
      <category>performance</category>
    </item>
    <item>
      <title>Streamlining frontend CI/CD pipelines with enhanced observability</title>
      <dc:creator>Sergii Sergieiev</dc:creator>
      <pubDate>Tue, 17 Dec 2024 11:44:59 +0000</pubDate>
      <link>https://forem.com/manychat/streamlining-frontend-cicd-pipelines-with-enhanced-observability-2g4i</link>
      <guid>https://forem.com/manychat/streamlining-frontend-cicd-pipelines-with-enhanced-observability-2g4i</guid>
      <description>&lt;p&gt;I'm Sergii Sergieiev, an Engineering Manager with over 20 years of experience in software development. I've spent most of my career in big tech, and for the past four years I've been working at Manychat.&lt;/p&gt;

&lt;p&gt;In this article, we'll explore why CI/CD observability are so crucial for the development process and look at tools that can help improve them.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is CI/CD
&lt;/h2&gt;

&lt;p&gt;First, let's cover the basics. CI/CD stands for Continuous Integration and Continuous Deployment. These techniques and practices are designed to enhance your development process, ensuring the seamless integration and deployment of new features.&lt;/p&gt;

&lt;p&gt;When I first joined the company, deploying was a one-step process that took about 10 minutes. Curious about whether this was too long, I asked my teammates. One casually replied, "It's just long enough to grab a coffee."&lt;/p&gt;

&lt;p&gt;Now, think about it: is 10 minutes too long for your build? What about 5 minutes - does that feel more reasonable?&lt;/p&gt;

&lt;p&gt;At first glance, these times might seem fine. But the real question isn't just about the minutes - it's about what they represent for efficiency and performance.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;…when you can measure what you are speaking about, and express it in numbers, you know something about it.&lt;br&gt;
&lt;em&gt;William Thomson, 1st Baron Kelvin&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Observability allows us to monitor and measure various aspects of our CI/CD pipeline, helping us identify bottlenecks, optimize processes, and ultimately deliver software more quickly and reliably.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key steps of our CI/CD
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Preparation: npm, environment, etc.&lt;/li&gt;
&lt;li&gt;Build phases&lt;/li&gt;
&lt;li&gt;Testing: Unit, UI, and End-to-End (E2E) tests&lt;/li&gt;
&lt;li&gt;Deployment&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We should measure and understand the time and resources deployment costs us. It's essential to assess the deployment process, including the time spent and the speed of execution, to identify areas for improvement.&lt;/p&gt;

&lt;h2&gt;
  
  
  DORA Metrics
&lt;/h2&gt;

&lt;p&gt;The DevOps Research and Assessment (DORA) team focuses on four meaningful metrics in the CI/CD process:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Deployment Frequency&lt;/strong&gt; (DF) measures how often a team successfully releases to production. High-performing teams typically deploy more frequently, ranging from multiple deployments per day to a few per week, indicating agility and responsiveness to the market and customer needs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lead Time for Changes&lt;/strong&gt; (LT) measures the time it takes for a commit to be deployed into production. Shorter lead times indicate faster delivery of value to customers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Time to Restore Service&lt;/strong&gt; (TRS) measures the time it takes for the team to recover from a failure in the production environment.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Change Failure Rate&lt;/strong&gt; (CFR) measures the percentage of deployments causing a failure in production that requires immediate remedy (such as a rollback or a hotfix). A lower change failure rate indicates better quality control and higher reliability of the deployment process.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  A look back: the Manychat build process
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;How we started: long run,  &amp;gt; 10 min&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Four years ago, the Manychat build process had a single large step taking over 10 minutes with unpredictable timing. If something went wrong, we couldn't identify exactly what caused the problem.&lt;/p&gt;

&lt;p&gt;We needed to go into logging and invest significant time in investigating issues. Without breaking this step into smaller parts, fixing issues could take multiple attempts, each consuming about 12 minutes. In the worst case, it might take an hour just to fix the CI/CD pipeline.&lt;/p&gt;

&lt;p&gt;Additionally, we couldn't run parallel jobs due to limitations in the tools, which were based on an outdated version.&lt;/p&gt;

&lt;p&gt;Although it wasn't my main focus, I began investigating tools that could fix this problem, and help us gain better control of our process.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementing GitHub Actions
&lt;/h2&gt;

&lt;p&gt;We use GitHub for development, and the first tool we considered was &lt;a href="https://docs.github.com/en/actions" rel="noopener noreferrer"&gt;GitHub Actions&lt;/a&gt;. Upon implementing GitHub Actions, we immediately saw our first results: the ability to run parallel jobs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe6smj9a7mmqw63naqm08.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe6smj9a7mmqw63naqm08.png" alt="GitHub Actions Steps" width="800" height="565"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Perks we've got
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Improved speed line&lt;/strong&gt;: We can run multiple jobs in parallel, eliminating the need to wait for tasks like type checking to finish before starting the build process.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Visual flow:&lt;/strong&gt; Allows us to identify issues and pinpoint time-consuming tasks more effectively.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Custom runners&lt;/strong&gt;: By using GitHub runners, we can create local runners with substantial resources.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Later, GitHub introduced the ability to easily configure runners based on resource consumption, which we leveraged to avoid running our own runners on separate infrastructure.&lt;/p&gt;

&lt;h2&gt;
  
  
  Before vs. after
&lt;/h2&gt;

&lt;p&gt;After setting up this configuration, we gained several key benefits. Firstly, we now have clear timings for each CI/CD step, allowing us to see exactly how much time is spent on each meaningful stage. This step separation enables us to segment the CI/CD process according to our needs.&lt;/p&gt;

&lt;p&gt;With this detailed insight, we can focus on the most time-consuming steps to identify and resolve issues more effectively. Consequently, our build times have significantly decreased.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Build: ≈ 1 min&lt;/li&gt;
&lt;li&gt;Unit tests: ≈ 3 min&lt;/li&gt;
&lt;li&gt;UI test: ≈ 1 min&lt;/li&gt;
&lt;li&gt;Deploy: ≈ 30 sec&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We set up monitoring for these steps so we could observe them dynamically.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwssn0wi1nb8cdhwfskbw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwssn0wi1nb8cdhwfskbw.png" alt="Build steps in CloudWatch" width="800" height="251"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Tools
&lt;/h2&gt;

&lt;p&gt;These are the tools that helped us improve the process.&lt;/p&gt;

&lt;h3&gt;
  
  
  Esbuild
&lt;/h3&gt;

&lt;p&gt;We have transitioned to using &lt;a href="https://esbuild.github.io" rel="noopener noreferrer"&gt;Esbuild&lt;/a&gt; for our project's build process and, experiencing a substantial increase in speed compared to our previous setup with Webpack. The primary bottleneck we faced with Webpack was its long build times. Now, with Esbuild integrated into our development environment, our build times have been dramatically reduced to about five seconds, significantly enhancing the efficiency of our workflow.&lt;/p&gt;

&lt;p&gt;Additionally, Esbuild offers an intuitive plugin system that is particularly user-friendly for frontend developers. This system allows creation of custom plugins, which streamline various processes within Esbuild, further increasing its versatility and usefulness in our development process.&lt;/p&gt;

&lt;h3&gt;
  
  
  Playwright
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://playwright.dev" rel="noopener noreferrer"&gt;Playwright&lt;/a&gt;, a UI testing framework developed by Microsoft, offers an exceptional developer experience. It streamlines the management and debugging of UI test errors, making it easier and more efficient to identify and resolve issues. Playwright also delivers high performance, enhancing test execution times and overall efficiency.&lt;/p&gt;

&lt;h3&gt;
  
  
  CloudWatch (AWS)
&lt;/h3&gt;

&lt;p&gt;We have also integrated &lt;a href="https://aws.amazon.com/cloudwatch/" rel="noopener noreferrer"&gt;CloudWatch&lt;/a&gt; into our infrastructure for monitoring metrics, which has streamlined our monitoring process, making it more effective.&lt;/p&gt;

&lt;h3&gt;
  
  
  Custom Visualization
&lt;/h3&gt;

&lt;p&gt;To effectively monitor the timing and key focus areas within our CI/CD pipeline, created a detailed graph. This visual aid clarifies the sequence and pivotal steps of the process. To achieve this, I initiated an internal hackathon. In just one day, a team of two developers crafted an internal service to visualize this workflow, giving us a comprehensive view of our entire CI/CD process.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft5bjwxw3iwedzkjskufe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft5bjwxw3iwedzkjskufe.png" alt="Visualize jobs and pipelines executions as traces" width="800" height="1234"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Big wins we've scored
&lt;/h2&gt;

&lt;p&gt;To date, our achievements include segmenting our process into distinct parts, resulting in a threefold increase in build speed and a significant enhancement of our feedback loop.&lt;/p&gt;

&lt;p&gt;This improvement has enabled us to closely monitor our entire CI/CD pipeline, making the development of internal tools not only productive but also enjoyable. Interestingly, although it wasn't our initial goal, this approach has led to an impressive 200% reduction in our monthly resource consumption.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where to start
&lt;/h2&gt;

&lt;p&gt;To optimize your CI/CD pipeline, start by breaking down the process into distinct steps. Prioritize not only the major steps but also those with the most significant impact on the overall timeline. Collaboration is essential: integrate tool building and CI/CD infrastructure setup seamlessly.&lt;/p&gt;

&lt;p&gt;Additionally, transition from on-demand to continuous measurement of these steps to maintain a daily overview of releases and process efficiency. This approach is crucial for anyone aiming to enhance observability and the tools that support it.&lt;/p&gt;

</description>
      <category>cicd</category>
      <category>observability</category>
    </item>
    <item>
      <title>Burning Bugs at Manychat: Sharing Expertise and Experience in Bug Management</title>
      <dc:creator>Dmitrii Mironov</dc:creator>
      <pubDate>Thu, 08 Jun 2023 11:14:47 +0000</pubDate>
      <link>https://forem.com/manychat/burning-bugs-at-manychat-sharing-expertise-and-experience-in-bug-management-4fha</link>
      <guid>https://forem.com/manychat/burning-bugs-at-manychat-sharing-expertise-and-experience-in-bug-management-4fha</guid>
      <description>&lt;p&gt;For several years of work in Manychat, I have accumulated expertise and experience in bug management and resolution. Today, I am thrilled to share valuable insights with the LinkedIn community. In this article, we will delve into the essential practices that our team follows to effectively burn bugs and ensure a smooth operation of our platform while delivering an outstanding user experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sync with the Product Owner
&lt;/h2&gt;

&lt;p&gt;Our team maintains regular sync meetings with the Product Owner to establish seamless collaboration and align priorities. These discussions allow us to address urgent bug issues, allocate appropriate resources, and ensure a shared understanding of bug priorities for efficient resolution.&lt;/p&gt;

&lt;h2&gt;
  
  
  OKR-Driven Bug Management with Weekly Metrics
&lt;/h2&gt;

&lt;p&gt;At Manychat, we embrace a results-oriented approach by setting clear objectives and key results (OKRs) for bug management. These measurable goals serve as a guiding force, and we emphasize the importance of tracking and reviewing weekly metrics. By analyzing these metrics, we monitor bug resolution progress, identify bottlenecks, and make data-driven decisions to optimize our bug-burning process continually.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tech Days: Uniting for Bug Burning
&lt;/h2&gt;

&lt;p&gt;In our pursuit of efficient bug resolution, we organize dedicated Tech Days, where all teams come together to focus solely on burning bugs. These special occasions foster collaboration and create a conducive environment for engineers from diverse disciplines to share knowledge and expertise. Through this collective effort, we expedite bug resolution, enhance cross-functional understanding, and strengthen the bonds within our team.&lt;/p&gt;

&lt;h2&gt;
  
  
  Making Time to Burn Bugs Inside Sprints
&lt;/h2&gt;

&lt;p&gt;Recognizing the importance of bug resolution, we allocate dedicated time within our sprint cycles to address bugs. Integrating bug-burning sessions into each sprint ensures that bugs receive the attention they deserve. This practice balances delivering new features and maintaining a stable and reliable platform, ultimately enhancing the overall code quality and user experience.&lt;/p&gt;

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

&lt;p&gt;Bug management at Manychat is not just a reactive process but a proactive and continuous effort driven by our collective expertise and commitment. By syncing with the Product Owner, following OKR-driven bug management with weekly metrics, organizing Tech Days, and making time to burn bugs inside sprints, we strive to deliver a robust, bug-free software experience that empowers businesses to connect seamlessly with their customers.&lt;/p&gt;

&lt;p&gt;Please feel free to share your thoughts and talk about our bug-burning approach in the comments section below. Together, let's shape a bug-free future and elevate the standard of software excellence!&lt;/p&gt;

</description>
      <category>codequality</category>
      <category>testing</category>
      <category>bugs</category>
      <category>management</category>
    </item>
    <item>
      <title>Manychat Product Engineering Meetup in Barcelona</title>
      <dc:creator>Anna Kriukova</dc:creator>
      <pubDate>Wed, 07 Jun 2023 18:57:41 +0000</pubDate>
      <link>https://forem.com/manychat/manychat-product-engineering-meetup-in-barcelona-1ooi</link>
      <guid>https://forem.com/manychat/manychat-product-engineering-meetup-in-barcelona-1ooi</guid>
      <description>&lt;p&gt;We're thrilled to host our &lt;strong&gt;first tech meetup in Barcelona&lt;/strong&gt; on June 15, 2023!&lt;/p&gt;

&lt;p&gt;Join us to discuss various aspects of &lt;strong&gt;Product Engineering&lt;/strong&gt; together with speakers from Manychat and Semrush.&lt;/p&gt;

&lt;p&gt;Here're three talks for this evening:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Product Engineer: Your Next Step in IT — Aleksandr Lavrinenko (Engineering Manager, Manychat)&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Here are a few questions for engineers: Is there a difference between engineers and product engineers? What drives businesses to actively seek these professionals? Why should you consider becoming one yourself? And what actionable steps can you take to embark on this transformative journey? Join me as I explore and provide answers to these questions in my upcoming speech.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;What your company actually wants from your code — Sergei Iakovlev (Frontend Developer, Manychat)&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;The current economic uncertainty and its effect on the tech industry is an excellent trigger to ask ourselves - “How can I do my job better?”. For product engineers, this question mostly goes down to “How can my code bring more value to the company?”. We asked product owners at Manychat what they expect from good code and how it can help the business grow. In this talk, I will share the insights we gathered and the practices we use to meet their expectations and achieve bigger results as a company.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;Product development mindset for engineers — Anastasiia Kononova (Head of Engineering, Semrush)&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Are there really any special skills required for a developer to be called a ‘product engineer’? What exactly are product teams and product companies then? Are there any other options? How to choose a direction if you are just starting your career in IT or thinking about changes? We will talk about such job expectations and specifics of work in product companies compared to delivery of implementation projects.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The event language is English.&lt;/p&gt;

&lt;p&gt;Snacks, drinks, and a friendly atmosphere are on us!&lt;/p&gt;

&lt;p&gt;For more information visit &lt;a href="https://www.eventbrite.com/e/manychat-product-engineering-meetup-in-barcelona-tickets-647144485577?utm_source=devto" rel="noopener noreferrer"&gt;Eventbrite&lt;/a&gt; and register to reserve a spot!&lt;/p&gt;

&lt;p&gt;If you can't attend the events, please &lt;a href="https://www.youtube.com/live/nvMa6Y37AtQ?feature=share" rel="noopener noreferrer"&gt;join us online&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>barcelona</category>
      <category>meetup</category>
      <category>development</category>
    </item>
  </channel>
</rss>
