webprofiler-10.0.x-dev/templates/Collector/frontend.html.twig
templates/Collector/frontend.html.twig
{% block toolbar %}
{% set icon %}
{{ include('@webprofiler/Icon/time.svg') }}
<span class="sf-toolbar-value" id="wp--frontend__toolbar">0</span>
{% endset %}
{% set text %}
<div class="sf-toolbar-info-piece">
<b>{{ 'DNS lookup'|t }}</b>
<span id="wp--frontend__dns"></span>
</div>
<div class="sf-toolbar-info-piece">
<b>{{ 'TCP handshake'|t }}</b>
<span id="wp--frontend__tcp"></span>
</div>
<div class="sf-toolbar-info-piece">
<b>{{ 'TTFB' }}</b>
<span id="wp--frontend__ttfb"></span>
</div>
<div class="sf-toolbar-info-piece">
<b>{{ 'Data download'|t }}</b>
<span id="wp--frontend__data"></span>
</div>
<div class="sf-toolbar-info-piece">
<b>{{ 'DOM building'|t }}</b>
<span id="wp--frontend__dom"></span>
</div>
<div class="sf-toolbar-info-piece">
<b>{{ 'CLS'|t }}</b>
<span id="wp--frontend__cls">{{ 'n/a'|t }}</span>
</div>
<div class="sf-toolbar-info-piece">
<b>{{ 'FID'|t }}</b>
<span id="wp--frontend__fid">{{ 'n/a'|t }}</span>
</div>
<div class="sf-toolbar-info-piece">
<b>{{ 'LCP'|t }}</b>
<span id="wp--frontend__lcp">{{ 'n/a'|t }}</span>
</div>
{% endset %}
<script>
const navigation = performance.getEntriesByType('navigation')[0],
dns = navigation.domainLookupEnd - navigation.domainLookupStart,
tcp = navigation.connectEnd - navigation.connectEnd,
ttfb = navigation.responseStart - navigation.connectEnd,
data = navigation.responseEnd - navigation.responseStart,
dom = navigation.loadEventStart - navigation.responseEnd;
document.getElementById('wp--frontend__toolbar').innerHTML = ttfb.toFixed(2) + ' ms';
document.getElementById('wp--frontend__dns').innerHTML = dns.toFixed(2) + ' ms';
document.getElementById('wp--frontend__tcp').innerHTML = tcp.toFixed(2) + ' ms';
document.getElementById('wp--frontend__ttfb').innerHTML = ttfb.toFixed(2) + ' ms';
document.getElementById('wp--frontend__data').innerHTML = data.toFixed(2) + ' ms';
document.getElementById('wp--frontend__dom').innerHTML = dom.toFixed(2) + ' ms';
const payload = JSON.stringify(
{
'navigation': navigation,
'timeOrigin': performance.timeOrigin
}
);
navigator.sendBeacon('{{ url("webprofiler.frontend.navigation", {profile: token}) }}', payload);
const script = document.createElement('script');
script.src = 'https://unpkg.com/web-vitals@3/dist/web-vitals.attribution.iife.js';
script.onload = function () {
const queue = new Set();
function addToQueue(metric) {
switch(metric.name) {
case 'LCP':
document.getElementById('wp--frontend__lcp').innerHTML = metric.value.toFixed(2) + ' ms';
break;
case 'FID':
document.getElementById('wp--frontend__fid').innerHTML = metric.value.toFixed(2) + ' ms';
break;
case 'CLS':
document.getElementById('wp--frontend__cls').innerHTML = metric.value.toFixed(4);
break;
}
queue.add(metric);
}
function flushQueue() {
if (queue.size > 0) {
// Replace with whatever serialization method you prefer.
// Note: JSON.stringify will likely include more data than you need.
const body = JSON.stringify([...queue]);
navigator.sendBeacon('{{ url("webprofiler.frontend.cwv", {profile: token}) }}', body)
queue.clear();
}
}
webVitals.onLCP(addToQueue);
webVitals.onFID(addToQueue);
webVitals.onCLS(addToQueue);
// Report all available metrics whenever the page is backgrounded or unloaded.
addEventListener('visibilitychange', () => {
if (document.visibilityState === 'hidden') {
flushQueue();
}
});
// NOTE: Safari does not reliably fire the `visibilitychange` event when the
// page is being unloaded. If Safari support is needed, you should also flush
// the queue in the `pagehide` event.
addEventListener('pagehide', flushQueue);
}
document.head.appendChild(script);
</script>
{{ include('@webprofiler/Profiler/toolbar_item.html.twig', { link: profiler_url }) }}
{% endblock %}
{% block panel %}
{{ collector.panel() }}
{% endblock %}
