Skip to content

Instantly share code, notes, and snippets.

@polarnik
Last active June 30, 2025 13:43
Show Gist options
  • Select an option

  • Save polarnik/c7f34235e1e191245c17722eb3839424 to your computer and use it in GitHub Desktop.

Select an option

Save polarnik/c7f34235e1e191245c17722eb3839424 to your computer and use it in GitHub Desktop.
SiteSpeed custom wait function
function defaultPageCompleteCheck(waitTime) {
var end = window.performance.timing.loadEventEnd;
var start = window.performance.timing.navigationStart;
return (end > 0) && (performance.now() > end - start + waitTime);
}
function customWaitTime() {
return 2000;
}
function getRequestByRegEx(resources, regex) {
return resources.find(entry =>
entry.name.match(regex) &&
entry.initiatorType === "fetch"
);
}
function measureRequest(request, measureName) {
performance.measure(measureName, {
start: request.startTime,
duration: request.responseEnd - request.startTime
});
}
/**
* Calculate summary PerformanceResourceTiming by groups:
*
* Name-based groups are metrics by domains:
* - "youtrack" group: names started with "https://youtrack.jetbrains.com/"
* - "hub" group: names started with "https://hub.jetbrains.com/"
* - "other" group: other names
*
* Groups by fields:
* - contentType ("text/javascript", "image/png", etc.)
* - deliveryType ("cache", "")
* - initiatorType ("script", "link", "img", "fetch", etc.)
* - nextHopProtocol ("", "h2", "h3", etc.)
* - renderBlockingStatus ("blocking" or "non-blocking")
* - responseStatus (200, 400, 500, etc.)
*
* The key object has string fields:
* - domain_group
* - contentType
* - initiatorType
* - nextHopProtocol
* - renderBlockingStatus
* - responseStatus
*
* The function prepares the list of objects with all combinations of group values
* based on the PerformanceResourceTiming[] entries.
*
* The values are values
*
* @param resources : PerformanceResourceTiming[]
*/
function measureResources(resources) {
const youtrackRequests = resources.filter(resource => {
resource.name.startsWith("https://youtrack.jetbrains.com/")
});
const hubRequests = resources.filter(resource => {
resource.name.startsWith("https://hub.jetbrains.com/")
});
}
function waitRequest(request, name, waitTime) {
// If the request is found and completed
if (request && request.responseEnd > 0) {
// Check if enough time has passed since the request completed
const status = performance.now() > request.responseEnd + customWaitTime();
if(status) {
measureRequest(request, name);
return true;
} else
return defaultPageCompleteCheck(waitTime);
} else
return defaultPageCompleteCheck(waitTime);
}
function waitTwoRequests(request1, name1, request2, name2, waitTime) {
if (request1 && request2 &&
request1.responseEnd > 0 &&
request2.responseEnd > 0) {
// Check if enough time has passed since the last request completed
const lastRequestEnd = Math.max(request1.responseEnd, request2.responseEnd);
const status = performance.now() > lastRequestEnd + customWaitTime();
if(status) {
measureRequest(request1, name1);
measureRequest(request2, name2);
return true;
} else return defaultPageCompleteCheck(waitTime);
} else
return defaultPageCompleteCheck(waitTime);
}
/**
* Wait key HTTP Requests
* of the issue list page (https://youtrack.jetbrains.com/agiles/153-1739/current)
*
* The key request is
* - (POST) https://youtrack.jetbrains.com/api/issuesGetter?_top=-1&_topLinks=3&fields=attachments(id),fields(_type,hasStateMachine,id,isUpdatable,name,projectCustomField(_type,bundle(id),canBeEmpty,emptyFieldText,field(fieldType(isMultiValue,valueType),id,localizedName,name,ordinal),id,isEstimation,isPublic,isSpentTime,ordinal,size),value(_type,archived,avatarUrl,buildIntegration,buildLink,color(background,foreground,id),description,fullName,id,isResolved,localizedName,login,markdownText,minutes,name,presentation,ringId,text)),id,idReadable,isDraft,numberInProject,project(_type,archived,id,name,plugins(timeTrackingSettings(enabled,estimate(field(id,name),id),timeSpent(field(id,name),id))),projectType(id),ringId,shortName),reporter(_type,id,login,ringId),resolved,subtasks(id,issuesSize,unresolvedIssuesSize)
*
* The method measures duration of POST/api/issuesGetter
* @param resources
* @param waitTime
*/
function agile_Boards_Kotlin_Notebook_PageCompleteCheck(resources, waitTime) {
try {
const postRequest = getRequestByRegEx(resources, "/api/issuesGetter");
return waitRequest(postRequest, "GET/api/issuesGetter", waitTime);
// TODO: Wait by selectors
} catch (e) {
console.log(`agile_Boards_Kotlin_Notebook_PageCompleteCheck: exception: \n${e}`);
return true;
}
}
function issue_IDEA_PageCompleteCheck(waitTime) {
return issue_YouTrack_PageCompleteCheck(waitTime);
}
/**
* Wait key HTTP Requests
* of the issue list page (https://youtrack.jetbrains.com/issue/JT-32215)
*
* The key requests are:
* - (GET) https://youtrack.jetbrains.com/api/issues/JT-32215/links?_topLinks=25&fields=id,direction(),linkType(id,directed,aggregation,sourceToTarget,targetToSource,localizedSourceToTarget,localizedTargetToSource),issuesSize,trimmedIssues(id,idReadable,summary,reporter(id,ringId,login,name,email,isEmailVerified,guest,fullName,avatarUrl,online,banned,banBadge,canReadProfile,isLocked,userType(id),issueRelatedGroup(%40permittedGroups)),resolved,fields(value(id,minutes,presentation,isEstimation,isSpentTime,name,description,localizedName,isResolved,color(id,background,foreground),buildIntegration,buildLink,text,ringId,login,email,isEmailVerified,guest,fullName,avatarUrl,online,banned,banBadge,canReadProfile,isLocked,userType(id),issueRelatedGroup(%40permittedGroups),allUsersGroup,_type(),icon,teamForProject(name,shortName)),id,_type,hasStateMachine,isUpdatable,projectCustomField(_type,id,field(id,name,ordinal,aliases,localizedName,fieldType(id,presentation,isBundleType,valueType,isMultiValue)),bundle(id,_type),canBeEmpty,emptyFieldText,hasRunningJob,ordinal,isSpentTime,isEstimation,isPublic),visibleOnList,searchResults(id,textSearchResult(highlightRanges(%40textRange),textRange(%40textRange))),pausedTime),project(id,ringId,name,shortName,projectType(id),pinned,iconUrl,template,archived,hasArticles,isDemo,sourceTemplate,fieldsSorted,query,issuesUrl,restricted,leader(%40permittedUsers),creationTime,widgets(id,key,appId,description,appName,appTitle,name,collapsed,configurable,indexPath,extensionPoint,iconPath,appIconPath,appDarkIconPath,defaultHeight,defaultWidth,expectedHeight,expectedWidth,vendorName,vendorEmail,vendorUrl,marketplaceId),plugins(timeTrackingSettings(id,enabled),helpDeskSettings(id,defaultForm(uuid,title)),vcsIntegrationSettings(hasVcsIntegrations),grazie(disabled))),visibility(_type,implicitPermittedUsers(%40permittedUsers),permittedGroups(%40permittedGroups),permittedUsers(%40permittedUsers)),watchers(hasStar))%3B%40permittedUsers%3Aid,ringId,login,name,email,isEmailVerified,guest,fullName,avatarUrl,online,banned,banBadge,canReadProfile,isLocked,userType(id)%3B%40permittedGroups%3Aid,name,ringId,allUsersGroup,_type(),icon,teamForProject(name,shortName)%3B%40textRange%3AstartOffset,endOffset&customFields=Priority
* - (GET) https://youtrack.jetbrains.com/api/issues/JT-32215/activitiesPage?categories=IssueCreatedCategory,CommentsCategory&reverse=true&fields=activities(category(id()),added(id,ringId,login,name,email,isEmailVerified,guest,fullName,avatarUrl,online,banned,banBadge,canReadProfile,isLocked,userType(id),localizedName,numberInProject,project(name,shortName),author(id,ringId,avatarUrl,canReadProfile,isLocked,login,name,email,isEmailVerified,guest,fullName,online,banned,banBadge,userType(id)),created,updated,mimeType,url,size,visibility(%40visibility),imageDimensions(width,height),thumbnailURL,recognizedText,searchResults(%40searchResults),comment(%40comment),embeddedIntoDocument(id),embeddedIntoComments(id),idReadable,summary,resolved,creator(%40value1),text,type(%40value),duration(minutes,presentation),textPreview,date,usesMarkdown,attributes(id,name,value(%40value)),mentionedUsers(%40author),mentionedIssues(id,idReadable,summary,reporter(%40author),updater(%40author),resolved,updated,created,unauthenticatedReporter,fields(value(id,minutes,presentation,isEstimation,isSpentTime,name,description,localizedName,isResolved,color(%40color),buildIntegration,buildLink,text,ringId,login,email,isEmailVerified,guest,fullName,avatarUrl,online,banned,banBadge,canReadProfile,isLocked,userType(id),issueRelatedGroup(%40issueRelatedGroup),allUsersGroup,_type(),icon,teamForProject(name,shortName)),id,_type,hasStateMachine,isUpdatable,projectCustomField(_type,id,field(id,name,ordinal,aliases,localizedName,fieldType(id,presentation,isBundleType,valueType,isMultiValue)),bundle(id,_type),canBeEmpty,emptyFieldText,hasRunningJob,ordinal,isSpentTime,isEstimation,isPublic),visibleOnList,searchResults(id,textSearchResult(highlightRanges(%40highlightRanges),textRange(%40highlightRanges))),pausedTime),project(%40project),visibility(%40visibility),tags(%40tags),votes,voters(hasVote),watchers(hasStar),usersTyping(timestamp,user(%40value1)),canUndoComment),mentionedArticles(id,idReadable,reporter(%40value1),summary,project(%40project),parentArticle(idReadable),ordinal,visibility(%40visibility),hasUnpublishedChanges,hasChildren,tags(%40tags),hasStar),files,commands(errorText,hasError,start,end),noHubUserReason(_type,id),noUserReason(_type,id),pullRequest(_type,author(%40value1),date,fetched,processor(id,_type),files,id,branch,idExternal,idReadable,noHubUserReason(_type,id),noUserReason(_type,id),title,text,url),urls,processors(id,_type),state(_type,id),version,deleted,pinned,attachments(id,name,author(%40author1),created,updated,mimeType,url,size,visibility(%40visibility),imageDimensions(width,height),thumbnailURL,recognizedText,searchResults(%40searchResults),comment(%40comment),embeddedIntoDocument(id),embeddedIntoComments(id)),reactions(id,reaction,author(%40value1)),reactionOrder,hasEmail,canUpdateVisibility,suspiciousEmail,issue(id,project(id)),markdownEmbeddings(key,settings,widget(id)),reaction,presentation),removed(id,ringId,login,name,email,isEmailVerified,guest,fullName,avatarUrl,online,banned,banBadge,canReadProfile,isLocked,userType(id),localizedName,numberInProject,project(name,shortName),author(%40author1),created,updated,mimeType,url,size,visibility(%40visibility),imageDimensions(width,height),thumbnailURL,recognizedText,searchResults(%40searchResults),comment(%40comment),embeddedIntoDocument(id),embeddedIntoComments(id),idReadable,summary,resolved,presentation),issue(description,customFields(name,projectCustomField(emptyFieldText,field(id,localizedName,name,fieldType(%40fieldType))),value(%40value1))),id,author(%40author),authorGroup(id),timestamp,field(id,presentation,customField(fieldType(%40fieldType))),target(id,_type),targetMember,type,pseudo,emptyFieldText,sprintsDisabled),hasBefore,hasAfter,beforeCursor,afterCursor,cursor%3B%40project%3Aid,ringId,name,shortName,projectType(id),pinned,iconUrl,template,archived,hasArticles,isDemo,sourceTemplate,fieldsSorted,query,issuesUrl,restricted,leader(%40value1),creationTime,widgets(id,key,appId,description,appName,appTitle,name,collapsed,configurable,indexPath,extensionPoint,iconPath,appIconPath,appDarkIconPath,defaultHeight,defaultWidth,expectedHeight,expectedWidth,vendorName,vendorEmail,vendorUrl,marketplaceId),plugins(timeTrackingSettings(id,enabled),helpDeskSettings(id,defaultForm(uuid,title)),vcsIntegrationSettings(hasVcsIntegrations),grazie(disabled))%3B%40comment%3Aid,visibility(%40visibility)%3B%40visibility%3A_type,implicitPermittedUsers(%40value1),permittedGroups(%40issueRelatedGroup),permittedUsers(%40value1)%3B%40author%3Aid,ringId,login,name,email,isEmailVerified,guest,fullName,avatarUrl,online,banned,banBadge,canReadProfile,isLocked,userType(id),issueRelatedGroup(%40issueRelatedGroup)%3B%40value%3Aid,name,autoAttach,description,hasRunningJobs,color(%40color),attributes(id,timeTrackingSettings(id,project(id)))%3B%40value1%3Aid,ringId,login,name,email,isEmailVerified,guest,fullName,avatarUrl,online,banned,banBadge,canReadProfile,isLocked,userType(id)%3B%40issueRelatedGroup%3Aid,name,ringId,allUsersGroup,_type(),icon,teamForProject(name,shortName)%3B%40tags%3Aid,name,color(%40color),isDeletable,isUpdatable,isUsable%3B%40searchResults%3AtextSearchResult(highlightRanges(%40highlightRanges))%3B%40author1%3Aid,ringId,avatarUrl,canReadProfile,isLocked,login,name%3B%40color%3Aid,background,foreground%3B%40fieldType%3AvalueType,isMultiValue%3B%40highlightRanges%3AstartOffset,endOffset
*
* The method measures duration of GET/api/issues/{ID}/links and GET/api/issues/{ID}/activitiesPage
* @param waitTime
*/
function issue_YouTrack_PageCompleteCheck(waitTime) {
try {
// Get all resource timing entries
const resources = performance.getEntriesByType("resource");
const linksRequest = getRequestByRegEx(resources, "/api/issues/[^/]+/links");
const activitiesRequest = getRequestByRegEx(resources, "/api/issues/[^/]+/activitiesPage");
return waitTwoRequests(linksRequest, "GET/api/issues/{ID}/links",
activitiesRequest, "GET/api/issues/{ID}/activitiesPage", waitTime);
} catch (e) {
console.log(`issue_YouTrack_PageCompleteCheck: exception: \n${e}`);
return true;
}
}
/**
* Wait key HTTP Requests
* of the issue list page (https://youtrack.jetbrains.com/issues)
*
* The keys request is:
* - (POST) https://youtrack.jetbrains.com/api/issuesGetter?_top=-1&_skip=0&referringQuery=&fields=id,idReadable,summary,reporter(%40updater),updater(%40updater),resolved,updated,created,unauthenticatedReporter,fields(value(id,minutes,presentation,isEstimation,isSpentTime,name,description,localizedName,isResolved,color(%40color),buildIntegration,buildLink,text,ringId,login,email,isEmailVerified,guest,fullName,avatarUrl,online,banned,banBadge,canReadProfile,isLocked,userType(id),issueRelatedGroup(%40permittedGroups),allUsersGroup,_type(),icon,teamForProject(name,shortName)),id,_type,hasStateMachine,isUpdatable,projectCustomField(_type,id,field(id,name,ordinal,aliases,localizedName,fieldType(id,presentation,isBundleType,valueType,isMultiValue)),bundle(id,_type),canBeEmpty,emptyFieldText,hasRunningJob,ordinal,isSpentTime,isEstimation,isPublic),visibleOnList,searchResults(id,textSearchResult(highlightRanges(%40textRange),textRange(%40textRange))),pausedTime),project(id,ringId,name,shortName,projectType(id),pinned,iconUrl,template,archived,hasArticles,isDemo,sourceTemplate,fieldsSorted,query,issuesUrl,restricted,leader(%40user),creationTime,widgets(id,key,appId,description,appName,appTitle,name,collapsed,configurable,indexPath,extensionPoint,iconPath,appIconPath,appDarkIconPath,defaultHeight,defaultWidth,expectedHeight,expectedWidth,vendorName,vendorEmail,vendorUrl,marketplaceId),plugins(timeTrackingSettings(id,enabled),helpDeskSettings(id,defaultForm(uuid,title)),vcsIntegrationSettings(hasVcsIntegrations),grazie(disabled))),visibility(_type,implicitPermittedUsers(%40user),permittedGroups(%40permittedGroups),permittedUsers(%40user)),tags(id,name,color(%40color),isDeletable,isUpdatable,isUsable),votes,voters(hasVote),watchers(hasStar),usersTyping(timestamp,user(%40user)),canUndoComment%3B%40updater%3Aid,ringId,login,name,email,isEmailVerified,guest,fullName,avatarUrl,online,banned,banBadge,canReadProfile,isLocked,userType(id),issueRelatedGroup(%40permittedGroups)%3B%40user%3Aid,ringId,login,name,email,isEmailVerified,guest,fullName,avatarUrl,online,banned,banBadge,canReadProfile,isLocked,userType(id)%3B%40permittedGroups%3Aid,name,ringId,allUsersGroup,_type(),icon,teamForProject(name,shortName)%3B%40color%3Aid,background,foreground%3B%40textRange%3AstartOffset,endOffset&fieldsVisibleOnList=false
*
* The method measures the durations of the (POST) /api/issuesGetter request and response.
* @param waitTime
*/
function issues_PageCompleteCheck(waitTime) {
try {
// Get all resource timing entries
// https://developer.mozilla.org/en-US/docs/Web/API/Performance/getEntriesByType
// https://developer.mozilla.org/en-US/docs/Web/API/PerformanceResourceTiming
const resources = performance.getEntriesByType("resource");
const postRequest = getRequestByRegEx(resources, "/api/issuesGetter[?]");
return waitRequest(postRequest, "POST/api/issuesGetter", waitTime);
} catch (e) {
console.log(`issues_PageCompleteCheck: exception: \n${e}`);
return true;
}
}
function project_IntelliJ_IDEA_PageCompleteCheck(waitTime) {
return project_YouTrack_PageCompleteCheck(waitTime);
}
/**
* Wait key HTTP Requests
* of the project page YouTrack (https://youtrack.jetbrains.com/projects/22-1)
*
* The key requests are
* - (GET) /api/issueFolders/22-1/sortOrder/issues?fields=id,idReadable,summary,resolved,fields(id,value(id,name,localizedName,login,avatarUrl,name,presentation,minutes,color(id,foreground,background)),projectCustomField(id,bundle(id),field(id,name,localizedName,fieldType(id,valueType))))&query=%23Unresolved%20sort%20by%3A%20votes%20&$top=50&$skip=0
* - (POST) /api/issuesGetter/count?fields=count
*
* The method measures the durations of the first (GET) /api/issueFolders/{ID}/sortOrder/issues request and response.
* The method waits the second (POST) /api/issuesGetter/count?fields=count response
* @param waitTime
*/
function project_YouTrack_PageCompleteCheck(waitTime) {
try {
const resources = performance.getEntriesByType("resource");
const getRequest = getRequestByRegEx(resources, "/api/issueFolders/[^/]+/sortOrder/issues");
return waitRequest(getRequest, "GET/api/issueFolders/{ID}/sortOrder/issues", waitTime);
} catch (e) {
console.log(`project_YouTrack_PageCompleteCheck: exception: \n${e}`);
return true;
}
}
function addCusomMetrics() {
try {
const entries = performance.getEntriesByType("navigation");
const entry = entries[0];
performance.measure(`Redirect`,
{
start: entry.startTime,
duration: entry.workerStart - entry.startTime,
}
);
performance.measure(`ServiceWorker`,
{
start: entry.workerStart,
duration: entry.domainLookupStart - entry.workerStart,
}
);
performance.measure(`DNS`,
{
start: entry.domainLookupStart,
duration: entry.domainLookupEnd - entry.domainLookupStart,
}
);
performance.measure(`TCP`,
{
start: entry.domainLookupEnd,
duration: entry.secureConnectionStart - entry.domainLookupEnd,
}
);
performance.measure(`TLS`,
{
start: entry.secureConnectionStart,
duration: entry.requestStart - entry.secureConnectionStart,
}
);
performance.measure(`Request`,
{
start: entry.requestStart,
duration: entry.finalResponseHeadersStart - entry.requestStart,
}
);
performance.measure(`Response`,
{
start: entry.finalResponseHeadersStart,
duration: entry.responseEnd - entry.finalResponseHeadersStart,
}
);
performance.measure(`Processing`,
{
start: entry.responseEnd,
duration: entry.loadEventStart - entry.responseEnd,
}
);
performance.measure(`Load`,
{
start: entry.loadEventStart,
duration: entry.loadEventEnd - entry.loadEventStart,
}
);
} catch (e) {
console.log(`defaultPageCompleteCheck: exception: \n${(e)}`)
}
}
function get_status(waitTime) {
let status = false;
try {
const entries = performance.getEntriesByType("navigation");
if(entries && entries.length > 0) {
const entry = entries[0];
// Get all resource timing entries
const resources = performance.getEntriesByType("resource");
if (entry.name.includes("test=PreUrl")) {
status = defaultPageCompleteCheck(waitTime);
} else if (entry.name.includes("youtrack.jetbrains.com")) {
if(entry.name.includes("/issue/"))
status = issue_YouTrack_PageCompleteCheck(resources, waitTime);
else if(entry.name.includes("/issues"))
status = issues_PageCompleteCheck(resources, waitTime);
else if(entry.name.includes("/agiles/"))
status = agile_Boards_Kotlin_Notebook_PageCompleteCheck(resources, waitTime);
else if(entry.name.includes("/projects/"))
status = project_YouTrack_PageCompleteCheck(resources, waitTime)
else
status = defaultPageCompleteCheck(waitTime)
}
} else {
status = false;
}
} catch (e) {
console.log(`defaultPageCompleteCheck: exception: \n${(e)}`);
status = true;
}
return status;
}
return (function(waitTime) {
if(get_status(waitTime)) {
addCusomMetrics();
return true;
} else {
return false;
}
})(arguments[arguments.length - 1]);
function getNamePattern(name) {
let group = "";
if(name.includes("https://youtrack.jetbrains.com/")) {
group = "youtrack"
} else if(name.includes("https://hub.jetbrains.com/")) {
group = "hub"
} else {
group = "other"
}
const parts = name.split("/");
if(group == "other") {
return group
} else {
if(parts.length >= 3) {
if(parts[3].includes("?") || parts[3].includes("#"))
return group + "/" + "other";
else
return group + "/" + parts[3];
} else {
return group
}
}
}
/**
* @param entry : PerformanceResourceTiming
* @param name : String
* @param value : number
*/
function putMetric(metrics, entry, name, value) {
console.log("putMetric");
console.log(`metrics 1:\n`);
JSON.stringify(metrics);
console.log(`name:\n`);
JSON.stringify(name)
console.log(`value:\n`);
JSON.stringify(value)
const pattern = getNamePattern(entry.name);
let deliveryType = "non-cache";
if(entry.deliveryType) {
if(entry.deliveryType === "") {
deliveryType = "non-cache"
} else {
deliveryType = entry.deliveryType;
}
} else {
if(entry.decodedBodySize > 0 && entry.transferSize === 0) {
deliveryType = "cache"
} else {
deliveryType = "non-cache"
}
}
if(!(metrics[name]))
metrics[name] = {};
if(!(metrics[name][deliveryType]))
metrics[name][deliveryType] = {};
if(!(metrics[name][deliveryType][pattern]))
metrics[name][deliveryType][pattern] = 0.0;
if(!(metrics[name][deliveryType]["ALL"]))
metrics[name][deliveryType]["ALL"] = 0.0;
if(!(metrics[name]["ALL"]))
metrics[name]["ALL"] = {};
if(!(metrics[name]["ALL"]["ALL"]))
metrics[name]["ALL"]["ALL"] = 0.0;
metrics[name][deliveryType][pattern] += Math.max(value, 0.0);
metrics[name][deliveryType]["ALL"] += Math.max(value, 0.0);
metrics[name]["ALL"]["ALL"] += Math.max(value, 0.0);
console.log(`metrics 2:\n ${JSON.stringify(metrics)}`);
return metrics;
}
function createPerformanceMeasurements(metrics) {
console.log("createPerformanceMeasurements");
console.log(`metrics:\n`);
JSON.stringify(metrics);
for(const metricName of Object.keys(metrics)) {
for(const deliveryType of Object.keys(metrics[metricName])) {
for(const pattern of Object.keys(metrics[metricName][deliveryType])) {
performance.measure(`custom.${metricName}.${deliveryType}.${pattern}`,
{
start: 0,
duration: metrics[metricName][deliveryType][pattern],
}
);
}
}
}
}
function addCusomMetrics_total() {
console.log("addCusomMetrics_total");
try {
const entries = performance.getEntriesByType("resource");
console.log(`addCusomMetrics_total: entries :\n`);
JSON.stringify(entries);
let metrics = {};
for(const entry of entries) {
if(entry.entryType === "resource") {
metrics = putMetric(metrics, entry, "Count", 1);
// https://developer.mozilla.org/en-US/docs/Web/API/PerformanceResourceTiming#typical_resource_timing_metrics
// Measuring redirection time (redirectEnd - redirectStart)
// metrics = putMetric(metrics, entry, "Redirect", entry.redirectEnd - entry.redirectStart);
// // !!!!! Measuring ServiceWorker processing time (fetchStart - workerStart)
// metrics = putMetric(metrics, entry, "ServiceWorker", entry.fetchStart - entry.workerStart);
// // Measuring DNS lookup time (domainLookupEnd - domainLookupStart)
// metrics = putMetric(metrics, entry, "DNS", entry.domainLookupEnd - entry.domainLookupStart);
// // Measuring TCP handshake time (connectEnd - connectStart)
// metrics = putMetric(metrics, entry, "TCP_handshake", entry.connectEnd - entry.connectStart);
// // Measuring interim request time (firstInterimResponseStart - finalResponseHeadersStart)
// metrics = putMetric(metrics, entry, "Interim_Request", entry.firstInterimResponseStart - entry.finalResponseHeadersStart);
//
// // Zero-safe
// metrics = putMetric(metrics, entry, "TCP", entry.secureConnectionStart - entry.domainLookupEnd);
// // Zero-safe, Measuring TLS negotiation time (requestStart - secureConnectionStart)
// metrics = putMetric(metrics, entry, "TLS", entry.requestStart - entry.secureConnectionStart);
// // Zero-safe
// metrics = putMetric(metrics, entry, "Request", entry.responseStart - entry.requestStart);
// // !!!!!
// metrics = putMetric(metrics, entry, "Response", entry.responseEnd - entry.responseStart);
// Measuring time to fetch (without redirects) (responseEnd - fetchStart)
metrics = putMetric(metrics, entry, "TimeToFetch", entry.responseEnd - entry.fetchStart);
metrics = putMetric(metrics, entry, "duration", entry.duration);
// metrics = putMetric(metrics, entry, "transferSize", entry.transferSize);
// metrics = putMetric(metrics, entry, "decodedBodySize", entry.decodedBodySize);
// metrics = putMetric(metrics, entry, "encodedBodySize", entry.encodedBodySize);
}
/**
* connectEnd: 0
* connectStart: 0
* decodedBodySize: 0
* domainLookupEnd: 0
* domainLookupStart: 0
* encodedBodySize: 0
* redirectEnd: 0
* redirectStart: 0
* requestStart: 0
* responseStart: 0
* responseStatus: 0
* secureConnectionStart: 0
* transferSize: 0
* workerStart: 0
*
* duration: 78
* startTime: 2632
* responseEnd: 2710
* fetchStart: 2632
*/
}
createPerformanceMeasurements(metrics);
} catch (e) {
console.log(`addCusomMetrics_total: exception: \n${(e)}`)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment