mirror of
https://github.com/Findus23/MatomoLiteTracker.git
synced 2024-09-11 06:43:45 +02:00
add performancetracking
This commit is contained in:
parent
30c164f438
commit
b14b3127bb
8 changed files with 146 additions and 25 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -5,6 +5,6 @@ out.min.js
|
|||
*.map
|
||||
node_modules
|
||||
dist
|
||||
example/
|
||||
example/*
|
||||
!example/index.html
|
||||
!example/main.ts
|
||||
|
|
|
@ -16,8 +16,6 @@ That said, if you are interested in trying it out, I'd be interested in hearing
|
|||
- much smaller (1KB gzipped with only the core code)
|
||||
- easier to bundle in applications
|
||||
|
||||
|
||||
|
||||
## Features
|
||||
|
||||
- tracking page views
|
||||
|
@ -32,17 +30,17 @@ That said, if you are interested in trying it out, I'd be interested in hearing
|
|||
- Campaign tracking
|
||||
- Search Tracking
|
||||
- Goal Tracking
|
||||
- manual Outlink Tracking
|
||||
- Outlink Tracking
|
||||
- manual ping
|
||||
- manual DoNotTrack detection
|
||||
- sendBeacon
|
||||
|
||||
## missing (yet)
|
||||
|
||||
- non utf-8 pages
|
||||
- performance tracking
|
||||
- setCustomUrl
|
||||
- setReferrerUrl
|
||||
- automatic outlink tracking
|
||||
- event queue (every tracking request is sent immediatly when it is tracked)[^1]
|
||||
- HeartBeatTimer (automatic regular ping)
|
||||
|
||||
## missing (???)
|
||||
|
@ -51,6 +49,7 @@ That said, if you are interested in trying it out, I'd be interested in hearing
|
|||
- Content Tracking
|
||||
- download tracking
|
||||
- setDomains
|
||||
- event queue (every tracking request is sent immediatly when it is tracked)[^1]
|
||||
|
||||
## missing (intentionally)
|
||||
|
||||
|
|
13
example/index.html
Normal file
13
example/index.html
Normal file
|
@ -0,0 +1,13 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Title</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<a href="https://example.com">TEST</a>
|
||||
|
||||
<script src="main.js"></script>
|
||||
</body>
|
||||
</html>
|
17
example/main.ts
Normal file
17
example/main.ts
Normal file
|
@ -0,0 +1,17 @@
|
|||
import {MatomoLiteTracker} from "../src/tracker";
|
||||
import {BrowserFeatures, detectBrowserPlugins} from "../src/browserfeatures";
|
||||
import {defaultDownloadFileExtensions, enableLinkTracking} from "../src/linktracking";
|
||||
import {PerformanceMetric} from "../src/performancetracking";
|
||||
|
||||
const matomo = new MatomoLiteTracker("https://dev.matomo", 1)
|
||||
matomo.performanceMetric = new PerformanceMetric()
|
||||
console.log(matomo.performanceMetric)
|
||||
const features = new BrowserFeatures()
|
||||
features.addBrowserPlugins(detectBrowserPlugins())
|
||||
matomo.browserFeatures = features
|
||||
matomo.customDimensions = {
|
||||
2: "something"
|
||||
}
|
||||
|
||||
enableLinkTracking(matomo, defaultDownloadFileExtensions)
|
||||
matomo.trackPageview()
|
|
@ -6,7 +6,8 @@
|
|||
"module": "dist/tracker.js",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
"build": "tsc && node --loader ts-node/esm build.ts",
|
||||
"serve": "node --loader ts-node/esm build.ts serve"
|
||||
},
|
||||
"devDependencies": {
|
||||
"esbuild": "^0.14.38",
|
||||
|
|
|
@ -3,3 +3,4 @@ export const navigatorAlias = navigator
|
|||
export const screenAlias = screen
|
||||
export const windowAlias = window
|
||||
export const locationAlias = windowAlias.location
|
||||
export const performanceAlias = windowAlias.performance
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
import {performanceAlias} from "./aliases";
|
||||
|
||||
// strongly based on appendAvailablePerformanceMetrics() in piwik.js
|
||||
|
||||
function diff(end: number, start: number): number | undefined {
|
||||
const value = Math.round(end - start)
|
||||
if (value > 0) {
|
||||
return value
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
export class PerformanceMetric {
|
||||
pf_net?: number | undefined
|
||||
pf_srv?: number | undefined
|
||||
pf_tfr?: number | undefined
|
||||
pf_dm1?: number | undefined
|
||||
pf_dm2?: number | undefined
|
||||
pf_onl?: number | undefined
|
||||
|
||||
constructor() {
|
||||
let performanceData: PerformanceNavigationTiming | PerformanceTiming | undefined
|
||||
performanceData = (typeof performanceAlias.timing === 'object') && performanceAlias.timing ? performanceAlias.timing : undefined;
|
||||
if (typeof performanceData === "undefined") {
|
||||
if ((typeof performanceAlias.getEntriesByType === 'function') && performanceAlias.getEntriesByType('navigation')) {
|
||||
performanceData = performanceAlias.getEntriesByType('navigation')[0] as PerformanceNavigationTiming;
|
||||
}
|
||||
}
|
||||
|
||||
if (!performanceData) {
|
||||
return;
|
||||
}
|
||||
console.log(performanceData)
|
||||
if (performanceData.connectEnd && performanceData.fetchStart) {
|
||||
this.pf_net = diff(performanceData.connectEnd, performanceData.fetchStart)
|
||||
console.info(performanceData.connectEnd - performanceData.fetchStart)
|
||||
}
|
||||
if (performanceData.responseStart && performanceData.requestStart) {
|
||||
this.pf_srv = diff(performanceData.responseStart, performanceData.requestStart)
|
||||
}
|
||||
if (performanceData.responseStart && performanceData.responseEnd) {
|
||||
this.pf_tfr = diff(performanceData.responseStart, performanceData.responseEnd)
|
||||
}
|
||||
if (performanceData.responseStart && performanceData.responseEnd) {
|
||||
this.pf_tfr = diff(performanceData.responseStart, performanceData.responseEnd)
|
||||
}
|
||||
// @ts-ignore
|
||||
if (performanceData.domLoading !== "undefined") {
|
||||
// @ts-ignore
|
||||
if (performanceData.domInteractive && performanceData.domLoading) {
|
||||
// @ts-ignore
|
||||
this.pf_dm1 = diff(performanceData.domInteractive, performanceData.domLoading)
|
||||
}
|
||||
} else {
|
||||
if (performanceData.domInteractive && performanceData.responseEnd) {
|
||||
this.pf_dm1 = diff(performanceData.domInteractive, performanceData.responseEnd)
|
||||
}
|
||||
}
|
||||
if (performanceData.domComplete && performanceData.domInteractive) {
|
||||
this.pf_dm2 = diff(performanceData.domComplete, performanceData.domInteractive)
|
||||
}
|
||||
if (performanceData.loadEventEnd && performanceData.loadEventStart) {
|
||||
this.pf_onl = diff(performanceData.loadEventEnd, performanceData.loadEventStart)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,8 +1,9 @@
|
|||
import {documentAlias} from "./aliases";
|
||||
import {documentAlias, navigatorAlias} from "./aliases";
|
||||
import {boolToIntBool, getCurrentURL} from "./url";
|
||||
import type {CustomDimensionName, CustomDimensions, IntBoolean, LinkType} from "./types";
|
||||
import type {BrowserFeatures} from "./browserfeatures";
|
||||
import {generateUniqueId} from "./util";
|
||||
import type {PerformanceMetric} from "./performancetracking";
|
||||
|
||||
|
||||
// the query paramters the Matomo API expects to recieve
|
||||
|
@ -66,6 +67,13 @@ interface Request {
|
|||
interface PageViewRequest extends Request {
|
||||
// Title
|
||||
action_name: string
|
||||
pf_net?: number
|
||||
pf_srv?: number
|
||||
pf_tfr?: number
|
||||
pf_dm1?: number
|
||||
pf_dm2?: number
|
||||
pf_onl?: number
|
||||
|
||||
}
|
||||
|
||||
interface EventRequest extends Request {
|
||||
|
@ -106,6 +114,8 @@ export class MatomoLiteTracker {
|
|||
siteID: number
|
||||
matomoURL: string
|
||||
phpFileName: string = "matomo.php"
|
||||
useSendBeacon: boolean = false
|
||||
performanceMetric?: PerformanceMetric
|
||||
userID?: string
|
||||
browserFeatures?: BrowserFeatures
|
||||
customDimensions?: CustomDimensions
|
||||
|
@ -163,6 +173,16 @@ export class MatomoLiteTracker {
|
|||
this.pageViewID = generateUniqueId()
|
||||
const parameters = this.getRequest() as PageViewRequest
|
||||
parameters.action_name = customTitle ? customTitle : documentAlias.title
|
||||
const performanceMetric = this.performanceMetric
|
||||
if (performanceMetric) {
|
||||
console.log(performanceMetric)
|
||||
Object.entries(performanceMetric).forEach(([key, value]) => {
|
||||
if (typeof value !== "undefined") {
|
||||
parameters[key] = value
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
this.sendRequest(parameters)
|
||||
}
|
||||
|
||||
|
@ -203,7 +223,7 @@ export class MatomoLiteTracker {
|
|||
trackLink(sourceUrl: string, linkType: LinkType) {
|
||||
const parameters = this.getRequest() as OutlinkRequest
|
||||
parameters[linkType] = sourceUrl
|
||||
this.sendRequest(parameters)
|
||||
this.sendRequest(parameters, true)
|
||||
}
|
||||
|
||||
ping() {
|
||||
|
@ -212,28 +232,32 @@ export class MatomoLiteTracker {
|
|||
this.sendRequest(parameters)
|
||||
}
|
||||
|
||||
sendRequest(parameters: Request) {
|
||||
sendRequest(parameters: Request, forceBeacon: boolean = false) {
|
||||
console.log(parameters)
|
||||
const requestMethod = this.requestMethod
|
||||
const params = new URLSearchParams(parameters)
|
||||
let url = this.matomoURL
|
||||
+ (this.matomoURL.endsWith("/") ? "" : "/")
|
||||
+ this.phpFileName
|
||||
if (requestMethod === "GET") {
|
||||
url += "?" + params.toString()
|
||||
}
|
||||
const options: RequestInit = {
|
||||
method: requestMethod,
|
||||
mode: "no-cors",
|
||||
cache: "no-cache",
|
||||
credentials: "omit",
|
||||
}
|
||||
if (requestMethod === "POST") {
|
||||
options.body = params
|
||||
}
|
||||
console.log(url)
|
||||
fetch(url, options).then(value => {
|
||||
console.info(value)
|
||||
})
|
||||
if (this.useSendBeacon || forceBeacon) {
|
||||
navigatorAlias.sendBeacon(url, params)
|
||||
} else {
|
||||
if (requestMethod === "GET") {
|
||||
url += "?" + params.toString()
|
||||
}
|
||||
const options: RequestInit = {
|
||||
method: requestMethod,
|
||||
mode: "no-cors",
|
||||
cache: "no-cache",
|
||||
credentials: "omit",
|
||||
}
|
||||
if (requestMethod === "POST") {
|
||||
options.body = params
|
||||
}
|
||||
fetch(url, options).then(value => {
|
||||
console.info(value)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue