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éseauet 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 projetQUI, 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 à travers3 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 normauxERROR
: Erreurs JS, erreurs d'interface, etc. Enregistrements de données de typeDEBUG
: réservés aux développeurs pour renvoyer des enregistrements de données pour résoudre les bogues via des appels manuelsWARN
: réservés aux développeurs. retour via des appels manuels Transmission des enregistrements de données de comportement anormal des utilisateursCATEGORY
: 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 suivisDID_MOUNTED
: L'objet SDK est initialisé et les opérations asynchrones telles que l'obtention des empreintes digitales de l'appareil sont terminéesAJAX
: données liées à AJAXERROR
: données liées aux exceptions dans la pagePERFORMANCE
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 proxy Il existe actuellement deux méthodes de requête principales dans le navigateur, l'une est
et l'autre estXMLHttpRequest
.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 etUV
est calculé à partir desession id
.PV
vous pouvez passerJS
etwindow.onerror
Pour capturer les exceptions d'exécution, utilisez généralementwindow.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 queScript Error
hébergé dans un CDN tiers > Script. Ce type de problème est plus difficile à résoudre. La solution est :js
CORS
Access-Control-Allow-Origin: * | 指定域名
//加载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 lejs
méthode, Lorsque l'objet Promise est rejeté et n'est pas traité en même temps Une erreur deonerror
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!