generated from cms/tibi-docs
This commit is contained in:
parent
f5526e7907
commit
b1d84bc633
29
api/collections/lighthouse-subpaths.yml
Normal file
29
api/collections/lighthouse-subpaths.yml
Normal file
@ -0,0 +1,29 @@
|
||||
name: lighthouseSubpath
|
||||
|
||||
meta:
|
||||
label: Lighthouse Subpaths
|
||||
muiIcon: web
|
||||
views:
|
||||
- type: table
|
||||
columns:
|
||||
- source: lighthouseSubpath
|
||||
|
||||
permissions:
|
||||
public:
|
||||
methods:
|
||||
get: false
|
||||
post: false
|
||||
put: false
|
||||
delete: false
|
||||
user:
|
||||
methods:
|
||||
get: true
|
||||
post: true
|
||||
put: true
|
||||
delete: true
|
||||
|
||||
fields:
|
||||
- type: string
|
||||
name: lighthouseSubpath
|
||||
meta:
|
||||
label: PagespeedPaths
|
120
api/collections/lighthouse.yml
Normal file
120
api/collections/lighthouse.yml
Normal file
@ -0,0 +1,120 @@
|
||||
name: lighthouse
|
||||
|
||||
meta:
|
||||
label: Lighthouse
|
||||
muiIcon: web
|
||||
views:
|
||||
- type: table
|
||||
mediaQuery: "(min-width: 600px)"
|
||||
columns:
|
||||
- source: insertTime
|
||||
filter: true
|
||||
- source: perfomance
|
||||
filter: true
|
||||
- source: accessibility
|
||||
filter: true
|
||||
- source: bestPractices
|
||||
filter: true
|
||||
- source: seo
|
||||
filter: true
|
||||
- type: simpleList
|
||||
mediaQuery: "(max-width: 599px)"
|
||||
primaryText: insertTime
|
||||
secondaryText: performance
|
||||
tertiaryText: accessibility
|
||||
|
||||
permissions:
|
||||
public:
|
||||
methods:
|
||||
get: false
|
||||
post: false
|
||||
put: false
|
||||
delete: false
|
||||
user:
|
||||
methods:
|
||||
get: true
|
||||
post: true
|
||||
put: true
|
||||
delete: true
|
||||
|
||||
projections:
|
||||
dashboard:
|
||||
|
||||
hooks:
|
||||
post:
|
||||
create:
|
||||
type: javascript
|
||||
file: hooks/lighthouse/post_create.js
|
||||
|
||||
fields:
|
||||
- name: analyzedPaths
|
||||
type: string[]
|
||||
meta:
|
||||
label: Analyzed Paths
|
||||
- name: performance
|
||||
type: number
|
||||
meta:
|
||||
label: Performance
|
||||
- name: accessibility
|
||||
type: number
|
||||
meta:
|
||||
label: Accessibility
|
||||
- name: bestPractices
|
||||
type: number
|
||||
meta:
|
||||
label: Best Practices
|
||||
- name: seo
|
||||
type: number
|
||||
meta:
|
||||
label: SEO
|
||||
- name: lighthouseMetrics
|
||||
|
||||
type: object
|
||||
meta:
|
||||
label: Lighthouse Metrics
|
||||
subFields:
|
||||
- name: FCPS
|
||||
type: number
|
||||
meta:
|
||||
label: First Contentful Paint Score
|
||||
- name: FCPV
|
||||
type: number
|
||||
meta:
|
||||
label: First Contentful Paint Value
|
||||
- name: FMPV
|
||||
type: number
|
||||
meta:
|
||||
label: First Meaningful Paint Value
|
||||
|
||||
- name: FMPS
|
||||
type: number
|
||||
meta:
|
||||
label: First Meaningful Paint Score
|
||||
|
||||
- name: SIS
|
||||
type: number
|
||||
meta:
|
||||
label: Speed Index Score
|
||||
|
||||
- name: SIV
|
||||
type: number
|
||||
meta:
|
||||
label: Speed Index Value
|
||||
- name: TTIS
|
||||
type: number
|
||||
meta:
|
||||
label: Time to Interactive Score
|
||||
|
||||
- name: TTIV
|
||||
type: number
|
||||
meta:
|
||||
label: Time to Interactive Value
|
||||
- name: FPIDS
|
||||
type: number
|
||||
meta:
|
||||
label: First Potential Input Delay Score
|
||||
|
||||
- name: FPIDV
|
||||
type: number
|
||||
meta:
|
||||
label: First Potential Input Delay Value
|
267
api/config.yml
267
api/config.yml
@ -7,9 +7,248 @@ meta:
|
||||
servers:
|
||||
- url: https://tibi-admin-server.code.testversion.online/api/v1/_/demo
|
||||
description: code-server
|
||||
|
||||
dashboard:
|
||||
majorItems:
|
||||
- type: "sectionTitle"
|
||||
title: { de: "Website Perfomance", en: "Website Perfomance" }
|
||||
appendix:
|
||||
collection: lighthouse
|
||||
eval: |
|
||||
(function(){
|
||||
return " " + new Date($date).toLocaleDateString() + ""
|
||||
})()
|
||||
- type: graph
|
||||
filter: false
|
||||
graphType: radialBar
|
||||
until: "lastYear"
|
||||
value: total
|
||||
containerProps:
|
||||
#optional class prop
|
||||
layout:
|
||||
breakBefore: false
|
||||
breakAfter: false
|
||||
size:
|
||||
default: "col-6"
|
||||
small: "col-12"
|
||||
large: "col-3"
|
||||
options:
|
||||
{
|
||||
property: plotOptions,
|
||||
value:
|
||||
{
|
||||
radialBar:
|
||||
{
|
||||
hollow: { margin: 0, size: "70%" },
|
||||
track: { dropShadow: { enabled: true, top: 2, left: 0, blur: 4, opacity: 0.15 } },
|
||||
dataLabels:
|
||||
{
|
||||
name: { offsetY: -10, color: "#000", fontSize: "13px" },
|
||||
value: { color: "#000", fontSize: "30px", show: true },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
graphs:
|
||||
- collection: lighthouse
|
||||
field: performance
|
||||
yAxis: latestValue
|
||||
graphName: { de: "Perfomance Score", en: "Perfomance Score" }
|
||||
dateTimeField: insertTime
|
||||
|
||||
- type: graph
|
||||
filter: false
|
||||
graphType: radialBar
|
||||
until: "lastYear"
|
||||
value: total
|
||||
containerProps:
|
||||
#optional class prop
|
||||
layout:
|
||||
breakBefore: false
|
||||
breakAfter: false
|
||||
size:
|
||||
default: "col-6"
|
||||
small: "col-12"
|
||||
large: "col-3"
|
||||
options:
|
||||
{
|
||||
property: plotOptions,
|
||||
value:
|
||||
{
|
||||
radialBar:
|
||||
{
|
||||
hollow: { margin: 0, size: "70%" },
|
||||
track: { dropShadow: { enabled: true, top: 2, left: 0, blur: 4, opacity: 0.15 } },
|
||||
dataLabels:
|
||||
{
|
||||
name: { offsetY: -10, color: "#000", fontSize: "13px" },
|
||||
value: { color: "#000", fontSize: "30px", show: true },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
graphs:
|
||||
- collection: lighthouse
|
||||
field: accessibility
|
||||
yAxis: latestValue
|
||||
graphName: { de: "Accessibility Score", en: "Accessibility Score" }
|
||||
dateTimeField: insertTime
|
||||
|
||||
- type: graph
|
||||
filter: false
|
||||
graphType: radialBar
|
||||
until: "lastYear"
|
||||
value: total
|
||||
containerProps:
|
||||
#optional class prop
|
||||
layout:
|
||||
breakBefore: false
|
||||
breakAfter: false
|
||||
size:
|
||||
default: "col-6"
|
||||
small: "col-12"
|
||||
large: "col-3"
|
||||
options:
|
||||
{
|
||||
property: plotOptions,
|
||||
value:
|
||||
{
|
||||
radialBar:
|
||||
{
|
||||
hollow: { margin: 0, size: "70%" },
|
||||
track: { dropShadow: { enabled: true, top: 2, left: 0, blur: 4, opacity: 0.15 } },
|
||||
dataLabels:
|
||||
{
|
||||
name: { offsetY: -10, color: "#000", fontSize: "13px" },
|
||||
value: { color: "#000", fontSize: "30px", show: true },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
graphs:
|
||||
- collection: lighthouse
|
||||
field: bestPractices
|
||||
yAxis: latestValue
|
||||
graphName: { de: "Best Practices Score", en: "Best Practices Score" }
|
||||
dateTimeField: insertTime
|
||||
|
||||
- type: graph
|
||||
filter: false
|
||||
graphType: radialBar
|
||||
until: "lastYear"
|
||||
value: total
|
||||
containerProps:
|
||||
#optional class prop
|
||||
layout:
|
||||
breakBefore: false
|
||||
breakAfter: false
|
||||
size:
|
||||
default: "col-6"
|
||||
small: "col-12"
|
||||
large: "col-3"
|
||||
options:
|
||||
{
|
||||
property: plotOptions,
|
||||
value:
|
||||
{
|
||||
radialBar:
|
||||
{
|
||||
hollow: { margin: 0, size: "70%" },
|
||||
track: { dropShadow: { enabled: true, top: 2, left: 0, blur: 4, opacity: 0.15 } },
|
||||
dataLabels:
|
||||
{
|
||||
name: { offsetY: -10, color: "#000", fontSize: "13px" },
|
||||
value: { color: "#000", fontSize: "30px", show: true },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
graphs:
|
||||
- collection: lighthouse
|
||||
field: seo
|
||||
yAxis: latestValue
|
||||
graphName: { de: "SEO Score", en: "SEO Score" }
|
||||
dateTimeField: insertTime
|
||||
|
||||
- type: swiper # Art des Elements, hier ein Swiper
|
||||
containerProps:
|
||||
#optional class prop
|
||||
layout:
|
||||
breakBefore: false
|
||||
breakAfter: false
|
||||
size:
|
||||
default: "col-12"
|
||||
small: "col-12"
|
||||
large: "col-6 row-2-4"
|
||||
|
||||
elements: # Liste der Elemente in diesem Swiper
|
||||
- type: graph
|
||||
title:
|
||||
value: { de: "Ladezeit (Score)", en: "Loadtime (Score)" }
|
||||
xAxis: manual
|
||||
until: "lastYear"
|
||||
filter: false #deaktiviert die Filter möglichkeit für den Nutzer beim diagramm, normalerweise aktiviert. Hierbei sind alle kombinationen x >= until möglich
|
||||
columns:
|
||||
- name: { de: '["Erstes sichtbares", "Element"]', en: '["First Contentful", "Paint"]' }
|
||||
field: lighthouseMetrics.FCPS
|
||||
|
||||
- name: { de: '["Erstes bedeutsames", "Element"]', en: '["First Meaningful", "Paint"]' }
|
||||
field: lighthouseMetrics.FMPS
|
||||
|
||||
- name:
|
||||
{
|
||||
de: '["Maximale potenzielle", "erste", "ingabeverzögerung"]',
|
||||
en: '["Max Potential", "First Input", "Delay"]',
|
||||
}
|
||||
field: lighthouseMetrics.FPIDS
|
||||
|
||||
- name: { de: '["Zeit bis", "zur", "Interaktivität"]', en: '["Time to", "Interactive"]' }
|
||||
field: lighthouseMetrics.TTIS
|
||||
|
||||
- name: { de: '["Geschwindigkeitsindex"]', en: '["Speed Index"]' }
|
||||
field: lighthouseMetrics.SIS
|
||||
|
||||
graphType: "bar"
|
||||
graphs:
|
||||
- graphName: { de: "Lighthouse Metriken", en: "Lighthouse Metrics" }
|
||||
yAxis: latestValue
|
||||
collection: lighthouse
|
||||
dateTimeField: insertTime
|
||||
- type: graph
|
||||
title:
|
||||
value: { de: "Ladezeit (Sekunden)", en: "Loadtime (seconds)" }
|
||||
xAxis: manual
|
||||
until: "lastYear"
|
||||
filter: false #deaktiviert die Filter möglichkeit für den Nutzer beim diagramm, normalerweise aktiviert. Hierbei sind alle kombinationen x >= until möglich
|
||||
columns:
|
||||
- name: { de: '["Erstes sichtbares", "Element"]', en: '["First Contentful", "Paint"]' }
|
||||
field: lighthouseMetrics.FCPV
|
||||
|
||||
- name: { de: '["Erstes bedeutsames", "Element"]', en: '["First Meaningful", "Paint"]' }
|
||||
field: lighthouseMetrics.FMPV
|
||||
|
||||
- name:
|
||||
{
|
||||
de: '["Maximale potenzielle", "erste", "ingabeverzögerung"]',
|
||||
en: '["Max Potential", "First Input", "Delay"]',
|
||||
}
|
||||
field: lighthouseMetrics.FPIDV
|
||||
|
||||
- name: { de: '["Zeit bis", "zur", "Interaktivität"]', en: '["Time to", "Interactive"]' }
|
||||
field: lighthouseMetrics.TTIV
|
||||
|
||||
- name: { de: '["Geschwindigkeitsindex"]', en: '["Speed Index"]' }
|
||||
field: lighthouseMetrics.SIV
|
||||
|
||||
graphType: "bar"
|
||||
graphs:
|
||||
- graphName: { de: "Lighthouse Metriken", en: "Lighthouse Metrics" }
|
||||
yAxis: latestValue
|
||||
collection: lighthouse
|
||||
dateTimeField: insertTime
|
||||
|
||||
- type: "sectionTitle"
|
||||
title: { de: "Seiteninhalte", en: "Page content" }
|
||||
|
||||
- collection: navigation
|
||||
type: reference
|
||||
style:
|
||||
@ -34,6 +273,25 @@ meta:
|
||||
upper: rgba(3, 50, 59, 0.7)
|
||||
lower: rgba(3, 50, 59)
|
||||
|
||||
- type: "sectionTitle"
|
||||
title: { de: "Aktionen", en: "Actions" }
|
||||
|
||||
- collection: lighthouse
|
||||
type: action
|
||||
action: "Lighthouse Durchlauf starten"
|
||||
backgroundAction: true
|
||||
modalText:
|
||||
{
|
||||
de: "Zur Analyse der Website werden einige Zeitintensive prozesse gestartet, daher wird dies im Hintergrund ausgeführt. Es kann einige Minuten dauern bis das Dashboard aktuallisiert wird, bitte haben Sie etwas Geduld.",
|
||||
en: "To analyze the website, some time-intensive processes are started, so this is done in the background. It may take a few minutes for the dashboard to be updated, please be patient.",
|
||||
}
|
||||
properties:
|
||||
url: https://www.fontis.de
|
||||
type: post
|
||||
style:
|
||||
upper: rgba(3, 50, 59, 0.7)
|
||||
lower: rgba(3, 50, 59)
|
||||
|
||||
minorItems:
|
||||
- collection: page
|
||||
subNavigation: 0
|
||||
@ -49,7 +307,14 @@ collections:
|
||||
- !include collections/medialib.yml
|
||||
- !include collections/backups.yml
|
||||
- !include collections/ssr.yml
|
||||
- !include collections/lighthouse.yml
|
||||
- !include collections/lighthouse-subpaths.yml
|
||||
|
||||
assets:
|
||||
- name: img
|
||||
path: img
|
||||
|
||||
jobs:
|
||||
- cron: "0 0 * * 1"
|
||||
type: javascript
|
||||
file: jobs/lighthouse.js
|
||||
|
@ -29,4 +29,5 @@ module.exports = {
|
||||
return -1
|
||||
},
|
||||
ssrPublishCheckCollections: ["page"],
|
||||
LIGHTHOUSE_TOKEN: "AIzaSyC0UxHp3-MpJiDL3ws7pEV6lj57bfIc7GQ",
|
||||
}
|
||||
|
@ -46,8 +46,103 @@ function clearSSRCache() {
|
||||
context.response.header("X-SSR-Cleared", info.removed)
|
||||
}
|
||||
|
||||
var { LIGHTHOUSE_TOKEN } = require("../config")
|
||||
function calculateAverageDynamically(dbObjs) {
|
||||
const sumObj = {}
|
||||
let count = 0
|
||||
|
||||
dbObjs.forEach((obj) => {
|
||||
accumulate(obj, sumObj)
|
||||
count++
|
||||
})
|
||||
|
||||
function accumulate(sourceObj, targetObj) {
|
||||
for (const key in sourceObj) {
|
||||
if (typeof sourceObj[key] === "number") {
|
||||
targetObj[key] = (targetObj[key] || 0) + sourceObj[key]
|
||||
} else if (typeof sourceObj[key] === "object" && sourceObj[key] !== null) {
|
||||
targetObj[key] = targetObj[key] || {}
|
||||
accumulate(sourceObj[key], targetObj[key])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function average(targetObj) {
|
||||
for (const key in targetObj) {
|
||||
if (typeof targetObj[key] === "number") {
|
||||
targetObj[key] = targetObj[key] / count
|
||||
} else if (typeof targetObj[key] === "object") {
|
||||
average(targetObj[key])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
average(sumObj)
|
||||
return sumObj
|
||||
}
|
||||
|
||||
function run(url) {
|
||||
const response = context.http
|
||||
.fetch(url, {
|
||||
timeout: 300,
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
})
|
||||
.body.json()
|
||||
// needs enough traffic to be collected
|
||||
const cruxMetrics = {
|
||||
"First Contentful Paint": response?.loadingExperience?.metrics?.FIRST_CONTENTFUL_PAINT_MS?.category,
|
||||
"First Input Delay": response?.loadingExperience?.metrics?.FIRST_INPUT_DELAY_MS?.category,
|
||||
}
|
||||
const lighthouse = response.lighthouseResult
|
||||
const lighthouseMetrics = {
|
||||
FCPS: lighthouse.audits["first-contentful-paint"].score * 100,
|
||||
FCPV: lighthouse.audits["first-contentful-paint"].numericValue / 1000,
|
||||
FMPS: lighthouse.audits["first-meaningful-paint"].score * 100,
|
||||
FMPV: lighthouse.audits["first-meaningful-paint"].numericValue / 1000,
|
||||
|
||||
SIS: lighthouse.audits["speed-index"].score * 100,
|
||||
SIV: lighthouse.audits["speed-index"].numericValue / 1000,
|
||||
TTIS: lighthouse.audits["interactive"].score * 100,
|
||||
TTIV: lighthouse.audits["interactive"].numericValue / 1000,
|
||||
|
||||
FPIDS: lighthouse.audits["max-potential-fid"].score * 100,
|
||||
FPIDV: lighthouse.audits["max-potential-fid"].numericValue / 1000,
|
||||
}
|
||||
|
||||
let dbObject = {
|
||||
cruxMetrics,
|
||||
lighthouseMetrics,
|
||||
performance: Math.round(lighthouse.categories.performance.score * 100),
|
||||
accessibility: Math.round(lighthouse.categories.accessibility.score * 100),
|
||||
bestPractices: Math.round(lighthouse.categories["best-practices"].score * 100),
|
||||
seo: Math.round(lighthouse.categories.seo.score * 100),
|
||||
}
|
||||
return dbObject
|
||||
}
|
||||
function setUpQuery(subPath = "/") {
|
||||
const api = "https://www.googleapis.com/pagespeedonline/v5/runPagespeed"
|
||||
let params = `category=performance&category=accessibility&category=best-practices&category=seo`
|
||||
|
||||
const parameters = {
|
||||
url: encodeURIComponent(`https://www.fontis.de/${subPath}`),
|
||||
key: LIGHTHOUSE_TOKEN,
|
||||
}
|
||||
|
||||
let query = `${api}?`
|
||||
for (let key in parameters) {
|
||||
query += `${key}=${parameters[key]}&`
|
||||
}
|
||||
query += params // Append other parameters without URL encoding
|
||||
return query
|
||||
}
|
||||
module.exports = {
|
||||
log,
|
||||
clearSSRCache,
|
||||
obj2str,
|
||||
run,
|
||||
setUpQuery,
|
||||
calculateAverageDynamically,
|
||||
}
|
||||
|
16
api/hooks/lighthouse/post_create.js
Normal file
16
api/hooks/lighthouse/post_create.js
Normal file
@ -0,0 +1,16 @@
|
||||
var { setUpQuery, calculateAverageDynamically, run } = require("../lib/utils")
|
||||
;(function () {
|
||||
let subPaths = context.db.find("lighthouseSubpath")
|
||||
let urls = []
|
||||
for (let i = 0; i < subPaths.length; i++) {
|
||||
urls.push(setUpQuery(subPaths[i].lighthouseSubpath))
|
||||
}
|
||||
let dbObjs = []
|
||||
urls.forEach((url) => {
|
||||
console.log("URL:", url)
|
||||
dbObjs.push(run(url))
|
||||
})
|
||||
let dbObject = calculateAverageDynamically(dbObjs)
|
||||
dbObject.analyzedPaths = [...subPaths].map((subPath) => subPath.lighthouseSubpath)
|
||||
return { data: dbObject }
|
||||
})()
|
17
api/jobs/lighthouse.js
Normal file
17
api/jobs/lighthouse.js
Normal file
@ -0,0 +1,17 @@
|
||||
var { setUpQuery, calculateAverageDynamically, run } = require("../hooks/lib/utils")
|
||||
;(function () {
|
||||
console.log("Running lighthouse job")
|
||||
let subPaths = context.db.find("lighthouseSubpath")
|
||||
let urls = []
|
||||
for (let i = 0; i < subPaths.length; i++) {
|
||||
urls.push(setUpQuery(subPaths[i].lighthouseSubpath))
|
||||
}
|
||||
let dbObjs = []
|
||||
urls.forEach((url) => {
|
||||
console.log("URL:", url)
|
||||
dbObjs.push(run(url))
|
||||
})
|
||||
let dbObject = calculateAverageDynamically(dbObjs)
|
||||
dbObject.analyzedPaths = [...subPaths].map((subPath) => subPath.lighthouseSubpath)
|
||||
context.db.create("lighthouse", dbObject)
|
||||
})()
|
Loading…
Reference in New Issue
Block a user