fg-tracker-browser 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +13 -0
- package/README.md +48 -16
- package/dist/index.d.ts +5 -3
- package/dist/index.js +374 -67
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +67 -6
- package/dist/vitals.d.ts +57 -0
- package/dist/vitals.js +537 -0
- package/dist/vitals.js.map +1 -0
- package/package.json +5 -3
package/dist/vitals.js
ADDED
|
@@ -0,0 +1,537 @@
|
|
|
1
|
+
import { randomId, screenBucket } from './analytics.js';
|
|
2
|
+
/**
|
|
3
|
+
* Web Vitals por view (CONTRATO.md §24.1): LCP, FCP e TTFB da carga do documento; CLS e INP de cada
|
|
4
|
+
* view (carga do documento, navegação SPA ou volta do bfcache). Opt-in (`webVitals`), sem cookie e
|
|
5
|
+
* sem dado pessoal: a view é um id aleatório da página, a rota passa por `sanitizePath`.
|
|
6
|
+
*
|
|
7
|
+
* Semântica (a mesma do web-vitals/CrUX, com as diferenças documentadas no contrato):
|
|
8
|
+
* - LCP/FCP só contam o que aconteceu antes de a página ficar oculta pela primeira vez (aba aberta
|
|
9
|
+
* em segundo plano não tem LCP); o LCP fecha no primeiro input (tecla, ponteiro) ou ao ocultar, e
|
|
10
|
+
* uma navegação SPA nunca produz LCP: o conteúdo da rota nova não é a carga do documento.
|
|
11
|
+
* - CLS = maior janela de sessão (shifts com < 1 s entre si, janela ≤ 5 s), sem shift logo após input.
|
|
12
|
+
* - INP = interação mais lenta (p98 aproximado: a cada 50 interações, descarta a pior), só com interação;
|
|
13
|
+
* interações contadas pelos `interactionId` das entradas de ≥ 16 ms (e a primeira, de qualquer duração).
|
|
14
|
+
* - Entradas de performance pertencem à view pelo `startTime`, não pela hora em que chegam: o clique
|
|
15
|
+
* que dispara a navegação SPA é da view anterior.
|
|
16
|
+
* Cada relatório é um retrato completo da view com `seq` crescente; a API guarda o de maior `seq`.
|
|
17
|
+
*/
|
|
18
|
+
/** Limiares (bom ≤ primeiro, ruim > segundo) do web.dev, os mesmos do painel. */
|
|
19
|
+
export const WEB_VITALS_THRESHOLDS = {
|
|
20
|
+
lcp: [2500, 4000],
|
|
21
|
+
inp: [200, 500],
|
|
22
|
+
cls: [0.1, 0.25],
|
|
23
|
+
fcp: [1800, 3000],
|
|
24
|
+
ttfb: [800, 1800],
|
|
25
|
+
};
|
|
26
|
+
/** Views por documento (navegações SPA além disso não são medidas). */
|
|
27
|
+
export const MAX_VIEWS_PER_DOCUMENT = 100;
|
|
28
|
+
/** Relatórios por view (cada um só sai quando algum valor mudou). */
|
|
29
|
+
export const MAX_REPORTS_PER_VIEW = 20;
|
|
30
|
+
/** Espera depois de uma navegação SPA para as entradas atrasadas da view anterior chegarem. */
|
|
31
|
+
export const SOFT_VIEW_GRACE_MS = 1000;
|
|
32
|
+
/** Limiar do observer de `event` (o mínimo da API): conta as interações de cada view pelos ids. */
|
|
33
|
+
const INP_DURATION_THRESHOLD_MS = 16;
|
|
34
|
+
/** Ids de interação guardados por view para não contar duas vezes (acima disso só soma). */
|
|
35
|
+
const MAX_TRACKED_INTERACTION_IDS = 5000;
|
|
36
|
+
const MAX_LONGEST_INTERACTIONS = 10;
|
|
37
|
+
const CLS_SESSION_GAP_MS = 1000;
|
|
38
|
+
const CLS_SESSION_MAX_MS = 5000;
|
|
39
|
+
const round1 = (value) => Math.round(value * 10) / 10;
|
|
40
|
+
const round4 = (value) => Math.round(value * 10000) / 10000;
|
|
41
|
+
const tagOf = (element) => {
|
|
42
|
+
const tag = element && typeof element.tagName === 'string' ? element.tagName.toLowerCase() : '';
|
|
43
|
+
return /^[a-z][a-z0-9-]{0,31}$/.test(tag) ? tag : undefined;
|
|
44
|
+
};
|
|
45
|
+
const NAVIGATION_TYPES = new Set(['navigate', 'reload', 'back_forward', 'prerender']);
|
|
46
|
+
const CONNECTIONS = new Set(['slow-2g', '2g', '3g', '4g']);
|
|
47
|
+
/** Mede os Web Vitals da página; `null` quando o navegador não tem as APIs ou a carga não foi sorteada. */
|
|
48
|
+
export function createWebVitals(env, options) {
|
|
49
|
+
const win = env.window;
|
|
50
|
+
const perf = win?.performance;
|
|
51
|
+
const Observer = win?.PerformanceObserver;
|
|
52
|
+
const supported = Observer?.supportedEntryTypes ?? [];
|
|
53
|
+
if (!win || !perf || !Observer || typeof perf.now !== 'function')
|
|
54
|
+
return null;
|
|
55
|
+
if (!['largest-contentful-paint', 'layout-shift', 'event'].some((type) => supported.includes(type)))
|
|
56
|
+
return null;
|
|
57
|
+
const sampleRate = Math.min(1, Math.max(0, options.sampleRate));
|
|
58
|
+
if (sampleRate <= 0 || (sampleRate < 1 && Math.random() >= sampleRate))
|
|
59
|
+
return null;
|
|
60
|
+
const doc = env.document ?? win.document;
|
|
61
|
+
const loc = env.location ?? win.location;
|
|
62
|
+
const nav = (env.navigator ?? win.navigator);
|
|
63
|
+
const timeOrigin = typeof perf.timeOrigin === 'number' ? perf.timeOrigin : Date.now() - perf.now();
|
|
64
|
+
const isPrerendering = () => doc?.prerendering === true;
|
|
65
|
+
const prerendering = isPrerendering();
|
|
66
|
+
const navigation = (perf.getEntriesByType?.('navigation')?.[0] ?? undefined);
|
|
67
|
+
/**
|
|
68
|
+
* Início da ativação do prerender, lido na hora: com o SDK iniciado durante o prerender ele ainda
|
|
69
|
+
* vale 0 e só ganha o valor final na ativação (o Navigation Timing é o mesmo objeto).
|
|
70
|
+
*/
|
|
71
|
+
const activationStart = () => Math.max(0, navigation?.activationStart ?? 0);
|
|
72
|
+
const clsSupported = supported.includes('layout-shift');
|
|
73
|
+
const interactionsSupported = supported.includes('event') || supported.includes('first-input');
|
|
74
|
+
/**
|
|
75
|
+
* Ocultação vista pelo evento. Com o histórico `visibility-state` (o Chrome guarda o estado inicial
|
|
76
|
+
* em 0 e cada troca), ele diz quando a página ficou oculta, mesmo com o SDK iniciado depois: uma
|
|
77
|
+
* carga visível que o usuário ocultou antes do init não vira "aberta em segundo plano". Sem
|
|
78
|
+
* histórico, a página oculta no init conta como oculta desde o início (o prerender não conta).
|
|
79
|
+
*/
|
|
80
|
+
const hasVisibilityHistory = supported.includes('visibility-state') && (perf.getEntriesByType?.('visibility-state')?.length ?? 0) > 0;
|
|
81
|
+
let hiddenByEvent = !hasVisibilityHistory && doc?.visibilityState === 'hidden' && !prerendering ? 0 : Infinity;
|
|
82
|
+
/**
|
|
83
|
+
* Primeira vez em que a página ficou oculta para o usuário. LCP/FCP depois disso não contam. As
|
|
84
|
+
* entradas `visibility-state` cobrem o SDK iniciado tarde; a ocultação antes da ativação de um
|
|
85
|
+
* prerender (e o prerender em curso) não é do usuário e fica de fora.
|
|
86
|
+
*/
|
|
87
|
+
const firstHidden = () => {
|
|
88
|
+
if (isPrerendering())
|
|
89
|
+
return Infinity;
|
|
90
|
+
let first = hiddenByEvent;
|
|
91
|
+
if (supported.includes('visibility-state')) {
|
|
92
|
+
const activation = activationStart();
|
|
93
|
+
for (const entry of perf.getEntriesByType?.('visibility-state') ?? []) {
|
|
94
|
+
if (entry.name === 'hidden' && entry.startTime >= activation)
|
|
95
|
+
first = Math.min(first, entry.startTime);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return first;
|
|
99
|
+
};
|
|
100
|
+
const views = [];
|
|
101
|
+
let viewCount = 0;
|
|
102
|
+
const pathOf = (raw) => (raw ?? '/').split('#')[0].split('?')[0] || '/';
|
|
103
|
+
const sanitize = (pathname) => {
|
|
104
|
+
try {
|
|
105
|
+
const route = options.sanitizePath(pathname);
|
|
106
|
+
return typeof route === 'string' && route.startsWith('/') ? route.slice(0, 512) : null;
|
|
107
|
+
}
|
|
108
|
+
catch {
|
|
109
|
+
return null;
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
const openView = (navigationType, pathname, startTime) => {
|
|
113
|
+
const previous = views[views.length - 1];
|
|
114
|
+
if (previous && previous.endTime === Infinity) {
|
|
115
|
+
previous.endTime = startTime;
|
|
116
|
+
previous.closeAt = Date.now() + SOFT_VIEW_GRACE_MS;
|
|
117
|
+
}
|
|
118
|
+
if (viewCount >= MAX_VIEWS_PER_DOCUMENT)
|
|
119
|
+
return null;
|
|
120
|
+
viewCount += 1;
|
|
121
|
+
const view = {
|
|
122
|
+
id: randomId(env),
|
|
123
|
+
navigationType,
|
|
124
|
+
pathname,
|
|
125
|
+
route: sanitize(pathname),
|
|
126
|
+
startTime,
|
|
127
|
+
startedAt: new Date(timeOrigin + startTime).toISOString(),
|
|
128
|
+
endTime: Infinity,
|
|
129
|
+
closeAt: Infinity,
|
|
130
|
+
seq: 0,
|
|
131
|
+
lastSignature: '',
|
|
132
|
+
done: false,
|
|
133
|
+
painted: false,
|
|
134
|
+
lcpCutoff: navigationType === 'soft' || navigationType === 'restore' ? 0 : Infinity,
|
|
135
|
+
cls: 0,
|
|
136
|
+
sessionValue: 0,
|
|
137
|
+
sessionFirst: 0,
|
|
138
|
+
sessionLast: 0,
|
|
139
|
+
interactions: [],
|
|
140
|
+
interactionIds: new Set(),
|
|
141
|
+
interactionTotal: 0,
|
|
142
|
+
};
|
|
143
|
+
views.push(view);
|
|
144
|
+
return view;
|
|
145
|
+
};
|
|
146
|
+
// A carga do documento: rota da URL do documento (o SDK pode iniciar depois de uma navegação SPA).
|
|
147
|
+
let documentPath = pathOf(loc?.pathname);
|
|
148
|
+
try {
|
|
149
|
+
if (navigation?.name)
|
|
150
|
+
documentPath = pathOf(new URL(navigation.name).pathname);
|
|
151
|
+
}
|
|
152
|
+
catch {
|
|
153
|
+
/* fica o location */
|
|
154
|
+
}
|
|
155
|
+
const navType = prerendering || activationStart() > 0 ? 'prerender' : NAVIGATION_TYPES.has(navigation?.type ?? '') ? navigation.type : 'navigate';
|
|
156
|
+
const documentView = openView(navType, documentPath, 0);
|
|
157
|
+
/** Tempo desde o início da navegação (ou da ativação do prerender), lido no relatório. */
|
|
158
|
+
const sinceActivation = (time) => round1(Math.max(0, time - activationStart()));
|
|
159
|
+
/** TTFB do Navigation Timing, lido no relatório (resposta e ativação podem chegar depois do início). */
|
|
160
|
+
const ttfb = () => {
|
|
161
|
+
const responseStart = navigation?.responseStart;
|
|
162
|
+
return typeof responseStart === 'number' && Number.isFinite(responseStart) && responseStart > 0 ? sinceActivation(responseStart) : undefined;
|
|
163
|
+
};
|
|
164
|
+
if (options.softNavigations && pathOf(loc?.pathname) !== documentPath)
|
|
165
|
+
openView('soft', pathOf(loc?.pathname), perf.now());
|
|
166
|
+
/** View dona de uma entrada pelo instante em que ela aconteceu. */
|
|
167
|
+
const viewAt = (time) => {
|
|
168
|
+
for (let i = views.length - 1; i >= 0; i -= 1) {
|
|
169
|
+
const view = views[i];
|
|
170
|
+
if (time >= view.startTime)
|
|
171
|
+
return time < view.endTime && !view.done ? view : null;
|
|
172
|
+
}
|
|
173
|
+
return null;
|
|
174
|
+
};
|
|
175
|
+
/**
|
|
176
|
+
* Fecha o LCP no instante `at`. Candidatos pintados antes disso ainda valem quando chegam depois
|
|
177
|
+
* (o observer entrega de forma assíncrona); os pintados depois não.
|
|
178
|
+
*/
|
|
179
|
+
const finalizeLcp = (at) => {
|
|
180
|
+
documentView.lcpCutoff = Math.min(documentView.lcpCutoff, at);
|
|
181
|
+
};
|
|
182
|
+
/* ------------------------------------------------------------ observers */
|
|
183
|
+
const observers = [];
|
|
184
|
+
const observe = (type, handler, extra = {}) => {
|
|
185
|
+
if (!supported.includes(type))
|
|
186
|
+
return;
|
|
187
|
+
try {
|
|
188
|
+
const observer = new Observer((list) => {
|
|
189
|
+
try {
|
|
190
|
+
handler(list.getEntries());
|
|
191
|
+
}
|
|
192
|
+
catch (err) {
|
|
193
|
+
options.log?.('web vitals: entrada ignorada', err);
|
|
194
|
+
}
|
|
195
|
+
});
|
|
196
|
+
observer.observe({ type, buffered: true, ...extra });
|
|
197
|
+
observers.push({ observer, handler });
|
|
198
|
+
}
|
|
199
|
+
catch (err) {
|
|
200
|
+
options.log?.(`web vitals: ${type} indisponível`, err);
|
|
201
|
+
}
|
|
202
|
+
};
|
|
203
|
+
observe('paint', (entries) => {
|
|
204
|
+
for (const entry of entries) {
|
|
205
|
+
if (entry.name !== 'first-contentful-paint')
|
|
206
|
+
continue;
|
|
207
|
+
documentView.painted = true;
|
|
208
|
+
if (entry.startTime < firstHidden() && documentView.fcpStart === undefined)
|
|
209
|
+
documentView.fcpStart = entry.startTime;
|
|
210
|
+
}
|
|
211
|
+
});
|
|
212
|
+
observe('largest-contentful-paint', (entries) => {
|
|
213
|
+
for (const entry of entries) {
|
|
214
|
+
if (documentView.done)
|
|
215
|
+
return;
|
|
216
|
+
// Candidato depois do input, de ocultar ou da primeira navegação SPA não é o LCP do documento.
|
|
217
|
+
if (entry.startTime >= Math.min(documentView.lcpCutoff, firstHidden(), documentView.endTime))
|
|
218
|
+
continue;
|
|
219
|
+
documentView.lcpStart = entry.startTime;
|
|
220
|
+
documentView.lcpElement = tagOf(entry.element);
|
|
221
|
+
}
|
|
222
|
+
});
|
|
223
|
+
observe('layout-shift', (entries) => {
|
|
224
|
+
for (const entry of entries) {
|
|
225
|
+
if (entry.hadRecentInput || !(entry.value >= 0))
|
|
226
|
+
continue;
|
|
227
|
+
const view = viewAt(entry.startTime);
|
|
228
|
+
if (!view)
|
|
229
|
+
continue;
|
|
230
|
+
if (view.sessionValue > 0 && entry.startTime - view.sessionLast < CLS_SESSION_GAP_MS && entry.startTime - view.sessionFirst < CLS_SESSION_MAX_MS) {
|
|
231
|
+
view.sessionValue += entry.value;
|
|
232
|
+
}
|
|
233
|
+
else {
|
|
234
|
+
view.sessionValue = entry.value;
|
|
235
|
+
view.sessionFirst = entry.startTime;
|
|
236
|
+
}
|
|
237
|
+
view.sessionLast = entry.startTime;
|
|
238
|
+
view.cls = Math.max(view.cls, view.sessionValue);
|
|
239
|
+
}
|
|
240
|
+
});
|
|
241
|
+
/**
|
|
242
|
+
* Dono de cada interação (`interactionId`): a view em que a primeira entrada dela aconteceu. As
|
|
243
|
+
* entradas de uma interação (keydown e keyup, pointerdown/up/click) podem cair dos dois lados de
|
|
244
|
+
* uma navegação SPA; o grupo inteiro fica na view onde começou, com a duração da maior entrada.
|
|
245
|
+
* Quando a view fecha, o id sai daqui e vai para `retired`.
|
|
246
|
+
*/
|
|
247
|
+
const owners = new Map();
|
|
248
|
+
/**
|
|
249
|
+
* Interações de views já fechadas: as que a view levou ao fechar e as cuja primeira entrada só
|
|
250
|
+
* chegou depois do fechamento. Uma entrada posterior do grupo (o keyup de uma tecla segura além
|
|
251
|
+
* da carência, ou entregue tarde) é descartada, nunca vira interação da view nova. Memória
|
|
252
|
+
* limitada: as mais antigas saem primeiro.
|
|
253
|
+
*/
|
|
254
|
+
const retired = new Set();
|
|
255
|
+
const MAX_RETIRED = 1000;
|
|
256
|
+
const retire = (id) => {
|
|
257
|
+
if (retired.size >= MAX_RETIRED)
|
|
258
|
+
retired.delete(retired.values().next().value);
|
|
259
|
+
retired.add(id);
|
|
260
|
+
};
|
|
261
|
+
const putLongest = (view, item) => {
|
|
262
|
+
const index = view.interactions.findIndex((other) => other.id === item.id);
|
|
263
|
+
if (index >= 0)
|
|
264
|
+
view.interactions.splice(index, 1);
|
|
265
|
+
view.interactions.push({ ...item });
|
|
266
|
+
view.interactions.sort((a, b) => b.duration - a.duration);
|
|
267
|
+
if (view.interactions.length > MAX_LONGEST_INTERACTIONS)
|
|
268
|
+
view.interactions.length = MAX_LONGEST_INTERACTIONS;
|
|
269
|
+
};
|
|
270
|
+
const claim = (view, id) => {
|
|
271
|
+
if (view.interactionIds.size < MAX_TRACKED_INTERACTION_IDS)
|
|
272
|
+
view.interactionIds.add(id);
|
|
273
|
+
view.interactionTotal += 1;
|
|
274
|
+
};
|
|
275
|
+
const release = (view, id) => {
|
|
276
|
+
view.interactionIds.delete(id);
|
|
277
|
+
view.interactionTotal = Math.max(0, view.interactionTotal - 1);
|
|
278
|
+
const index = view.interactions.findIndex((other) => other.id === id);
|
|
279
|
+
if (index >= 0)
|
|
280
|
+
view.interactions.splice(index, 1);
|
|
281
|
+
};
|
|
282
|
+
const onEventEntries = (entries) => {
|
|
283
|
+
// Na ordem em que aconteceram: a primeira entrada de cada interação decide a view.
|
|
284
|
+
for (const entry of [...entries].sort((a, b) => a.startTime - b.startTime)) {
|
|
285
|
+
const id = entry.interactionId;
|
|
286
|
+
if (!id || retired.has(id))
|
|
287
|
+
continue;
|
|
288
|
+
const found = { id, duration: entry.duration, name: entry.name, target: tagOf(entry.target) ?? null };
|
|
289
|
+
let owner = owners.get(id);
|
|
290
|
+
if (owner) {
|
|
291
|
+
// Entrada anterior ao início conhecido (entregue depois): o grupo muda para a view dela.
|
|
292
|
+
const earlier = entry.startTime < owner.start ? viewAt(entry.startTime) : null;
|
|
293
|
+
if (earlier && earlier !== owner.view && !owner.view.done) {
|
|
294
|
+
release(owner.view, id);
|
|
295
|
+
claim(earlier, id);
|
|
296
|
+
owner.view = earlier;
|
|
297
|
+
}
|
|
298
|
+
owner.start = Math.min(owner.start, entry.startTime);
|
|
299
|
+
if (owner.view.done)
|
|
300
|
+
continue;
|
|
301
|
+
// O alvo pode vir nulo numa entrada (Event Timing permite) e não em outra da mesma interação:
|
|
302
|
+
// a maior duração decide o INP, e o alvo vem de qualquer entrada que o tenha.
|
|
303
|
+
if (found.duration > owner.longest.duration)
|
|
304
|
+
owner.longest = { ...found, target: found.target ?? owner.longest.target };
|
|
305
|
+
else if (!owner.longest.target && found.target)
|
|
306
|
+
owner.longest = { ...owner.longest, target: found.target };
|
|
307
|
+
}
|
|
308
|
+
else {
|
|
309
|
+
// Pelo `startTime`, não pela chegada: o `performance.interactionCount` só sobe depois da
|
|
310
|
+
// pintura, e o clique que dispara a navegação SPA cairia na view nova.
|
|
311
|
+
const view = viewAt(entry.startTime);
|
|
312
|
+
if (!view) {
|
|
313
|
+
retire(id);
|
|
314
|
+
continue;
|
|
315
|
+
}
|
|
316
|
+
owner = { view, start: entry.startTime, longest: found };
|
|
317
|
+
owners.set(id, owner);
|
|
318
|
+
claim(view, id);
|
|
319
|
+
}
|
|
320
|
+
putLongest(owner.view, owner.longest);
|
|
321
|
+
}
|
|
322
|
+
};
|
|
323
|
+
observe('event', onEventEntries, { durationThreshold: INP_DURATION_THRESHOLD_MS });
|
|
324
|
+
// A primeira interação entra mesmo abaixo do limiar do observer de `event`.
|
|
325
|
+
observe('first-input', onEventEntries);
|
|
326
|
+
// O LCP fecha no primeiro input do usuário (o navegador também para de emitir candidatos).
|
|
327
|
+
const inputEvents = ['keydown', 'pointerdown', 'click'];
|
|
328
|
+
const onInput = (event) => {
|
|
329
|
+
finalizeLcp(typeof event.timeStamp === 'number' && event.timeStamp > 0 ? event.timeStamp : perf.now());
|
|
330
|
+
for (const type of inputEvents)
|
|
331
|
+
win.removeEventListener(type, onInput, true);
|
|
332
|
+
};
|
|
333
|
+
for (const type of inputEvents)
|
|
334
|
+
win.addEventListener(type, onInput, { capture: true, once: true, passive: true });
|
|
335
|
+
/* ------------------------------------------------------------ relatório */
|
|
336
|
+
/** Lê o que os observers ainda não entregaram (o callback deles roda depois do evento de ocultar). */
|
|
337
|
+
const drain = () => {
|
|
338
|
+
for (const { observer, handler } of observers) {
|
|
339
|
+
try {
|
|
340
|
+
const records = observer.takeRecords?.() ?? [];
|
|
341
|
+
if (records.length > 0)
|
|
342
|
+
handler(records);
|
|
343
|
+
}
|
|
344
|
+
catch {
|
|
345
|
+
/* entrada ignorada */
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
};
|
|
349
|
+
const snapshot = (view) => {
|
|
350
|
+
if (!view.route)
|
|
351
|
+
return null;
|
|
352
|
+
const isDocument = view === documentView;
|
|
353
|
+
// Prerender descartado sem ativação: o usuário nunca viu a página.
|
|
354
|
+
if (isDocument && isPrerendering())
|
|
355
|
+
return null;
|
|
356
|
+
const event = {
|
|
357
|
+
type: 'web_vitals',
|
|
358
|
+
view_id: view.id,
|
|
359
|
+
seq: view.seq + 1,
|
|
360
|
+
navigation_type: view.navigationType,
|
|
361
|
+
route: view.route,
|
|
362
|
+
started_at: view.startedAt,
|
|
363
|
+
ts: new Date().toISOString(),
|
|
364
|
+
screen: screenBucket(win.screen?.width ?? win.innerWidth),
|
|
365
|
+
sample_rate: sampleRate,
|
|
366
|
+
};
|
|
367
|
+
if (isDocument) {
|
|
368
|
+
// Começou oculta: a primeira ocultação do usuário é o início (ou a ativação) da carga.
|
|
369
|
+
if (firstHidden() <= activationStart())
|
|
370
|
+
event.started_hidden = true;
|
|
371
|
+
const firstByte = ttfb();
|
|
372
|
+
if (firstByte !== undefined)
|
|
373
|
+
event.ttfb = firstByte;
|
|
374
|
+
if (view.fcpStart !== undefined)
|
|
375
|
+
event.fcp = sinceActivation(view.fcpStart);
|
|
376
|
+
if (view.lcpStart !== undefined && view.lcpCutoff !== Infinity) {
|
|
377
|
+
event.lcp = sinceActivation(view.lcpStart);
|
|
378
|
+
if (view.lcpElement)
|
|
379
|
+
event.lcp_element = view.lcpElement;
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
// CLS só com o observer de layout-shift (sem ele, 0 seria uma medida falsa) e, no documento,
|
|
383
|
+
// depois de alguma pintura; navegação SPA e bfcache sempre.
|
|
384
|
+
if (clsSupported && (!isDocument || view.painted))
|
|
385
|
+
event.cls = round4(view.cls);
|
|
386
|
+
const count = view.interactionTotal;
|
|
387
|
+
if (view.interactions.length > 0) {
|
|
388
|
+
const longest = view.interactions[Math.min(view.interactions.length - 1, Math.floor(count / 50))];
|
|
389
|
+
event.inp = round1(longest.duration);
|
|
390
|
+
event.inp_event = longest.name.slice(0, 32);
|
|
391
|
+
if (longest.target)
|
|
392
|
+
event.inp_target = longest.target;
|
|
393
|
+
}
|
|
394
|
+
if (interactionsSupported)
|
|
395
|
+
event.interactions = count;
|
|
396
|
+
const connection = nav?.connection?.effectiveType;
|
|
397
|
+
if (connection && CONNECTIONS.has(connection))
|
|
398
|
+
event.connection = connection;
|
|
399
|
+
if (options.serviceName)
|
|
400
|
+
event.service = options.serviceName;
|
|
401
|
+
if (options.environment)
|
|
402
|
+
event.environment = options.environment;
|
|
403
|
+
if (options.release)
|
|
404
|
+
event.release = options.release;
|
|
405
|
+
const hasMetric = event.lcp !== undefined || event.fcp !== undefined || event.ttfb !== undefined || event.cls !== undefined || event.inp !== undefined;
|
|
406
|
+
return hasMetric ? event : null;
|
|
407
|
+
};
|
|
408
|
+
/**
|
|
409
|
+
* Reporta as views cujo retrato mudou e fecha as que acabaram. `all` (ocultar, sair, `close`):
|
|
410
|
+
* todas as views, e toda view que acabou fecha. `due`: só as que acabaram e cuja carência venceu
|
|
411
|
+
* (cada uma no seu prazo: uma navegação logo depois de outra não encurta a carência da anterior).
|
|
412
|
+
*/
|
|
413
|
+
const report = (mode) => {
|
|
414
|
+
drain();
|
|
415
|
+
const now = Date.now();
|
|
416
|
+
for (const view of views) {
|
|
417
|
+
if (view.done)
|
|
418
|
+
continue;
|
|
419
|
+
const ended = view.endTime !== Infinity;
|
|
420
|
+
if (mode === 'due' && !(ended && view.closeAt <= now))
|
|
421
|
+
continue;
|
|
422
|
+
const event = snapshot(view);
|
|
423
|
+
if (event && view.seq < MAX_REPORTS_PER_VIEW) {
|
|
424
|
+
const { ts: _ts, seq: _seq, ...rest } = event;
|
|
425
|
+
const signature = JSON.stringify(rest);
|
|
426
|
+
if (signature !== view.lastSignature) {
|
|
427
|
+
view.seq = event.seq;
|
|
428
|
+
view.lastSignature = signature;
|
|
429
|
+
try {
|
|
430
|
+
options.onEvent(event);
|
|
431
|
+
}
|
|
432
|
+
catch (err) {
|
|
433
|
+
options.log?.('web vitals: evento descartado', err);
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
if (ended) {
|
|
438
|
+
view.done = true;
|
|
439
|
+
for (const [id, owner] of owners) {
|
|
440
|
+
if (owner.view !== view)
|
|
441
|
+
continue;
|
|
442
|
+
owners.delete(id);
|
|
443
|
+
retire(id);
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
// Só a view atual e as que esperam a carência ficam na memória.
|
|
448
|
+
for (let i = views.length - 2; i >= 0; i -= 1)
|
|
449
|
+
if (views[i].done && views[i] !== documentView)
|
|
450
|
+
views.splice(i, 1);
|
|
451
|
+
};
|
|
452
|
+
let graceTimer = null;
|
|
453
|
+
/** Agenda o fechamento da próxima view que acabou, no prazo dela. */
|
|
454
|
+
const scheduleDue = () => {
|
|
455
|
+
if (graceTimer)
|
|
456
|
+
clearTimeout(graceTimer);
|
|
457
|
+
graceTimer = null;
|
|
458
|
+
const next = Math.min(...views.filter((view) => !view.done && view.endTime !== Infinity).map((view) => view.closeAt));
|
|
459
|
+
if (!Number.isFinite(next))
|
|
460
|
+
return;
|
|
461
|
+
graceTimer = setTimeout(() => {
|
|
462
|
+
graceTimer = null;
|
|
463
|
+
report('due');
|
|
464
|
+
scheduleDue();
|
|
465
|
+
}, Math.max(0, next - Date.now()));
|
|
466
|
+
graceTimer.unref?.();
|
|
467
|
+
};
|
|
468
|
+
const current = () => views[views.length - 1] ?? null;
|
|
469
|
+
const endCurrent = (at, graceMs) => {
|
|
470
|
+
const view = current();
|
|
471
|
+
if (view && view.endTime === Infinity) {
|
|
472
|
+
view.endTime = at;
|
|
473
|
+
view.closeAt = Date.now() + graceMs;
|
|
474
|
+
}
|
|
475
|
+
};
|
|
476
|
+
let closed = false;
|
|
477
|
+
return {
|
|
478
|
+
get viewId() {
|
|
479
|
+
const view = current();
|
|
480
|
+
return view && view.route && view.endTime === Infinity && !closed ? view.id : null;
|
|
481
|
+
},
|
|
482
|
+
onLocationChange() {
|
|
483
|
+
if (closed || !options.softNavigations)
|
|
484
|
+
return;
|
|
485
|
+
const pathname = pathOf(loc?.pathname);
|
|
486
|
+
const view = current();
|
|
487
|
+
if (!view || pathname === view.pathname)
|
|
488
|
+
return;
|
|
489
|
+
const now = perf.now();
|
|
490
|
+
finalizeLcp(now);
|
|
491
|
+
endCurrent(now, SOFT_VIEW_GRACE_MS);
|
|
492
|
+
if (viewCount < MAX_VIEWS_PER_DOCUMENT)
|
|
493
|
+
openView('soft', pathname, now);
|
|
494
|
+
scheduleDue();
|
|
495
|
+
},
|
|
496
|
+
onHidden(timeStamp) {
|
|
497
|
+
if (closed)
|
|
498
|
+
return;
|
|
499
|
+
const at = typeof timeStamp === 'number' && timeStamp > 0 ? timeStamp : perf.now();
|
|
500
|
+
if (hiddenByEvent === Infinity && !isPrerendering())
|
|
501
|
+
hiddenByEvent = at;
|
|
502
|
+
finalizeLcp(at);
|
|
503
|
+
report('all');
|
|
504
|
+
scheduleDue();
|
|
505
|
+
},
|
|
506
|
+
onPageHide() {
|
|
507
|
+
if (closed)
|
|
508
|
+
return;
|
|
509
|
+
finalizeLcp(perf.now());
|
|
510
|
+
report('all');
|
|
511
|
+
scheduleDue();
|
|
512
|
+
},
|
|
513
|
+
onRestore(timeStamp) {
|
|
514
|
+
if (closed)
|
|
515
|
+
return;
|
|
516
|
+
const at = typeof timeStamp === 'number' && timeStamp > 0 ? timeStamp : perf.now();
|
|
517
|
+
// A view anterior acabou no pagehide, muito antes: fecha sem carência.
|
|
518
|
+
endCurrent(at, 0);
|
|
519
|
+
report('due');
|
|
520
|
+
openView('restore', pathOf(loc?.pathname), at);
|
|
521
|
+
scheduleDue();
|
|
522
|
+
},
|
|
523
|
+
close() {
|
|
524
|
+
if (closed)
|
|
525
|
+
return;
|
|
526
|
+
report('all');
|
|
527
|
+
closed = true;
|
|
528
|
+
if (graceTimer)
|
|
529
|
+
clearTimeout(graceTimer);
|
|
530
|
+
for (const { observer } of observers.splice(0))
|
|
531
|
+
observer.disconnect();
|
|
532
|
+
for (const type of inputEvents)
|
|
533
|
+
win.removeEventListener(type, onInput, true);
|
|
534
|
+
},
|
|
535
|
+
};
|
|
536
|
+
}
|
|
537
|
+
//# sourceMappingURL=vitals.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vitals.js","sourceRoot":"","sources":["../src/vitals.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fg-tracker-browser",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "SDK de navegador do FG Tracker: erros não tratados, breadcrumbs (cliques, navegação, console, fetch), usuário, release
|
|
3
|
+
"version": "0.5.0",
|
|
4
|
+
"description": "SDK de navegador do FG Tracker: erros não tratados, breadcrumbs (cliques, navegação, console, fetch, XHR), usuário, release, propagação de trace para a API e Web Vitals",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"homepage": "https://github.com/FORTGROUND/fg-tracker/tree/main/packages/browser#readme",
|
|
7
7
|
"repository": {
|
|
@@ -20,7 +20,9 @@
|
|
|
20
20
|
"sourcemaps",
|
|
21
21
|
"tracing",
|
|
22
22
|
"analytics",
|
|
23
|
-
"pageviews"
|
|
23
|
+
"pageviews",
|
|
24
|
+
"web-vitals",
|
|
25
|
+
"rum"
|
|
24
26
|
],
|
|
25
27
|
"type": "module",
|
|
26
28
|
"main": "./dist/index.js",
|