With Web App Performance Monitoring
Maor Frankel
Real Users!
background: #story;
Real Time User Monitoring (RUM)
Real Data, Real Users, Real Time
Leverage our existing systems
http://tinyurl.com/y4y4b64j
@Mr_Frankel
@MrFrank
"This is the time it takes the page to load. It begins when the navigation begins and ends when the webpage has completed loading in the user’s browser"
pageLoadTime = loadEventStart - navigationStart
"The High Resolution Time standard defines a Performance interface that supports client-side latency measurements within applications. "
const then = performance.now();
console.log(then) // 3157728.1249999944
(function doSomething() {
for(let i=0 ; i < 10000 ; i++){
///DO SOMETHING...
}
})()
const now = performance.now();
console.log(now) // 3158311.935000005
console.log((now - then)) // 583.8100000107661Good
performance.mark('doSomething-start')
function doSomething() {
for(let i=0 ; i < 10000 ; i++){
///DO SOMETHING...
}
}
performance.mark('doSomething-end')
performance.measure('doSomething', 'doSomething-start', 'doSomething-end')
let marks = performance.getEntriesByName('doSomething', 'mark')
console.info(`${marks[1].startTime - marks[0].startTime}`) // 583.8100000107661Better
<!doctype html>
<html>
<head lang="en">
<meta charset="UTF-8">
<base href='/'/>
<title>Outbrain - Amplify</title>
<script>
performance.mark('page-load-start');
</script><script>performance.mark('scripts-start');</script>
<script src="https://u.outbrain.com/static/vendor.87b3e412.js"></script>
<script src="https://u.outbrain.com/static/app.10f8627e.js"></script>
<script>performance.mark('scripts-end');</script>
setDatasource(dataSource) {
this.showGridLoadingOverlay()
performance.mark('reports-start')
}
whenGridRenderComplete() {
performance.mark('reports-end')
this.hideGridLoadingOverlay()
}
performance.measure('ob_css', 'css-start', 'css-end');
performance.measure('ob_scripts', 'scripts-start', 'scripts-end');
performance.measure('ob_total_page', 'total-page-start', 'reports-end');
const measures = performance.getEntriesByType('measure');
.filter(msr => msr.name.includes('ob_'))
.map(msr => {
return {
name: msr.name,
duration: parseInt(msr.duration),
speed: connection ? connection.effectiveType : ''
}
});
//Fall back to http post
navigator.sendBeacon('/performance-benchmark', { measures }); this.app.post('/performance-benchmark', this.performanceBenchmark.observe);
async observe(req: express.Request, res: express.Response) {
const events: BenchmarkEvent[] = this.parseEvents(req.body);
this.metrics[`${event.name}_country`].observe(
{
app: event.app,
browser: event.browser,
speed: event.speed,
country,
},
event.duration
)
})
return res.sendStatus(200);
}Putting
it all together
Tracking
Memory Leaks
console.log(performance.memory);
// Would show, for example
{
jsHeapSizeLimit: 767557632,
totalJSHeapSize: 58054528,
usedJSHeapSize: 42930044
}Performance.memory
const MAX_MEMORY_LIMIT = 1000 * 1048576; // 1000MB
setInterval(() => {
if(performance.memory.usedJsHeadSize > MAX_MEMORY_LIMIT){
//fire alert
}
}, 60000*30);
Performance.memory