-
Notifications
You must be signed in to change notification settings - Fork 4
feat: add main-thread blocking detection (Long Tasks + LoAF + web Vitals) #166
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 16 commits
f5a369f
db69d93
442da72
3381039
0eef530
fa6cb0f
54a6fd3
203f1b7
068db0b
7355dda
b4755a1
d905d8b
6ec3d83
2619d36
2906466
d77424c
15c2982
6f1d2cc
cdcb316
2d5f4ca
a6a2a4d
d4ea672
5824ad7
62adf6f
029115a
5a206b4
35ee372
a61ec38
2117a70
6d56404
da281ae
b8c1310
ec425bd
b4fff54
c9e89e3
367b7e0
f7f9f01
d812192
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||
|---|---|---|---|---|
|
|
@@ -11,6 +11,9 @@ Error tracking for JavaScript/TypeScript applications. | |||
| - 🛡️ Sensitive data filtering | ||||
| - 🌟 Source maps consuming | ||||
| - 💬 Console logs tracking | ||||
| - 🧊 Main-thread blocking detection (Long Tasks + LoAF, Chromium-only) | ||||
| - 📊 Aggregated Web Vitals issues monitoring | ||||
| - ⚙️ Unified `issues` configuration (errors + performance detectors) | ||||
|
neSpecc marked this conversation as resolved.
Outdated
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||
| - <img src="https://cdn.svglogos.dev/logos/vue.svg" width="16" height="16"> Vue support | ||||
| - <img src="https://cdn.svglogos.dev/logos/react.svg" width="16" height="16"> React support | ||||
|
|
||||
|
|
@@ -85,11 +88,12 @@ Initialization settings: | |||
| | `user` | {id: string, name?: string, image?: string, url?: string} | optional | Current authenticated user | | ||||
| | `context` | object | optional | Any data you want to pass with every message. Has limitation of length. | | ||||
| | `vue` | Vue constructor | optional | Pass Vue constructor to set up the [Vue integration](#integrate-to-vue-application) | | ||||
| | `disableGlobalErrorsHandling` | boolean | optional | Do not initialize global errors handling | | ||||
| | `disableGlobalErrorsHandling` | boolean | optional | Deprecated. Use `issues.errors: false` instead. | | ||||
| | `disableVueErrorHandler` | boolean | optional | Do not initialize Vue errors handling | | ||||
| | `consoleTracking` | boolean | optional | Initialize console logs tracking | | ||||
| | `breadcrumbs` | false or BreadcrumbsOptions object | optional | Configure breadcrumbs tracking (see below) | | ||||
| | `beforeSend` | function(event) => event \| false \| void | optional | Filter data before sending. Return modified event, `false` to drop the event. | | ||||
| | `issues` | IssuesOptions object | optional | Issues config: `errors`, `webVitals`, `longTasks.thresholdMs`, `longAnimationFrames.thresholdMs` | | ||||
|
|
||||
| Other available [initial settings](types/hawk-initial-settings.d.ts) are described at the type definition. | ||||
|
|
||||
|
|
@@ -232,6 +236,85 @@ const breadcrumbs = hawk.breadcrumbs.get(); | |||
| hawk.breadcrumbs.clear(); | ||||
| ``` | ||||
|
|
||||
| ## Issues Detection | ||||
|
|
||||
| `issues` is an umbrella option for problems detected by the catcher. | ||||
| Browser support depends on the specific detector: | ||||
| - `errors` — works in all supported browsers | ||||
| - `webVitals` — via `web-vitals` package | ||||
| - `longTasks` / `longAnimationFrames` — Chromium-only (`long-animation-frame` requires Chrome/Edge 123+) | ||||
|
|
||||
| It currently includes three groups: | ||||
|
|
||||
| - `issues.errors` — global runtime errors handling | ||||
| - `issues.webVitals` — aggregated Core Web Vitals report | ||||
| - `issues.longTasks` and `issues.longAnimationFrames` — freeze-related detectors | ||||
|
|
||||
| Freeze detectors use two complementary APIs: | ||||
|
|
||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add
and pattern example |
||||
| - **Long Tasks API** — browser reports tasks taking longer than 50 ms. | ||||
| - **Long Animation Frames (LoAF)** — browser reports frames taking longer than 50 ms with richer script attribution (Chrome 123+, Edge 123+). | ||||
|
|
||||
| Both freeze detectors are disabled by default. If enabled and one API is unsupported, the other still works. | ||||
| Each detected freeze is reported immediately with detailed context (duration, blocking time, scripts involved, etc.). | ||||
| `thresholdMs` is an additional Hawk filter on top of browser reporting. Hawk emits an issue when measured duration is equal to or greater than this value. Values below `50ms` are clamped to `50ms`. | ||||
|
|
||||
| ### Web Vitals (Aggregated) | ||||
|
|
||||
| When `issues.webVitals` is enabled, Hawk collects Core Web Vitals (`LCP`, `FCP`, `TTFB`, `INP`, `CLS`) and sends a single issue event when at least one metric is rated `poor`. | ||||
| Reporting happens when all five metrics are collected, or earlier on timeout/page unload to avoid waiting indefinitely on pages where some metrics never fire. | ||||
|
|
||||
| The event context contains all metrics with: | ||||
| - `value` | ||||
| - `rating` | ||||
| - `delta` | ||||
|
|
||||
| `web-vitals` is optional and used only when `issues.webVitals: true`: | ||||
| - NPM/ESM setup: install `web-vitals` as dependency. | ||||
| - CDN setup: expose global `window.webVitals` before Hawk initialization. | ||||
|
|
||||
| ### Disabling | ||||
|
|
||||
| Disable global errors handling: | ||||
|
|
||||
| ```js | ||||
| const hawk = new HawkCatcher({ | ||||
| token: 'INTEGRATION_TOKEN', | ||||
| issues: { | ||||
| errors: false | ||||
| } | ||||
| }); | ||||
| ``` | ||||
|
|
||||
| ### Selective Configuration | ||||
|
|
||||
| Configure all issue detectors: | ||||
|
|
||||
| ```js | ||||
| const hawk = new HawkCatcher({ | ||||
| token: 'INTEGRATION_TOKEN', | ||||
| issues: { | ||||
| errors: true, | ||||
| webVitals: true, | ||||
| longTasks: { | ||||
| thresholdMs: 70 | ||||
| }, | ||||
| longAnimationFrames: { | ||||
| thresholdMs: 200 | ||||
| } | ||||
| } | ||||
| }); | ||||
| ``` | ||||
|
|
||||
| ### Options | ||||
|
|
||||
| | Option | Type | Default | Description | | ||||
| |--------|------|---------|-------------| | ||||
| | `errors` | `boolean` | `true` | Enable global errors handling (`window.onerror` and `unhandledrejection`). | | ||||
| | `webVitals` | `boolean` | `false` | Collect all Core Web Vitals and send one issue event when at least one metric is rated `poor`. Requires optional `web-vitals` dependency. | | ||||
| | `longTasks` | `boolean` or `{ thresholdMs?: number }` | `false` | `false` disables. `true` enables with default threshold. Object enables and uses `thresholdMs` when valid; otherwise fallback threshold `70ms` is used (minimum effective value `50ms`). | | ||||
| | `longAnimationFrames` | `boolean` or `{ thresholdMs?: number }` | `false` | `false` disables. `true` enables with default threshold. Object enables and uses `thresholdMs` when valid; otherwise fallback threshold `200ms` is used (minimum effective value `50ms`). Requires Chrome 123+ / Edge 123+. | | ||||
|
|
||||
| ## Source maps consuming | ||||
|
|
||||
| If your bundle is minified, it is useful to pass source-map files to the Hawk. After that you will see beautiful | ||||
|
|
||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.