Skip to main content
mod_pagespeed 2.1 is here — open source (Apache-2.0): the module you know, plus the optimizer worker

Add instrumentation

HTML

Adds a small client-side beacon that reports real load timings.

Filter add_instrumentation · Filter docs

A module filter.

Both frames render identically — that's the goal. The win is in the bytes and requests below, not the look. They're served live by the mod_pagespeed module on demo-httpd-1.1.modpagespeed.com; the optimized frame applies only this filter. Right after a cache purge it may briefly match the original while the worker rewrites it — reload to see the result.

Measured impact

This filter changes how the page is structured or delivered, not its size — so there's no byte or request reduction to chart. The change shows in the source diff below.

What changed in the source

The page's HTML, before and after this filter. Red lines are removed, green lines are added.

                
                  
<html>
<head>
<title>add_instrumentation example</title>
- </head>
+ <script>window.mod_pagespeed_start = Number(new Date());</script></head>
<body>
A small page to demonstrate how instrumentation is added to a page.
- </body>
+ <script data-pagespeed-no-defer type="text/javascript">//<![CDATA[ (function(){window.pagespeed=window.pagespeed||{};var g=window.pagespeed;function h(d,c,a){this.H=d;this.C=c;this.D=a;this.u=!1;this.l=-1;this.B={g:0,o:0,m:0};this.j=0;this.A=!1;this.i=-1;this.h=[];k(this)}function m(d,c,a,b){var e=window.PerformanceObserver;if(!e||!e.supportedEntryTypes||e.supportedEntryTypes.indexOf(c)==-1)return!1;try{var f=new e(function(l){a(l.getEntries())});b=b||{};b.type=c;b.buffered=!0;f.observe(b);d.h.push({v:f,G:a});return!0}catch(l){return!1}} function k(d){function c(a){for(var b=0;b<a.length;b++){var e=a[b];if(e.entryType!="event"||e.interactionId)e=Math.round(e.duration),e>d.i&&(d.i=e)}}m(d,"largest-contentful-paint",function(a){for(var b=0;b<a.length;b++){var e=a[b];d.l=Math.round(e.renderTime||e.loadTime||e.startTime)}});d.A=m(d,"layout-shift",function(a){for(var b=0;b<a.length;b++){var e=a[b];if(!e.hadRecentInput){var f=d.B;f.g>0&&e.startTime-f.m<1E3&&e.startTime-f.o<5E3?(f.g+=e.value,f.m=e.startTime):(f.g=e.value,f.o=f.m=e.startTime); f.g>d.j&&(d.j=f.g)}}});m(d,"event",c,{durationThreshold:40});m(d,"first-input",c)}
+ function n(d){if(!d.u){d.u=!0;for(var c=0;c<d.h.length;c++){var a=d.h[c];try{a.G(a.v.takeRecords()),a.v.disconnect()}catch(e){}}c=[];var b=window.performance;a=null;b&&b.getEntriesByType&&(b=b.getEntriesByType("navigation"))&&b.length>0&&(a=b[0]);a?(b=Math.round(a.loadEventStart),b>0&&(c.push("ets=load:"+b),c.push("rload="+b)),c.push("nav="+Math.round(a.fetchStart)),c.push("dns="+Math.round(a.domainLookupEnd-a.domainLookupStart)),c.push("connect="+Math.round(a.connectEnd-a.connectStart)),c.push("req_start="+
+ Math.round(a.requestStart)),c.push("c_ttfb="+Math.round(a.responseStart)),c.push("dwld="+Math.round(a.responseEnd-a.responseStart)),c.push("dom_c="+Math.round(a.domContentLoadedEventStart)),a.type&&c.push("nt="+a.type)):window.mod_pagespeed_start&&c.push("ets=load:"+(Number(new Date)-window.mod_pagespeed_start));d.l>=0&&c.push("lcp="+d.l);d.A&&c.push("cls="+Math.round(d.j*1E3));d.i>=0&&c.push("inp="+d.i);c.push("dpr="+window.devicePixelRatio);c=c.join("&");d.C!=""&&(c+=d.C);g.getResourceTimingData&&
+ (c+=g.getResourceTimingData());document.referrer&&(c+="&ref="+encodeURIComponent(document.referrer));a=d.H;a+=a.indexOf("?")==-1?"?":"&";a+="url="+encodeURIComponent(d.D);if((d=window.navigator)&&d.sendBeacon)try{if(d.sendBeacon(a,c))return}catch(e){}(new Image).src=a+"&"+c}}
+ g.F=function(d,c,a){if(window.parent==window){var b=new h(d,c,a);document.addEventListener("visibilitychange",function(){document.visibilityState=="hidden"&&n(b)});window.addEventListener("pagehide",function(){n(b)});window.addEventListener("pageshow",function(e){if(e.persisted){for(e=0;e<b.h.length;e++)try{b.h[e].v.disconnect()}catch(f){}b.h=[];b.u=!1;b.l=-1;b.B={g:0,o:0,m:0};b.j=0;b.i=-1;k(b)}})}};g.addInstrumentationInit=g.F;})(); pagespeed.addInstrumentationInit('/mod_pagespeed_beacon', '', 'https://demo-httpd-1.1.modpagespeed.com/mod_pagespeed_example/add_instrumentation.html'); //]]></script></body>
</html>

Run this on your own site

This is one of 49 filters the mod_pagespeed module applies in place — self-hosted on Apache, nginx, and IIS. Install and run it: it optimizes right away and adds an the optimized response headers shown above. Open source under the Apache License 2.0 — free in development and in production.