Эта статья была написана членом командыСяо ФанЕму разрешено исключительное использование Tuya Front-end, включая, помимо прочего, редактирование, пометку оригинальности и другие права.
Зачем вам нужна система захороненных точек?
в кино
Фронтенд-разработка siege lion счастливое кодирование, очень горжусь тем, что занимаюсь разработкой разделения бизнеса и пользовательского интерфейса, различные шаблоны проектирования, оптимизация алгоритмов по очереди, код написан идеально (код трудового капитала - первый в мире), без ошибок , программа идеальна, Совместимость №1, код может драться и сопротивляться высокому качеству. Легко зарегистрируйтесь после работы и идите домой, чтобы присмотреть за ребенком.
в реальности
На самом деле среда разработки — это не то же самое, что производственная среда, и каким бы совершенным ни был процесс тестирования, все равно будут пропущенные тесты. С учетом использования пользователемКлиентская среда, сетевая средаСуществует ряд неопределенных факторов.
Так что в процессе разработки надо помнить три принципа (я вру)
- Не бывает идеального кода, есть не обнаруженные ошибки
- Никогда не верьте тестовой среде, ни одна тестовая среда не охватывает все онлайн-ситуации
- Если нет отзывов в сети, не сомневайтесь, проблема должна быть спрятана глубоко-глубоко
Что такое система скрытых точек
Скрытая точка похожа на камеру в городе: с точки зрения продукта она может отслеживать поведение пользователей в наших продуктах, обеспечивая основу для итерации продукта и стабильности проекта.КТО, КОГДА, ГДЕ, КАК, ЧТО являются основными аспектами сбора данных.
Для интерфейсной разработки он может отслеживать производительность загрузки ресурсов страницы, исключения и т. д., предоставлять индикаторы работоспособности и работоспособности страницы, обеспечивать основу для последующей оптимизации производительности и своевременно сообщать об исключениях и сценариях возникновения. Таким образом, проблемы могут быть своевременно исправлены, а качество проекта может быть улучшено.
Могилы можно условно разделить на три категории:
- Нет следов похороненных- Без разбора собирать всю информацию о странице, включая вход и выход на страницу, клики по событиям и т. д., для получения полезной информации требуется сброс данных.
- Визуализируйте закопанные точки- Получите определенные баллы в соответствии с созданной структурой страницы и проанализируйте баллы отдельно
- Вручную похороните бизнес-код- В соответствии с конкретным и сложным бизнесом удалите два вышеуказанных места, которые не могут быть покрыты, и похороните бизнес-код.
| код похоронен | Визуализируйте закопанные точки | Нет следов похороненных | |
|---|---|---|---|
| Типичная сцена | Бесследные закопанные точки не могут быть покрыты, например, требуются бизнес-данные | Простая и каноничная сцена страницы | Простая и стандартизированная сцена страницы, |
| Преимущество | Очистить бизнес-данные | Стоимость разработки низкая, и операторы могут напрямую настраивать соответствующие закопанные точки. | Настройка не требуется, данные можно отследить |
| недостаточный | Данные невозможно отследить, а стоимость разработки высока. | Бизнес-данные не могут быть связаны, и данные нельзя отследить | Количество данных велико и не может быть связано с бизнес-данными |
В большинстве случаев мы можем собрать все информационные данные через скрытую точку без следов, а затем сотрудничать с визуальной скрытой точкой, чтобы найти определенную точку, чтобы можно было соответствующим образом проанализировать большую часть информации о скрытой точке.
В особых случаях вы можете добавить больше бизнес-кодов, чтобы вручную закопать точки, чтобы иметь дело с особыми сценариями (в большинстве случаев сильный бизнес связан с обычными кликами, а события обновления не имеют ничего общего с информацией, о которой необходимо сообщать).
Скрытая разработка SDK
Сбор и анализ данных о захороненных точках
- Основные данные события
- время события
- Моментальный снимок информации о странице, как это происходит
- страница
- Страница ПВ, УФ
- Время пребывания на странице пользователя
- событие перехода на страницу
- Страница уходит в фон
- Пользователь покидает страницу
- Информация о пользователе
- пользовательский идентификатор
- Отпечаток пользовательского устройства
- Информация об устройстве
- ip
- позиция
- Поведение пользователя при работе
- пользовательские клики
- нажмите цель
- пользовательские клики
- AJAX-запрос страницы
- запрос выполнен
- Запрос не выполнен
- Истекло время запроса
- ошибка страницы
- Ошибка загрузки ресурса
- Ошибка запуска JS
- Ресурс загружает новую производительность
- картина
- сценарий
- скорость загрузки страницы
Указанные выше данные передаются через3 измерениядля определения скрытых событий
- ·
LEVEL: описывает уровень журнала скрытых данных.-
INFO: некоторые пользовательские операции, успешный запрос, загрузка ресурсов и т. д. нормальные записи данных -
ERROR: ошибка JS, ошибка интерфейса и т. д. записи данных типа ошибки -
DEBUG: зарезервировано разработчиками для возврата записей данных для устранения ошибок путем ручного вызова -
WARN: зарезервировано для разработчиков, чтобы возвращать записи данных об аномальном поведении пользователей путем ручного вызова
-
-
CATEGORY: Опишите классификацию данных скрытых точек.-
TRACK: Жизненный цикл встроенного объекта SDK управляет всеми встроенными данными.-
WILL_MOUNT: объект sdk должен быть инициализирован и загружен, генерируется идентификатор по умолчанию, и все связанные события отслеживаются. -
DID_MOUNTED: Инициализация объекта sdk завершена, и асинхронные операции, такие как получение отпечатков пальцев устройства, завершены.
-
-
AJAX: данные, связанные с AJAX -
ERROR: данные, связанные с исключением, на странице. -
PERFORMANCE: данные о производительности -
OPERATION: Данные, связанные с операциями пользователя.
-
-
EVENT_NAME: конкретное название события
В соответствии с указанными выше размерами мы можем просто спроектировать следующую архитектуру
В соответствии с архитектурой на приведенном выше рисунке выполняется следующая конкретная разработка кода.
прокси-запрос
В браузере в основном есть 2 метода запроса, один из нихXMLHttpRequest, одинFetch.
Прокси 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;
}
Прокси-выборка
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
При входе на страницу мы алгоритмически генерируем уникальныйsession id, в качестве глобального идентификатора этого скрытого поведения, сообщите идентификатор пользователя, отпечаток пальца устройства и информацию об устройстве. Рассчитывается по отпечатку пальца устройства, когда пользователь не вошел в системуUV,пройти черезsession idрассчитатьPV.
ловушка исключения
Исключением является необычный инцидент, который мешает нормальному ходу программы.
RUNTIME ERROR
существуетJSсквозьwindow.onerrorа такжеwindow.addEventListener('error', callback)Перехват исключений во время выполнения, обычно используется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
}
//记录埋点
}
Script Error
Здесь мы фильтруемScript Error, это в основном вызвано ошибкой стороннего междоменного скрипта, загруженного на страницу, например, размещенного на сторонней CDN.jsсценарий. Такие проблемы сложнее устранить. Решения:
- Открыть
CORS(Совместное использование ресурсов между источниками, совместное использование ресурсов между доменами), следующие шаги<srcipt src="another domain/main.js" cossorigin="anonymous"></script>- Исправлять
Access-Control-Allow-Origin: * | 指定域名
- использовать
try catch<script scr="crgt.js"></script> //加载crgt脚本,window.crgt = {getUser: () => string} try{ window.crgt.getUser(); }catch(error) { throw error // 输出正确的错误堆栈 }
Promise reject
jsНе удалось передать асинхронное исключениеonerrorЗахват метода, когда объект Promise отклоняется и не обрабатывается одновременно
бросит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.
Изменения маршрутизации страницы
- hashRouter
Мониторинг изменений хэша страницы и анализ хэша
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) => {
//记录埋点
})
Архитектура 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('click', emit)
})
Однако, имея дело сajax, необходимо объединить несколько данных вместе, необходимо выполнить операцию слияния, это не так элегантно, и его трудно адаптировать к работе последующего сложного потока данных.
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класс журналаinfowarndebugerror
-
-
observableajaxbeforeUploadopeartionrouterChangeloggertrack
Ссылаться на
конец
Самостоятельно построенная система скрытых точек — это вопрос, который требует сотрудничества между интерфейсом и сервером.Если рабочей силы недостаточно, рекомендуется использовать сторонние аналитические плагины, такие какSentryдостаточно для большинства повседневного использования
Тем не менее, все же рекомендуется узнать больше, и когда сторонние плагины не могут удовлетворить потребности бизнеса, вы можете использовать их.