1
0
Fork 0
mirror of https://github.com/Findus23/MatomoLiteTracker.git synced 2024-09-19 16:03:45 +02:00

add performancetracking

This commit is contained in:
Lukas Winkler 2022-04-25 21:31:14 +02:00
parent 30c164f438
commit b14b3127bb
Signed by: lukas
GPG key ID: 54DE4D798D244853
8 changed files with 146 additions and 25 deletions

2
.gitignore vendored
View file

@ -5,6 +5,6 @@ out.min.js
*.map *.map
node_modules node_modules
dist dist
example/ example/*
!example/index.html !example/index.html
!example/main.ts !example/main.ts

View file

@ -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) - much smaller (1KB gzipped with only the core code)
- easier to bundle in applications - easier to bundle in applications
## Features ## Features
- tracking page views - 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 - Campaign tracking
- Search Tracking - Search Tracking
- Goal Tracking - Goal Tracking
- manual Outlink Tracking - Outlink Tracking
- manual ping - manual ping
- manual DoNotTrack detection - manual DoNotTrack detection
- sendBeacon
## missing (yet) ## missing (yet)
- non utf-8 pages - non utf-8 pages
- performance tracking
- setCustomUrl - setCustomUrl
- setReferrerUrl - setReferrerUrl
- automatic outlink tracking
- event queue (every tracking request is sent immediatly when it is tracked)[^1]
- HeartBeatTimer (automatic regular ping) - HeartBeatTimer (automatic regular ping)
## missing (???) ## missing (???)
@ -51,6 +49,7 @@ That said, if you are interested in trying it out, I'd be interested in hearing
- Content Tracking - Content Tracking
- download tracking - download tracking
- setDomains - setDomains
- event queue (every tracking request is sent immediatly when it is tracked)[^1]
## missing (intentionally) ## missing (intentionally)

13
example/index.html Normal file
View 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
View 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()

View file

@ -6,7 +6,8 @@
"module": "dist/tracker.js", "module": "dist/tracker.js",
"type": "module", "type": "module",
"scripts": { "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": { "devDependencies": {
"esbuild": "^0.14.38", "esbuild": "^0.14.38",

View file

@ -3,3 +3,4 @@ export const navigatorAlias = navigator
export const screenAlias = screen export const screenAlias = screen
export const windowAlias = window export const windowAlias = window
export const locationAlias = windowAlias.location export const locationAlias = windowAlias.location
export const performanceAlias = windowAlias.performance

View file

@ -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)
}
}
}

View file

@ -1,8 +1,9 @@
import {documentAlias} from "./aliases"; import {documentAlias, navigatorAlias} from "./aliases";
import {boolToIntBool, getCurrentURL} from "./url"; import {boolToIntBool, getCurrentURL} from "./url";
import type {CustomDimensionName, CustomDimensions, IntBoolean, LinkType} from "./types"; import type {CustomDimensionName, CustomDimensions, IntBoolean, LinkType} from "./types";
import type {BrowserFeatures} from "./browserfeatures"; import type {BrowserFeatures} from "./browserfeatures";
import {generateUniqueId} from "./util"; import {generateUniqueId} from "./util";
import type {PerformanceMetric} from "./performancetracking";
// the query paramters the Matomo API expects to recieve // the query paramters the Matomo API expects to recieve
@ -66,6 +67,13 @@ interface Request {
interface PageViewRequest extends Request { interface PageViewRequest extends Request {
// Title // Title
action_name: string 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 { interface EventRequest extends Request {
@ -106,6 +114,8 @@ export class MatomoLiteTracker {
siteID: number siteID: number
matomoURL: string matomoURL: string
phpFileName: string = "matomo.php" phpFileName: string = "matomo.php"
useSendBeacon: boolean = false
performanceMetric?: PerformanceMetric
userID?: string userID?: string
browserFeatures?: BrowserFeatures browserFeatures?: BrowserFeatures
customDimensions?: CustomDimensions customDimensions?: CustomDimensions
@ -163,6 +173,16 @@ export class MatomoLiteTracker {
this.pageViewID = generateUniqueId() this.pageViewID = generateUniqueId()
const parameters = this.getRequest() as PageViewRequest const parameters = this.getRequest() as PageViewRequest
parameters.action_name = customTitle ? customTitle : documentAlias.title 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) this.sendRequest(parameters)
} }
@ -203,7 +223,7 @@ export class MatomoLiteTracker {
trackLink(sourceUrl: string, linkType: LinkType) { trackLink(sourceUrl: string, linkType: LinkType) {
const parameters = this.getRequest() as OutlinkRequest const parameters = this.getRequest() as OutlinkRequest
parameters[linkType] = sourceUrl parameters[linkType] = sourceUrl
this.sendRequest(parameters) this.sendRequest(parameters, true)
} }
ping() { ping() {
@ -212,13 +232,17 @@ export class MatomoLiteTracker {
this.sendRequest(parameters) this.sendRequest(parameters)
} }
sendRequest(parameters: Request) { sendRequest(parameters: Request, forceBeacon: boolean = false) {
console.log(parameters) console.log(parameters)
const requestMethod = this.requestMethod const requestMethod = this.requestMethod
const params = new URLSearchParams(parameters) const params = new URLSearchParams(parameters)
let url = this.matomoURL let url = this.matomoURL
+ (this.matomoURL.endsWith("/") ? "" : "/") + (this.matomoURL.endsWith("/") ? "" : "/")
+ this.phpFileName + this.phpFileName
console.log(url)
if (this.useSendBeacon || forceBeacon) {
navigatorAlias.sendBeacon(url, params)
} else {
if (requestMethod === "GET") { if (requestMethod === "GET") {
url += "?" + params.toString() url += "?" + params.toString()
} }
@ -231,9 +255,9 @@ export class MatomoLiteTracker {
if (requestMethod === "POST") { if (requestMethod === "POST") {
options.body = params options.body = params
} }
console.log(url)
fetch(url, options).then(value => { fetch(url, options).then(value => {
console.info(value) console.info(value)
}) })
} }
}
} }