Skip to content

Commit

Permalink
Merge branch 'master' of github.com:nicjansma/perfbar.js
Browse files Browse the repository at this point in the history
  • Loading branch information
nicjansma committed Oct 6, 2017
2 parents c0c7db1 + 148448c commit 9a7e87c
Show file tree
Hide file tree
Showing 2 changed files with 215 additions and 25 deletions.
125 changes: 100 additions & 25 deletions perfbar.user.js
Original file line number Diff line number Diff line change
Expand Up @@ -946,11 +946,102 @@ var UW = unsafeWindow;
createCookie(cookieName, 'true', 1)
}

function toggleShowCacheStatus() {
setState("cacheStatus", getState("cacheStatus") ? false : true);
// cacheStatus stuff
let sheet
function toggleShowCacheStatus(e) {
sheet = sheet || (function () {
var style = document.createElement('style');
style.appendChild(document.createTextNode(''));
document.head.appendChild(style);
return style.sheet;
})()

if (sheet.cssRules.length > 0) {
setState("cacheStatus", false);
while (sheet.cssRules.length > 0) {
sheet.deleteRule(0)
}
} else {
setState("cacheStatus", true);
insertRule('.PerfBar-image { outline: 3px solid; outline-offset: -3px; opacity: 0.5; }');
insertRule('.PerfBar-browser { outline-color: green }');
insertRule('.PerfBar-edge { outline-color: blue }');
insertRule('.PerfBar-origin { outline-color: red }');
}
}

function insertRule(ruleText) {
sheet.insertRule(ruleText, sheet.cssRules.length);
}

function readCookie(name) {
function identifyCacheOnImage(img) {
if (img.complete === false) {
img.addEventListener('load', function () {
identifyCacheOnImage(img)
})
return
}

if (!img.ownerDocument) {
setTimeout(function() {
identifyCacheOnImage(img)
}, 10)
return
}

var entry = img.ownerDocument.defaultView.performance.getEntriesByName(img.src)[0]
if (!entry) {
return;
}

if (toolBar.cachedInBrowser(entry)) {
img.className = 'PerfBar-image PerfBar-browser'
} else if (toolBar.cachedAtEdge(entry)) {
img.className = 'PerfBar-image PerfBar-edge'
} else {
img.className = 'PerfBar-image PerfBar-origin'
}
}

function checkForImages(root) {
if (!root.getElementsByTagName) return;
Array.prototype.forEach.call(root.getElementsByTagName('img'), function (img) {
identifyCacheOnImage(img)
})
}
checkForImages(document)

;(function initMutationObserver(window) {
let target
try {
target = window.document
} catch (e) {
//cross-origin
}
if (!target) return

new MutationObserver(function (mutations) {
mutations.forEach(function (mutation) {
if (mutation.type === 'childList') {
mutation.addedNodes.forEach(function (addedNode) {
checkForImages(addedNode)
if (addedNode.tagName) {
if (addedNode.tagName.toLowerCase() === 'img') {
identifyCacheOnImage(this)
}
if (addedNode.tagName.toLowerCase() === 'iframe') {
addedNode.addEventListener('load', function () {
initMutationObserver(this.contentWindow)
})
}
}
})
}
})
}).observe(target, {attributes: true, childList: true, characterData: true, subtree: true});
})(window)

function readCookie(name) {
var nameEQ = name + "=";
var ca = document.cookie.split(';');
for (var i = 0; i < ca.length; i++) {
Expand Down Expand Up @@ -1042,7 +1133,12 @@ var UW = unsafeWindow;
toggleJank();
}

return {
if (getState("cacheStatus")) {
toggleShowCacheStatus();
}


return {
init: init
};
})(toolBar));
Expand Down Expand Up @@ -1091,27 +1187,6 @@ var UW = unsafeWindow;
// PerfBar Options
//

//
// Shows Cache Status overlay
//
if (getState("cacheStatus")) {
window.addEventListener("load", function () {
Array.prototype.forEach.call(document.getElementsByTagName('img'), function (img) {
var entry = performance.getEntriesByName(img.src)[0]
if (!entry) return

img.style.opacity = '0.5'
if (toolBar.cachedInBrowser(entry)) {
img.style.border = 'solid 3px green'
} else if (toolBar.cachedAtEdge(entry)) {
img.style.border = 'solid 3px blue'
} else {
img.style.border = 'solid 3px red'
}
})
})
}

//
// Delays Framework initialization
//
Expand Down
115 changes: 115 additions & 0 deletions server-timing-plugin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
// ==UserScript==
// @name server-timing-plugin.js
// @version 0.1
// @grant none
// @run-at document-start
// @include *
// @noframes
// ==/UserScript==

(function() {

(function () {
BOOMR = window.BOOMR || {};
BOOMR.plugins = BOOMR.plugins || {};
if (BOOMR.plugins.ServerTiming) {
return;
}

var impl = {
calculated: false
};

BOOMR.plugins.ServerTiming = {
init: function (config) {
return this;
},

is_complete: function () {
if (!impl.calculated) {
impl.calculated = true

BOOMR.plugins.ServerTiming.edge = calculateEdgeTime(performance.getEntriesByType('navigation')[0])
BOOMR.plugins.ServerTiming.edge_res = performance.getEntriesByType('resource').reduce(function (acc, entry) {
acc += calculateEdgeTime(entry)
return acc
}, 0)

let resourceCount = 0, browser_count = 0, edge_count = 0, origin_count = 0, offloadBytes = 0, im_bytes = 0
performance.getEntriesByType('resource').forEach(function (entry) {
resourceCount++
if (cachedInBrowser(entry)) {
browser_count++
} else {
const bytes = (entry.transferSize || entry.encodedBodySize)
const disk = findEntry(entry.serverTiming, 'disk')
if (disk) {
const orig = Number(disk.description)
if (orig > bytes) {
im_bytes += orig - bytes
}
}
if (cachedAtEdge(entry)) {
edge_count++
offloadBytes += bytes
} else {
origin_count++
}
}
})
BOOMR.plugins.ServerTiming.from = {
browser: browser_count / resourceCount,
edge: edge_count / resourceCount,
origin: origin_count / resourceCount,
}

if (origin_count) {
BOOMR.plugins.ServerTiming.offload_percent = edge_count / (edge_count + origin_count)
}
BOOMR.plugins.ServerTiming.offload_bytes = offloadBytes

BOOMR.plugins.ServerTiming.im_bytes = im_bytes

console.warn('BOOMR.plugins.ServerTiming', BOOMR.plugins.ServerTiming)
}
return true
}
};

function calculateEdgeTime({serverTiming}) {
let duration = 0
const cret = findEntry(serverTiming, 'cret')
if (cret) duration += (cret.duration || cret.value)
const ctt = findEntry(serverTiming, 'ctt')
if (ctt) duration += (ctt.duration || ctt.value)
return duration
}

function findEntry(serverTiming, entryName) {
return serverTiming.find(function ({name, metric}) {
return name === entryName || metric === entryName
})
}

function hasPermissiveTAO(rt) {
return rt.encodedBodySize > 0
}

function cachedInBrowser(rt) {
return hasPermissiveTAO(rt)
? rt.transferSize === 0
: rt.duration < 30
}

function cachedAtEdge(rt) {
let origin
const entry = findEntry(rt.serverTiming, 'origin')
if (entry) {
origin = entry.description === 'true'
}
return origin === false
}

}());

})()

0 comments on commit 9a7e87c

Please sign in to comment.