top of page
Search

Collecting and Sending Web Vitals to Kafka from React Applications

## Collecting and Sending Web Vitals to Kafka from React Applications


This article provides a comprehensive guide on how to collect Core Web Vitals in your React application and send them to a Kafka cluster for analysis and monitoring.  We'll cover setting up the necessary tools, instrumenting your React code, configuring a Spring Boot backend to receive and forward the vitals to Kafka, and consuming the messages.


### What are Core Web Vitals?


Core Web Vitals are a set of metrics that measure the user experience of your web application. They are essential for understanding how your site performs from a user's perspective and are a ranking factor for search engines.  The key vitals are:


  *LCP (Largest Contentful Paint):** Measures how long it takes for the largest content element (image, text block, etc.) to become visible within the viewport.

  *FID (First Input Delay):** Measures the time from when a user first interacts with your site (e.g., clicks a button) to the time when the browser is actually able to begin processing that interaction.

  *CLS (Cumulative Layout Shift):** A measure of how much the layout of the page shifts unexpectedly.


### Setting up the Project


1.  React Application:  Ensure you have a React project set up.  You can create one using Create React App:


    ```bash

    npx create-react-app my-web-vitals-app --template typescript

    cd my-web-vitals-app

    ```


2.  Install `web-vitals`:


    ```bash

    npm install web-vitals

    ```


3.  Spring Boot Backend: You'll need a backend service to act as an intermediary between your React app and Kafka. We'll use Spring Boot for this.  Create a new Spring Boot project (e.g., using Spring Initializr or your IDE).  Add the following dependencies to your `pom.xml`:


    ```xml

    <dependency>

        <groupId>org.springframework.boot</groupId>

        <artifactId>spring-boot-starter-web</artifactId>

    </dependency>

    <dependency>

        <groupId>org.springframework.kafka</groupId>

        <artifactId>spring-kafka</artifactId>

    </dependency>

    <dependency>

        <groupId>org.projectlombok</groupId>

        <artifactId>lombok</artifactId>

        <optional>true</optional>

    </dependency>

    ```


4.  Kafka Cluster: You'll need a running Kafka cluster.  You can set up a local cluster using Docker or use a managed Kafka service in the cloud.


### Instrumenting the React Application


1.  Create `webVitalsModule.ts`: Create a file named `webVitalsModule.ts` in your React project:


    ```typescript

    import { getCLS, getFID, getFCP, getLCP, getTTFB, Metric } from 'web-vitals';


    interface WebVitalsData {

      cls: number | undefined;

      fid: number | undefined;

      fcp: number | undefined;

      lcp: number | undefined;

      ttfb: number | undefined;

      branch: string;

      environment: string;

      component: string;

      timestamp: number;

    }


    async function sendWebVitalsToKafka(metric: Metric, componentName: string): Promise<void> {

      try {

        const vitals: WebVitalsData = {

          cls: metric.name === 'CLS' ? metric.value : undefined,

          fid: metric.name === 'FID' ? metric.value : undefined,

          fcp: metric.name === 'FCP' ? metric.value : undefined,

          lcp: metric.name === 'LCP' ? metric.value : undefined,

          ttfb: metric.name === 'TTFB' ? metric.value : undefined,

          branch: process.env.REACT_APP_BRANCH || 'development',

          environment: process.env.REACT_APP_ENVIRONMENT || 'development',

          component: componentName,

          timestamp: Date.now(),

        };


        const response = await fetch('/your-kafka-endpoint', { // Replace with your Spring Boot endpoint

          method: 'POST',

          headers: {

            'Content-Type': 'application/json',

          },

          body: JSON.stringify(vitals),

        });


        if (!response.ok) {

          console.error('Failed to send web vitals:', response.status);

        }

      } catch (error) {

        console.error('Error sending web vitals:', error);

      }

    }


    function collectWebVitals(componentName: string): void {

      getCLS((metric) => sendWebVitalsToKafka(metric, componentName));

      getFID((metric) => sendWebVitalsToKafka(metric, componentName));

      getFCP((metric) => sendWebVitalsToKafka(metric, componentName));

      getLCP((metric) => sendWebVitalsToKafka(metric, componentName));

      getTTFB((metric) => sendWebVitalsToKafka(metric, componentName));

    }


    export { collectWebVitals };

    ```


2.  Use in React Components: Import `collectWebVitals` into your components and call it within a `useEffect` hook, passing the component name:


    ```typescript

    import React, { useEffect } from 'react';

    import { collectWebVitals } from './webVitalsModule';


    function MyComponent() {

      useEffect(() => {

        collectWebVitals("MyComponent");

      }, []);


      // ... your component code

      return (<div>My Component</div>);

    }


    export default MyComponent;

    ```


### Spring Boot Backend


1.  `WebVitalsData` POJO: Create a class to represent the web vitals data:


    ```java

    import lombok.Data;


    @Data

    public class WebVitalsData {

        private Double cls;

        private Double fid;

        private Double fcp;

        private Double lcp;

        private Double ttfb;

        private String branch;

        private String environment;

        private String component;

        private Long timestamp;

    }

    ```


2.  `WebVitalsController`: Create a controller to handle the incoming POST requests from your React app:


    ```java

    import org.springframework.kafka.core.KafkaTemplate;

    import org.springframework.web.bind.annotation.PostMapping;

    import org.springframework.web.bind.annotation.RequestBody;

    import org.springframework.web.bind.annotation.RestController;

    import lombok.extern.slf4j.Slf4j;


    @RestController

    @Slf4j

    public class WebVitalsController {


        private final KafkaTemplate<String, WebVitalsData> kafkaTemplate;


        public WebVitalsController(KafkaTemplate<String, WebVitalsData> kafkaTemplate) {

            this.kafkaTemplate = kafkaTemplate;

        }


        @PostMapping("/your-kafka-endpoint")

        public void sendWebVitals(@RequestBody WebVitalsData vitals) {

            log.info("Received vitals: {}", vitals);

            kafkaTemplate.send("web-vitals-topic", vitals);

        }

    }

    ```


3.  `KafkaConfig`: Configure the Kafka producer:


    ```java

    import org.apache.kafka.clients.producer.ProducerConfig;

    import org.apache.kafka.common.serialization.StringSerializer;

    import org.springframework.boot.autoconfigure.kafka.KafkaProperties;

    import org.springframework.context.annotation.Bean;

    import org.springframework.context.annotation.Configuration;

    import org.springframework.kafka.core.DefaultKafkaProducerFactory;

    import org.springframework.kafka.core.KafkaTemplate;

    import org.springframework.kafka.support.serializer.JsonSerializer;

    import java.util.HashMap;

    import java.util.Map;


    @Configuration

    public class KafkaConfig {


        private final KafkaProperties kafkaProperties;


        public KafkaConfig(KafkaProperties kafkaProperties) {

            this.kafkaProperties = kafkaProperties;

        }


        @Bean

        public KafkaTemplate<String, WebVitalsData> kafkaTemplate() {

            Map<String, Object> props = new HashMap<>();

            props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, kafkaProperties.getBootstrapServers());

            props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class);

            props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, JsonSerializer.class);

            return new KafkaTemplate<>(new DefaultKafkaProducerFactory<>(props));

        }

    }

    ```


4.  `WebVitalsConsumer`: Create a consumer to read messages from Kafka:


    ```java

    import org.apache.kafka.clients.consumer.ConsumerConfig;

    import org.apache.kafka.common.serialization.StringDeserializer;

    import org.slf4j.Logger;

    import org.slf4j.LoggerFactory;

 
 
 

Recent Posts

See All
What we can learn from cats

That's a fascinating observation, and you've touched upon something quite profound about the apparent inner peace that some animals seem...

 
 
 

Comentários


Post: Blog2_Post

Subscribe Form

Thanks for submitting!

©2020 by LearnTeachMaster DevOps. Proudly created with Wix.com

bottom of page