mirror of
https://github.com/Findus23/MatomoLiteTracker.git
synced 2024-09-19 16:03: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
|
*.map
|
||||||
node_modules
|
node_modules
|
||||||
dist
|
dist
|
||||||
example/
|
example/*
|
||||||
!example/index.html
|
!example/index.html
|
||||||
!example/main.ts
|
!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)
|
- 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
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",
|
"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",
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 {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)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue