-
Notifications
You must be signed in to change notification settings - Fork 0
/
page-load.go
74 lines (66 loc) · 3.1 KB
/
page-load.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
package main
import (
"fmt"
"strconv"
"github.com/go-rod/rod"
"github.com/tidwall/gjson"
)
//Gets First Contentful Paint information for a given page and returns the value as a string
func getFirstContentfulPaint(page *rod.Page) string {
firstPaint, err := page.Eval("JSON.stringify(performance.getEntriesByType('paint'))")
explain(err)
fcp := gjson.Get(firstPaint.Value.String(), "0.startTime").Uint()
return strconv.FormatUint(fcp, 10)
}
//Gets Time to Interactive information for a given page and returns the value as a string
func getTimeToInteractive(page *rod.Page) string {
metrics, err := page.Eval("JSON.stringify(performance.toJSON())")
explain(err)
loadEventEnd := gjson.Get(metrics.Value.String(), "timing.loadEventEnd").Uint()
navigationStart := gjson.Get(metrics.Value.String(), "timing.navigationStart").Uint()
timeToInteractive := loadEventEnd - navigationStart
return strconv.FormatUint(timeToInteractive, 10)
}
//Gets Total Blocking Time information for a given page and returns the value as a string
func getTotalBlockingTime(firstContentfulPaint string, timeToInteractive string) string {
fcp, err := strconv.Atoi(firstContentfulPaint)
explain(err)
tti, err := strconv.Atoi(timeToInteractive)
explain(err)
return strconv.Itoa(tti - fcp)
}
////Gets Time to First Byte information for a given page and returns the value as a string
func getTimeToFirstByte(page *rod.Page) string {
metrics, err := page.Eval("JSON.stringify(performance.toJSON())")
explain(err)
requestStart := gjson.Get(metrics.Value.String(), "timing.requestStart").Uint()
responseStart := gjson.Get(metrics.Value.String(), "timing.responseStart").Uint()
timeToFirstByte := responseStart - requestStart
return strconv.FormatUint(timeToFirstByte, 10)
}
/**
* Calls functions to gather four different important performance page laod time metrics
* Formats the metrics into an easily readable multiline string and returns it
*/
func getPageLoadTimings(page *rod.Page) string {
fcp := getFirstContentfulPaint(page)
tti := getTimeToInteractive(page)
tbt := getTotalBlockingTime(fcp, tti)
ttfb := getTimeToFirstByte(page)
pageLoadTimings := fmt.Sprintf(`
First Paint: %vms
Page Interactive: %vms
Total Blocking Time: %vms
Time to First Byte: %vms
`, fcp, tti, tbt, ttfb)
return pageLoadTimings
}
/**
* Calls function to gather page laod timing metrics
* Creates a div to display these metrics as an overlay on the page
*/
func getPageLoadTimingsOverlay(page *rod.Page) {
pageLoadTimings := getPageLoadTimings(page)
inlineJS := `(pageLoadTimings) => {let existing = document.getElementById('PageLoadTimings');if(existing === null) {let body = document.querySelector('body');let div = document.createElement('div');div.setAttribute('id', 'PageLoadTimings');div.setAttribute('style', 'font-family:Segoe UI;color:#00FFFF;position:fixed;background:rgba(0,0,0,.8);z-index:99000000000;left:0px;bottom:0px;width:300px;height:100px;pointer-events:none;font-size:small;white-space:pre-wrap;');div.textContent = pageLoadTimings;body.appendChild(div);} else {existing.textContent = pageLoadTimings;}}`
page.MustEval(inlineJS, pageLoadTimings)
}