1<form
2 data-querystats
3 action="."
4 method="get"
5 target="querystats"
6 class="relative group/querystats"
7 style="display: none;">
8 <input type="hidden" name="querystats" value="store">
9 <button type="submit" class="px-2 py-px text-xs rounded-full bg-stone-700 text-stone-300 whitespace-nowrap" data-querystats-summary></button>
10 <div data-querystats-list style="display: none;" class="absolute right-0 z-50 hidden translate-y-full -bottom-1 group/querystats-hover:block">
11 <div class="p-2 text-xs border rounded shadow-md bg-zinc-900 border-zinc-700"><table><tbody></tbody></table></div>
12 </div>
13 <script async defer>
14 // Catch errors since some browsers throw when using the new `type` option.
15 // https://bugs.webkit.org/show_bug.cgi?id=209216
16 var querystatsTimings = [];
17 function renderQuerystats() {
18 // Render the most recent timing call
19 const latestTiming = querystatsTimings[querystatsTimings.length - 1];
20 let summary = latestTiming.description;
21 if (querystatsTimings.length > 1) {
22 summary += ` *`;
23 }
24 document.querySelector('[data-querystats-summary]').innerText = summary;
25
26 // Make sure the elements are visible
27 document.querySelector('[data-querystats]').style.display = 'inline';
28
29 // Render the table rows for all timings
30 const list = document.querySelector('[data-querystats-list]');
31 if (querystatsTimings.length > 1) {
32 const tableRows = querystatsTimings.map(timing => {
33 let url = timing.url;
34 if (url.startsWith(window.location.origin)) {
35 // Make the url relative if possible (usually is)
36 url = url.slice(window.location.origin.length);
37 }
38 return `<tr>
39 <td class="pr-2 font-medium whitespace-nowrap">${url}</td>
40 <td class="whitespace-nowrap">${timing.description}</td>
41 </tr>`;
42 }).join('');
43 list.querySelector("tbody").innerHTML = tableRows;
44 list.style.display = '';
45 } else {
46 list.style.display = 'none';
47 }
48 }
49 try {
50 // Create the performance observer.
51 const po = new PerformanceObserver((list) => {
52 for (const entry of list.getEntries()) {
53 if (!entry.serverTiming) {
54 console.warn("Server timing not available for querystats.")
55 return;
56 }
57 for (const timing of entry.serverTiming) {
58 if (querystatsTimings.length > 0) {
59 if (querystatsTimings[querystatsTimings.length - 1] === timing) {
60 // Skip duplicate timings (happens on initial load...)
61 continue;
62 }
63 }
64 if (timing.name === "querystats") {
65 console.log("Querystats timing", entry)
66 timing.url = entry.name; // Store this for reference later
67 querystatsTimings.push(timing);
68 renderQuerystats();
69 }
70 }
71 }
72 });
73 po.observe({type: 'navigation', buffered: true}); // Catch the regular page loads
74 po.observe({type: 'resource', buffered: true}); // Catch future ajax requests
75 } catch (e) {
76 // Do nothing if the browser doesn't support this API.
77 }
78 </script>
79</form>