Recommandations d'apprentissage associées : Tutoriel vidéo javascript
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
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 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)
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 :
代码埋点 | 可视化埋点 | 无痕埋点 | |
---|---|---|---|
典型场景 | 无痕埋点无法覆盖到,比如需要业务数据 | 简单规范的页面场景 | 简单规范的页面场景, |
优势 | 业务数据明确 | 开发成本低,运营人员可直接进行相关埋点配置 | 无需配置,数据可回溯 |
不足 | 数据不可回溯,开发成本高 | 不能关联业务数据,数据不可回溯 | 数据量较大,不能关联业务数据 |
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. )
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 PERFORMANCE
OPERATION
EVENT_NAME
Selon les dimensions ci-dessus, nous pouvons simplement concevoir l'architecture suivante
Basée sur l'architecture du image ci-dessus, nous pouvons ensuite développer le code spécifique suivantDemande de proxyIl existe actuellement deux méthodes de requête principales dans le navigateur, l'une est
et l'autre est XMLHttpRequest
. Fetch
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; }复制代码
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 }) }复制代码
PV
UV
, 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
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 } //记录埋点}复制代码
, 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
CORS
<srcipt src="another domain/main.js" cossorigin="anonymous"></script>
Access-Control-Allow-Origin: * | 指定域名
<script scr="crgt.js"></script> //加载crgt脚本,window.crgt = {getUser: () => string} try{ window.crgt.getUser(); }catch(error) { throw error // 输出正确的错误堆栈 }复制代码
try catch
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('error', (event) => { if (event.target instanceof HTMLElement) { const target = parseDom(event.target, ['src']); const detail = { target: target, path: parseXPath(target), } // 记录埋点 } }, true)复制代码
通过 addEventListener click
监听 click
事件
window.addEventListener('click', (event) => { //记录埋点}, true)复制代码
在这里通过组件的 displaName
来定位元素的位置,displaName
表示组件的文件目录,比如 src/components/Form.js
文件导出的组件 FormItem
通过 babel plugin
自动添加属性 @components/Form.FormItem
,或者使用者主动给组件添加 static
属性 displayName
。
window.addEventListener('hashchange', 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('beforeunload', (event) => { //记录埋点})复制代码
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('click', 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, 'AJAX_ERROR', true)export const ajaxSuccess$ = fromEvent(window, 'AJAX_SUCCESS', true)export const ajaxTimeout$ = fromEvent(window, 'AJAX_TIMEOUT', true)复制代码
ajaxError$.pipe( merge(ajaxSuccess$, ajaxTimeout$), map(data=> (data) => ({category: 'ajax', data; data})) subscribe(data => console.log(data))复制代码
通过 merge
, map
两个操作符完成对数据的合并和处理。
core
event$
数据流合并snapshot
获取当前设备快照,例如url
,userID
,router
track
埋点类,组合数据流和日志。logger
logger
日志类info
warn
debug
error
observable
ajax
beforeUpload
opeartion
routerChange
logger
track
自建埋点系统是一个需要前后端一起合作的事情,如果人力不足的情况下,建议使用第三方分析插件,例如 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!