Maison  >  Article  >  interface Web  >  Une exploration préliminaire du système de points enterrés

Une exploration préliminaire du système de points enterrés

coldplay.xixi
coldplay.xixiavant
2020-09-15 16:24:552539parcourir

Une exploration préliminaire du système de points enterrés

Recommandations d'apprentissage associées : Tutoriel vidéo javascript

Avant-propos

Il existe de nombreux éléments divers choses ces derniers temps, c'est rare de prendre le temps de rattraper les séries précédentes, et la série qui vous doit des points commence maintenant à décoller

Pourquoi le système de points est-il nécessaire

Dans le film

Le développement front-end siège Shi Kai code joyeusement et est très fier du développement séparé de l'entreprise et de l'interface utilisateur. Divers modèles de conception et optimisations d'algorithmes ont été implémentés tour à tour. Le code est parfait (le meilleur). code du travail dans le monde), il n'y a pas de BUG, ​​le programme est parfait et la compatibilité est n°1. Le code peut être tapé et résistant avec une haute qualité. Vous pouvez facilement pointer après avoir quitté le travail et rentrer chez vous pour prendre soin de votre bébé.

En réalité

En fait, l'environnement de développement et l'environnement de production ne sont pas les mêmes, et quelle que soit la perfection du processus de test, il y aura toujours des tests manqués. Considérant qu'il existe une série de facteurs incertains tels que l' environnement client de l'utilisateur, l'environnement réseau et ainsi de suite.

Donc pendant le processus de développement, vous devez vous rappeler les trois grands principes (J'ai inventé ça)

  1. Il n'y a pas de code parfait, seulement BUG non découverts
  2. Ne faites jamais confiance à l'environnement de test, aucun environnement de test ne couvre toutes les situations en ligne
  3. S'il n'y a pas de retour en ligne, n'en doutez pas, le le problème doit être caché très profondément, très profondément

Qu'est-ce qu'un système de points enterrés ?

Les points enterrés sont comme des caméras dans la ville, du point de vue du produit, il peut surveiller celui de l'utilisateur. mouvements dans nos produits Les trajectoires comportementales qu'il contient fournissent une base pour l'itération du produit et la stabilité du projet QUI, QUAND, OÙ, COMMENT et QUOI sont les dimensions de base pour la collecte de données .

Pour le développement front-end, il peut surveiller les performances de chargement des ressources de page, les exceptions, etc., fournir une expérience de page et un index de santé, fournir une base pour une optimisation ultérieure des performances et signaler les exceptions et les scénarios d'occurrence en temps opportun. Cela permet une correction rapide des problèmes et une amélioration de la qualité du projet.

Les points enterrés peuvent être grossièrement divisés en trois catégories :

  1. Points enterrés invisibles - Toutes les informations sur la page sont collectées sans discernement, y compris l'entrée et la sortie de la page, clics d'événement, etc. Un vidage des données est nécessaire pour obtenir des informations utiles
  2. Points cachés visuels - Obtenez des points spécifiques en fonction de la structure de la page générée et analysez les points cachés séparément
  3. Enfouissement manuel du code d'entreprise - Selon l'entreprise complexe spécifique, supprimez les deux zones ci-dessus qui ne peuvent pas être couvertes et enterrez le code d'entreprise

代码埋点 可视化埋点 无痕埋点
典型场景 无痕埋点无法覆盖到,比如需要业务数据 简单规范的页面场景 简单规范的页面场景,
优势 业务数据明确 开发成本低,运营人员可直接进行相关埋点配置 无需配置,数据可回溯
不足 数据不可回溯,开发成本高 不能关联业务数据,数据不可回溯 数据量较大,不能关联业务数据

Dans la plupart des cas, nous pouvons collecter toutes les données d'information via des points enterrés sans trace, puis coopérer avec les points enterrés visuels pour localiser spécifiquement un certain point, afin que la plupart des informations sur les points enterrés puissent être analysées en conséquence.

Dans des circonstances particulières, vous pouvez ajouter davantage de codes d'entreprise pour enterrer manuellement les points afin de gérer des scénarios spéciaux (dans la plupart des cas, une activité solide n'a rien à voir avec des clics normaux et des événements d'actualisation, ni avec les informations qui doivent être signalées. )

Développement du SDK pour les points enterrés

Collecte et analyse de données sur les points enterrés

  • Données d'événement de base
    • Heure d'occurrence de l'événement
    • Instantané des informations de la page lorsqu'elles se produisent
  • Page
    • Page PV, UV
    • Durée de séjour de la page utilisateur
    • Événement de saut de page
    • La page entre en arrière-plan
    • L'utilisateur quitte la page
  • Informations utilisateur
    • UId utilisateur
    • Appareil utilisateur empreinte digitale
    • Informations sur l'appareil
    • ip
    • Positionnement
  • Comportement de fonctionnement de l'utilisateur
    • Clic de l'utilisateur
      • Cible de clic
  • Requête AJAX de page
    • Demande réussie
    • Échec de la demande
    • Délai d'expiration de la demande
  • Erreur de page
    • Erreur de chargement des ressources
    • Erreur d'exécution JS
  • Performances de chargement des nouvelles ressources
  • Image
  • Script
  • Performances de chargement des pages

Les données ci-dessus définissent les événements enfouis à travers 3 dimensions

  • ·LEVEL : Décrivez le niveau de journalisation des données enfouies
    • INFO : certaines opérations utilisateur, requêtes réussies, chargement des ressources, etc. enregistrements de données normaux
    • ERROR : Erreurs JS, erreurs d'interface, etc. Enregistrements de données de type
    • DEBUG : réservés aux développeurs pour renvoyer des enregistrements de données pour résoudre les bogues via des appels manuels
    • WARN : réservés aux développeurs. retour via des appels manuels Transmission des enregistrements de données de comportement anormal des utilisateurs
  • CATEGORY : décrivant la classification des données enterrées
    • TRACK : gestion de l'ensemble du cycle de vie des données enterrées Objets SDK Données enterrées.
      • WILL_MOUNT : L'objet SDK est sur le point d'être initialisé et chargé, un ID par défaut est généré et tous les événements associés sont suivis
      • DID_MOUNTED : L'objet SDK est initialisé et les opérations asynchrones telles que l'obtention des empreintes digitales de l'appareil sont terminées
    • AJAX : données liées à AJAX
    • ERROR : données liées aux exceptions dans la page
    •  : À propos des données liées aux performancesPERFORMANCE
    •  : Données liées au fonctionnement de l'utilisateurOPERATION
  •  : Nom de l'événement spécifiqueEVENT_NAME

Selon les dimensions ci-dessus, nous pouvons simplement concevoir l'architecture suivante

Une exploration préliminaire du système de points enterrés
Basée sur l'architecture du image ci-dessus, nous pouvons ensuite développer le code spécifique suivant

Demande de proxy

Il existe actuellement deux méthodes de requête principales dans le navigateur, l'une est

et l'autre est XMLHttpRequest. Fetch

Proxy XMLHttpRequest

function NewXHR() {  var realXHR: any = new OldXHR(); // 代理模式里面有提到过
  realXHR.id = guid()  const oldSend = realXHR.send;

  realXHR.send = function (body) {
    oldSend.call(this, body)    //记录埋点
  }
  realXHR.addEventListener('load', function () {    //记录埋点
  }, false);
  realXHR.addEventListener('abort', function () {    //记录埋点
  }, false);

  realXHR.addEventListener('error', function () {    //记录埋点
  }, false);
  realXHR.addEventListener('timeout', function () {    //记录埋点
  }, false);  return realXHR;
}复制代码

Proxy Fetch

 const oldFetch = window.fetch;  function newFetch(url, init) {    const fetchObj = {      url: url,      method: method,      body: body,
    }
    ajaxEventTrigger.call(fetchObj, AJAX_START);    return oldFetch.apply(this, arguments).then(function (response) {      if (response.ok) {       //记录埋点
      } else {       //上报错误
      }      return response
    }).catch(function (error) {
      fetchObj.error = error        //记录埋点      
        throw error
    })
  }复制代码

Écoutez le

de la page, PVUV

En entrant dans la page, nous générons a via un algorithme unique

, en tant qu'identifiant global de ce comportement de suivi, signale l'identifiant de l'utilisateur, l'empreinte digitale de l'appareil et les informations sur l'appareil. Lorsque l'utilisateur n'est pas connecté, session id est calculé à partir de l'empreinte digitale de l'appareil et UV est calculé à partir de session id. PV

Capture d'exception

L'exception est un accident inhabituel qui interfère avec le déroulement normal du programme

ERREUR D'EXÉCUTION

Dans

vous pouvez passer JS et window.onerror Pour capturer les exceptions d'exécution, utilisez généralement window.addEventListener('error', callback), qui a une meilleure compatibilité. window.onerror

window.onerror = function(message, url, lineno, columnNo, error) {    const lowCashMessage = message.toLowerCase()    if(lowCashMessage.indexOf('script error') > -1) {      return
    }    const detail = {      url: url    
      filename: filename,      columnNo: columnNo,      lineno: lineno,      stack: error.stack,      message: message
    }    //记录埋点}复制代码

Erreur de script

Ici, nous avons filtré

, qui est principalement causé par des erreurs signalées par des scripts inter-domaines tiers chargés dans la page, tels que Script Error hébergé dans un CDN tiers 🎜> Script. Ce type de problème est plus difficile à résoudre. La solution est : js

    Ouvrir
  • (Partage de ressources inter-origines, partage de ressources inter-domaines), suivez les étapes ci-dessousCORS
    • e865d189fa941bf5a886d94c3872d7a02cacc6d41bbb37262a98f745aa00fbf0
    • Modifier
    • Access-Control-Allow-Origin: * | 指定域名
  • Utilisez
  •   <script scr="crgt.js"></script> //加载crgt脚本,window.crgt = {getUser: () => string}
      try{      window.crgt.getUser();
      }catch(error) {      throw error // 输出正确的错误堆栈
      }复制代码
    try catch
Rejet de promesse

lorsqu'une exception asynchrone ne peut pas être capturée par le js méthode, Lorsque l'objet Promise est rejeté et n'est pas traité en même temps Une erreur de onerror sera générée et ne sera pas détectée par la méthode ci-dessus, un événement de gestion distinct doit donc être ajouté. unhandledrejection

window.addEventListener("unhandledrejection", event => {  throw event.reason
});复制代码

资源加载异常

在浏览器中,可以通过 window.addEventListener('error', callback) 的方式监听资源加载异常,比如 js 或者 css 脚本文件丢失。

window.addEventListener(&#39;error&#39;, (event) => {  if (event.target instanceof HTMLElement) {    const target = parseDom(event.target, [&#39;src&#39;]);    const detail = {      target: target,      path: parseXPath(target),
    }    //  记录埋点
  }
}, true)复制代码

监听用户行为

通过 addEventListener click 监听 click 事件

window.addEventListener(&#39;click&#39;, (event) => {    //记录埋点}, true)复制代码

在这里通过组件的 displaName 来定位元素的位置,displaName 表示组件的文件目录,比如 src/components/Form.js 文件导出的组件 FormItem 通过 babel plugin 自动添加属性 @components/Form.FormItem,或者使用者主动给组件添加 static 属性 displayName

页面路由变化

  • hashRouter 监听页面hash变化,对hash进行解析
window.addEventListener(&#39;hashchange&#39;, event => {  const { oldURL, newURL } = event;  const oldURLObj = url.parseUrl(oldURL);  const newURLObj = url.parseUrl(newURL);  const from = oldURLObj.hash && url.parseHash(oldURLObj.hash);  const to = newURLObj.hash && url.parseHash(newURLObj.hash);  if(!from && !to ) return;  // 记录埋点})复制代码

监听页面离开

通过 addEventListener beforeunload 监听离开页面事件

window.addEventListener(&#39;beforeunload&#39;, (event) => {    //记录埋点})复制代码

SDK 架构

class Observable {    constructor(observer) {
        observer(this.emit)
    }
    emit = (data) => {        this.listeners.forEach(listener => {
            listener(data)
        })
    }
    listeners = [];
    
    subscribe = (listener) => {        this.listeners.push(listeners);        return () => {            const index = this.listeners.indexOf(listener);            if(index === -1) {                return false
            }            
            this.listeners.splice(index, 1);            return true;
        }
     }
}复制代码
const clickObservable = new Observable((emit) => {    window.addEventListener(&#39;click&#39;, emit)
})复制代码

然而在处理 ajax,需要将多种数据组合在一起,需要进行 merg 操作,则显得没有那么优雅,也很难适应后续复杂的数据流的操作。

const ajaxErrorObservable = new Observable((emit) => {    window.addEventListener(AJAX_ERROR, emit)
})const ajaxSuccessObservable = new Observable((emit) => {    window.addEventListener(AJAX_SUCCESS, emit)
})const ajaxTimeoutObservable = new Observable((emit) => {    window.addEventListener(AJAX_TIMEOUT, emit)
})复制代码

可以选择 RxJS 来优化代码

export const ajaxError$ = fromEvent(window, &#39;AJAX_ERROR&#39;, true)export const ajaxSuccess$ = fromEvent(window, &#39;AJAX_SUCCESS&#39;, true)export const ajaxTimeout$ = fromEvent(window, &#39;AJAX_TIMEOUT&#39;, true)复制代码
ajaxError$.pipe(
    merge(ajaxSuccess$, ajaxTimeout$), 
    map(data=> (data) => ({category: &#39;ajax&#39;, data; data}))
    subscribe(data => console.log(data))复制代码

通过 merge, map 两个操作符完成对数据的合并和处理。

数据流

Une exploration préliminaire du système de points enterrés

项目结构

  • core
    • event$ 数据流合并
    • snapshot 获取当前设备快照,例如urluserIDrouter
    • track 埋点类,组合数据流和日志。
  • logger
    • logger 日志类
      • info
      • warn
      • debug
      • error
  • observable
    • ajax
    • beforeUpload
    • opeartion
    • routerChange
    • logger
    • track

参考

  • www.alibabacloud.com/help/zh/doc…

结尾

自建埋点系统是一个需要前后端一起合作的事情,如果人力不足的情况下,建议使用第三方分析插件,例如 Sentry 就能足够满足大部分日常使用

但还是建议多了解,在第三方插件出现不能满足业务需求的时候,可以顶上。

想了解更多编程学习,敬请关注php培训栏目!

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer