Skip to content

Commit

Permalink
perfmap
Browse files Browse the repository at this point in the history
  • Loading branch information
zeman committed Oct 5, 2014
1 parent 5bd4b38 commit 98940f5
Show file tree
Hide file tree
Showing 2 changed files with 158 additions and 2 deletions.
35 changes: 33 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,33 @@
perfmap
=======
#PerfMap - In browser front-end performance heatmap

A bookmarklet to create a front-end performance heatmap of resources loaded in the browser using the Resource Timing API.

Just add the bookmarklet below to your bookmarks bar.

```
javascript:(function(){var el=document.createElement('script');el.type='text/javascript';el.src='//zeman.github.io/perfmap/bookmarklet/perfmap.js';document.getElementsByTagName('body')[0].appendChild(el);})();
```

##Background

Concived as part of a set of [data visualization experiments](http://lab.speedcurve.com) which re-imagining the front-end performance waterfall chart by Mark Zeman from [SpeedCurve](http://speedcurve.com) presented at Velocity New York 2014.

##Works In

Chrome

##To Do

- Deal with fixed position elements (calling all front-end ninjas, send me your thoughts on how best to do this)
- Hover state with more detail on the timimgs of an individual resource
- Add strip across top of browser with page level timings and browser events
- User timing, pull out and highlight any elements with associated user timing events
- Expand top nav to show full waterfall chart of all resources. Combine with Andy's waterfall bookmarklet?

##Change Log

2014-10-06 First push of rough proof of concept

##Thanks

Big thanks to Steve Souders who was inspired enough to whip up the intial code structure while simultaneously participating at WebPerfDays NY.
125 changes: 125 additions & 0 deletions perfmap.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
var gZeroLeft = 0;
var gZeroTop = 0;
var gWinWidth = window.innerWidth || document.documentElement.clientWidth;

function markElements(type) {
var aElems = document.getElementsByTagName(type);
for ( var i=0, len = aElems.length; i < len; i++ ) {
var elem = aElems[i];
if ( "link" == type && "stylesheet" != elem.rel ) {
continue;
}
var url = elem.src || elem.href;
if ( url ) {
var entry = performance.getEntriesByName(url)[0];
if ( entry ) {
var xy = getCumulativeOffset(elem);
var wh = elem.getBoundingClientRect();
var width = wh.width;
var height = wh.height;
if(width > 20){
if(height > 20){
placeMarker(xy, width, height, type, entry);
}
}
}
}
}
}

function placeMarker(xy, width, height, type, entry) {

var heat = entry.responseEnd / loaded;
if(width < 170){
var padding = 12;
var size = 12;
}else{
var padding = 9;
var size = 18;
}
var marker = document.createElement("div");
marker.style.cssText = "position: absolute; box-sizing: border-box; color: #000; padding-left:10px; padding-right:10px; line-height:14px; font-size: " + size + "px; font-weight:800; text-align:center; opacity: 0.85; " + heatmap(heat) + " top: " + xy.top + "px; left: " + xy.left + "px; width: " + width + "px; height:" + height + "px; padding-top:" + ((height/2)-padding) + "px; z-index: 4000;";
marker.innerHTML = parseInt(entry.responseEnd) + "ms (" + parseInt(entry.duration) + "ms)";
document.body.appendChild(marker);
if ( 0 == xy.top ) {
gZeroLeft += marker.offsetWidth + 10;
if ( gZeroLeft + 100 > gWinWidth ) {
gZeroTop += 30;
gZeroLeft = 0;
}
}
}


function prettyType(type) {
return ( "link" == type ? "stylesheet" : type );
}

function heatmap(heat) {
if ( heat < 0.125 ) {
return "background: #d73c4c;"
}
else if ( heat < 0.25 ) {
return "background: #f66d3a;"
}
else if ( heat < 0.375 ) {
return "background: #ffaf59;"
}
else if ( heat < 0.5 ) {
return "background: #ffe185;"
}
else if ( heat < 0.625 ) {
return "background: #e6f693;"
}
else if ( heat < 0.75 ) {
return "background: #aadea2;"
}
else if ( heat < 0.875 ) {
return "background: #62c3a5;"
}else{
return "background: #2c87bf;"
}
}

function typeCss(type) {
if ( "img" == type ) {
return "background: #C00;"
}
else if ( "script" == type ) {
return "background: #0C0;"
}
else if ( "link" == type ) {
return "background: #00C;"
}
}

function getCumulativeOffset(obj) {
var left, top, width;
left = top = 0;
if (obj.offsetParent) {
do {
left += obj.offsetLeft;
top += obj.offsetTop;
width += obj.offsetWidth;
//console.log(obj);
} while (obj = obj.offsetParent);
}

if ( 0 == top ) {
left += gZeroLeft;
top += gZeroTop;
}

return {
left: left,
top: top,
width: width,
};
}

// get full page load time to calculate heatmap max
var loaded = performance.timing.loadEventEnd - performance.timing.navigationStart;

markElements("img");
//markElements("script");
//markElements("link");

0 comments on commit 98940f5

Please sign in to comment.