前端埋点和监控(vue和react的代码实现)保姆级教学!

目录

首先!埋点和监控是有区别的 !

什么是埋点?

前端埋点的作用:

前端埋点的实现方式:

用户行为(埋点)

1.首先创一个空react框架

2. 设计行为埋点

3. 实现埋点逻辑

页面和效果:

​编辑什么是监控?

前端监控的作用:

前端监控的实现方式:

js错误总结图:

监控代码实现

目录:

main.js文件

App.js文件:

效果


首先!埋点和监控是有区别的 !

什么是埋点?

定义
前端埋点指的是在前端代码中,通过埋入特定的事件监听和数据采集代码,来跟踪用户在网站或应用上的各种行为,如点击、页面浏览、输入等。埋点数据通常会被上报到后台,用于后续的分析和优化。

前端埋点的作用
  1. 用户行为分析:通过埋点数据,分析用户如何与应用交互,例如:点击了哪些按钮、浏览了哪些页面、提交了哪些表单等。

  2. 产品优化:通过了解用户的行为路径和操作习惯,帮助产品团队优化用户体验、调整功能设计、提升转化率。

  3. 营销效果评估:帮助营销团队评估广告、促销活动等的效果,比如广告点击率、活动参与度、用户转化等。

  4. A/B 测试:收集不同版本页面的用户行为数据,比较不同版本之间的表现差异,帮助决策优化。

前端埋点的实现方式
  • 手动埋点:开发人员在代码中明确指定哪些行为需要收集和上报。

  • 可视化埋点:通过可视化工具,前端开发无需修改代码,直接在页面元素上配置需要跟踪的事件。

  • 无埋点:通过自动化工具,捕获所有的用户操作数据,无需开发人员手动指定。

用户行为(埋点)

1.首先创一个空react框架

npx create-react-app user-behavior-tracker
cd user-behavior-tracker
npm start

2. 设计行为埋点

我们将通过以下几个常见行为来进行数据收集:

  • 点击事件:用户点击按钮或链接。

  • 滚动事件:用户滚动页面时。

  • 页面加载事件:用户加载页面时。

  • 输入事件:用户在表单输入框中输入数据。

  • 页面停留时间:用户在页面上的停留时长。

3. 实现埋点逻辑

src 目录下,我们可以创建一个新的文件 trackEvents.js 来处理事件收集。

// 节流函数:防止事件过于频繁触发
const throttle = (func, delay) => {
    let lastTime = 0;  // 记录上次执行时间
    return function (...args) {
        const now = Date.now();  // 获取当前时间
        if (now - lastTime >= delay) {  // 如果当前时间与上次执行时间的差值大于等于指定的延迟时间
            func(...args);  // 执行传入的函数
            lastTime = now;  // 更新最后一次执行时间
        }
    };
};

// 事件追踪函数:负责将事件数据记录并输出
export const trackEvent = (eventType, data) => {
    const eventData = {
        eventType,  // 事件类型(例如:点击、滚动等)
        timestamp: new Date().toISOString(),  // 事件发生的时间,采用 ISO 格式
        ...data,  // 扩展其它事件数据(例如:页面地址、滚动位置等)
    };

    console.log("Event Data: ", eventData);  // 输出事件数据(可以在控制台查看)

    // 如果需要将事件数据发送到后端接口(例如进行数据分析),可以解除注释并配置 API
    // fetch('/api/track', { method: 'POST', body: JSON.stringify(eventData) });
};

// 页面加载事件追踪
export const trackPageLoad = () => {
    const startTime = Date.now();  // 页面加载时记录开始时间
    trackEvent('PAGE_LOAD', {
        url: window.location.href,  // 当前页面的 URL
        referrer: document.referrer,  // 页面来源(即从哪个页面跳转过来)
        userAgent: navigator.userAgent,  // 浏览器的用户代理信息(包含操作系统、浏览器类型等)
    });

    // 页面卸载时追踪停留时间
    window.addEventListener('beforeunload', () => {
        const endTime = Date.now();  // 页面离开时记录结束时间
        const stayTime = endTime - startTime;  // 计算停留时间(单位:毫秒)

        trackPageStayTime(stayTime);  // 调用追踪停留时间的函数
    });
};

// 页面停留时间追踪
export const trackPageStayTime = (stayTime) => {
    trackEvent('PAGE_STAY_TIME', {
        stayTime,  // 页面停留的时长
    });

    console.log(`Page Stay Time: ${stayTime} ms`);  // 在控制台输出页面停留时间
};

// 点击事件追踪
export const trackClick = (event) => {
    const target = event.target;  // 获取事件的目标元素(即点击的 DOM 元素)
    if (target && target.nodeName) {  // 如果目标元素存在且是有效的 DOM 元素
        trackEvent('CLICK', {
            targetType: target.nodeName,  // 目标元素的标签名(例如:BUTTON、DIV 等)
            targetId: target.id,  // 目标元素的 ID(如果有)
            targetClass: target.className,  // 目标元素的类名(如果有)
            pageX: event.pageX,  // 鼠标点击时的横坐标
            pageY: event.pageY,  // 鼠标点击时的纵坐标
        });
    } else {
        console.error("Error: event.target is undefined or null", event);  // 如果目标元素无效,打印错误信息
    }
};

// 滚动事件追踪
export const trackScroll = () => {
    const scrollTop = document.documentElement.scrollTop || document.body.scrollTop;  // 获取当前页面滚动的距离
    trackEvent('SCROLL', {
        scrollTop,  // 记录滚动的距离
    });
};

// 输入框事件追踪
export const trackInput = (event) => {
    const inputElement = event.target;  // 获取事件目标元素(输入框)
    if (inputElement) {  // 如果输入框存在
        trackEvent('INPUT', {
            inputType: inputElement.type,  // 输入框的类型(例如:text、password 等)
            inputValue: inputElement.value,  // 输入框当前的值
            inputId: inputElement.id,  // 输入框的 ID(如果有)
        });
    }
};

// 搜索事件追踪
export const trackSearch = (searchQuery) => {
    trackEvent('SEARCH', {
        searchQuery,  // 记录搜索的关键字或查询内容
    });
};

// 使用节流来限制滚动事件触发频率,设置为每 1000 毫秒触发一次
export const trackScrollWithThrottle = throttle(trackScroll, 1000);

// 启动页面加载时的追踪
trackPageLoad();

src 目录下,我们可以创建一个新的文件 Home.js 来处理事件收集。

import React, { useEffect, useState } from "react";
import { trackPageLoad, trackClick, trackScrollWithThrottle, trackInput, trackPageStayTime, trackSearch } from './trackEvents';

const Home = () => {
  const [startTime, setStartTime] = useState(null);
  const [searchQuery, setSearchQuery] = useState("");  // 用于存储搜索框的内容

  // 页面加载时,收集数据
  useEffect(() => {
    const loadTime = Date.now();
    setStartTime(loadTime);
    trackPageLoad();  // 只在页面加载时执行一次

    // 页面滚动监控
    const scrollHandler = () => {
      trackScrollWithThrottle(); // 使用节流后的滚动事件
    };
    window.addEventListener("scroll", scrollHandler);

    // 页面卸载时,记录离开时间并计算页面停留时间
    const unloadHandler = () => {
      const unloadTime = Date.now();
      trackPageStayTime(loadTime, unloadTime); // 计算停留时间
    };
    window.addEventListener("unload", unloadHandler);

    // 清理事件监听器
    return () => {
      window.removeEventListener("scroll", scrollHandler);
      window.removeEventListener("unload", unloadHandler);
    };
}, []);  // 确保此处依赖项是空数组,表示只在组件加载时执行一次


  // 输入框事件
  const handleInputChange = (event) => {
    setSearchQuery(event.target.value); // 更新搜索框的内容
    trackInput(event);
  };

  // 搜索按钮点击事件
  const handleSearchClick = () => {
    trackSearch(searchQuery);  // 记录最终的搜索内容
    console.log("搜索内容:", searchQuery); // 你也可以在这里进行搜索操作
  };

  // 按钮点击事件
  const handleButtonClick = (event) => {
    trackClick(event); // 传递原生事件对象
  };

  return (
    <div style={{ padding: "20px" }}>
      <h1>用户行为追踪</h1>

      <button id="myButton" onClick={handleButtonClick}>
        点击我
      </button>

      <div style={{ marginTop: "20px" }}>
        <label htmlFor="inputField">请输入内容:</label>
        <input
          id="inputField"
          type="text"
          onChange={handleInputChange}  // 捕获输入框变化
          placeholder="输入一些内容"
        />
        <button onClick={handleSearchClick}>搜索</button>  {/* 点击搜索时触发 */}
      </div>

      <div style={{ marginTop: "20px" }}>
        <p>请滚动页面,行为会被追踪...</p>
        <div style={{ height: "1500px", backgroundColor: "#f0f0f0" }}>
          <p style={{ paddingTop: "500px" }}>滚动到底部,查看滚动行为追踪</p>
        </div>
      </div>
    </div>
  );
};

export default Home;

页面和效果:

什么是监控?

定义
前端监控是指在前端应用中,通过采集和分析应用性能、错误信息、资源加载情况等数据,来监控应用的健康状态和用户体验。它主要关注系统的运行状况、性能瓶颈、错误信息等,确保前端应用的稳定性和流畅性。

前端监控的作用
  1. 错误监控:捕获和记录前端的 JavaScript 错误、网络请求失败、资源加载错误等异常情况,帮助开发团队及时发现和修复问题。

  2. 性能监控:监控页面加载时间、资源请求速度、用户交互响应速度等,识别并优化性能瓶颈,提高用户体验。

  3. 用户体验监控:通过捕获页面加载时间、错误堆栈、资源失败等问题,帮助团队理解用户在应用中遇到的困难和不流畅的地方。

  4. 网络请求监控:记录和分析 API 请求的成功率、响应时间等,确保后端接口的稳定性,及时发现接口性能问题或错误。

前端监控的实现方式
  • 错误上报:使用 try-catch 语句、全局事件监听、Promise 错误捕获等方式,捕获和上报 JavaScript 错误。

  • 性能指标:通过 performance API 或第三方库(如 Web Vitals)监控页面加载时间、白屏时间、可交互时间等指标。

  • 网络请求监控:捕获并分析 HTTP 请求的成功率、响应时间、错误信息等。

js错误总结图:

监控代码实现

目录:

/vue-error-monitor
├── /node_modules
├── /public
│   └── index.html
├── /src
│   ├── /assets
│   ├── /components
│   ├── /views
│   ├── App.vue
│   ├── main.js
│   ├── style.css
└── package.json

main.js文件

import { createApp } from 'vue';
import App from './App.vue';
import axios from 'axios';

const app = createApp(App);

// 1. 捕获全局 JavaScript 错误
window.addEventListener('error', function (e) {
    console.error('捕获到全局 JavaScript 错误:', e.message);
}, true);

// 2. 捕获未处理的 Promise 错误
window.addEventListener('unhandledrejection', function (e) {
    console.error('捕获到未处理的 Promise 错误:', e.reason);
}, true);

// 3. 捕获资源加载失败(如图片、JS、CSS)
window.addEventListener('error', function (e) {
    if (e.target instanceof HTMLImageElement) {
        console.error('图片加载失败:', e.target.src);
    } else if (e.target instanceof HTMLScriptElement) {
        console.error('JavaScript 文件加载失败:', e.target.src);
    } else if (e.target instanceof HTMLLinkElement && e.target.rel === 'stylesheet') {
        console.error('CSS 文件加载失败:', e.target.href);
    }
}, true);

// 4. 捕获 axios 请求错误
axios.interceptors.response.use(
    response => response,
    error => {
        if (error.response) {
            console.error('后端接口错误:', error.response.status, error.response.data);
        } else if (error.request) {
            console.error('请求路径错误,未收到响应:', error.request);
        } else {
            console.error('请求错误:', error.message);
        }
        return Promise.reject(error);
    }
);
window.onerror = function (message, source, lineno, colno, error) {
    console.error('浏览器兼容性错误:', message);
    console.error('发生错误的脚本:', source);
    console.error('发生错误的行号:', lineno);
    console.error('错误详情:', error);
    // 记录到 localStorage 或上报后端
    localStorage.setItem('compatibilityError', JSON.stringify({
        message,
        source,
        lineno,
        colno,
        error
    }));
    return true; // 防止浏览器默认错误提示
};
app.mount('#app');

App.js文件:

<template>
  <div id="app">
    <button @click="throwError">抛出组件内错误</button>
  </div>
</template>

<script>
export default {
  methods: {
    throwError() {
      // 模拟一个组件内部的错误
      throw new Error('这是组件内的错误');
    }
  },
  // errorCaptured(err, vm, info) {
  //   console.error('捕获到组件错误:', err.message);
  //   console.error('组件信息:', vm.$options.name);
  //   console.error('错误信息:', info);
  //   // 记录到 localStorage 或上报后端
  //   localStorage.setItem('componentError', JSON.stringify({
  //     message: err.message,
  //     stack: err.stack || '未知',
  //     component: vm.$options.name,
  //     info
  //   }));
  //   return false; // 阻止错误继续向上传播
  // }
}
</script>

效果

### 实现前端埋点的方法 #### 设计自定义前端数据埋点SDK 为了创建一个高效的前端数据埋点SDK,可以基于已有框架或库来构建。此过程涉及两个主要部分:初始化事件跟踪。 对于初始化阶段,在`AnalyticsSDK`对象内实现了`init`方法,该方法接收配置选项作为输入参数以设置全局变量或其他必要的环境准备操作[^2]: ```javascript const AnalyticsSDK = { init(config) { this.config = config; console.log('Initializing SDK with configuration:', config); }, }; ``` 当涉及到具体事件的记录时,则通过调用`trackEvent`函数完成。这个函数会获取到想要监测的具体动作(比如按钮点击),以及任何附加的信息一起发送给服务器端处理程序: ```javascript // 继续扩展上述的 AnalyticsSDK 对象 AnalyticsSDK.trackEvent = (eventName, eventData) => { const dataToReport = Object.assign({event: eventName}, eventData); // 合并基础信息与额外数据 fetch('/api/log-event', { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify(dataToReport), }).then(response => response.json()) .catch(error => console.error('Error reporting event:', error)); }; // 使用示例 document.getElementById('myButton').addEventListener('click', () => { AnalyticsSDK.trackEvent('button_click', {value: 'some_value'}); }); ``` #### 收集特定交互的数据 针对具体的用户互动行为,如页面上的点击事件,可以通过监听DOM元素的变化来进行捕捉,并在此基础上执行相应的逻辑。下面的例子展示了如何捕获一次点击并将相关信息传递给之前提到过的`trackEvent`接口[^4]: ```javascript function clickHandler(event) { let params = { event: 'click', targetId: event.target.id, timestamp: new Date().toISOString(), pageUrl: window.location.href }; AnalyticsSDK.trackEvent(params.event, params); } ``` 以上代码片段说明了怎样利用JavaScript原生特性结合自定义开发的SDK实现基本的功能需求——即每当发生指定类型的用户行动时自动触发日志提交流程。 #### 应用场景 前端埋点技术广泛应用于多个领域,包括但不限于推荐算法优化、用户体验改进研究等方面。它能够帮助开发者深入了解用户的浏览习惯及其偏好模式,从而指导后续的产品迭代方向[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值