// ==UserScript== // @name data-hpc GitHub Performance Monitor (Simplified) // @namespace http://tampermonkey.net/ // @version 1.0 // @description Measures time until data-hpc attribute appears on GitHub pages // @author Andri Alexandrou // @match http://github.localhost/* // @match https://github.com/* // @match https://*.github.com/* // @grant GM_addStyle // @run-at document-start // ==/UserScript== (function() { 'use strict'; // Record when the script starts const scriptStartTime = performance.now(); const navigationStartTime = performance.timeOrigin || performance.timing.navigationStart; // Create a status indicator let statusIndicator = null; // Store timeout IDs so we can clear them let checkIntervalId = null; let timeoutId = null; // Add styles GM_addStyle(` #data-hpc-indicator { position: fixed; z-index: 9999; bottom: 20px; right: 20px; background: rgba(30, 30, 30, 0.8); color: white; padding: 8px 12px; border-radius: 4px; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; font-size: 12px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2); transition: opacity 0.3s ease; max-width: 300px; } #data-hpc-indicator.success { background: rgba(46, 125, 50, 0.9); } #data-hpc-indicator.warning { background: rgba(245, 124, 0, 0.9); } `); // Create the indicator element once the DOM is ready function createStatusIndicator() { if (statusIndicator) return; statusIndicator = document.createElement('div'); statusIndicator.id = 'data-hpc-indicator'; statusIndicator.textContent = 'Monitoring for data-hpc...'; document.body.appendChild(statusIndicator); } // Function to stop all monitoring function stopMonitoring() { if (checkIntervalId) { clearInterval(checkIntervalId); checkIntervalId = null; } if (timeoutId) { clearTimeout(timeoutId); timeoutId = null; } } // Function to find elements with data-hpc attribute function checkForDataHpc() { const elements = document.querySelectorAll('[data-hpc]'); if (elements.length > 0) { // Elements with data-hpc found - record the time const foundTime = performance.now(); // Calculate timing const scriptToAttribute = foundTime - scriptStartTime; const navigationToAttribute = (navigationStartTime + foundTime) - navigationStartTime; // Stop all monitoring immediately stopMonitoring(); // Show visual indicator if (document.body) { createStatusIndicator(); statusIndicator.classList.add('success'); statusIndicator.innerHTML = ` Found ${elements.length} data-hpc elements
Nav → data-hpc: ${Math.round(navigationToAttribute)}ms
Script → data-hpc: ${Math.round(scriptToAttribute)}ms `; // Auto-hide after 10 seconds setTimeout(() => { if (statusIndicator && statusIndicator.parentNode) { statusIndicator.style.opacity = '0'; setTimeout(() => { if (statusIndicator && statusIndicator.parentNode) { statusIndicator.parentNode.removeChild(statusIndicator); statusIndicator = null; } }, 300); } }, 10000); } // Print simplified output to console console.log(`URL: ${window.location.href}`); console.log(`Navigation → data-hpc: ${Math.round(navigationToAttribute)}ms`); console.log(`Script → data-hpc: ${Math.round(scriptToAttribute)}ms`); console.log(`Found ${elements.length} data-hpc elements`); console.log('Tip: To see elements, use document.querySelectorAll("[data-hpc]")'); } } // Wait for DOM to initialize before adding status indicator if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', createStatusIndicator); } else if (document.body) { createStatusIndicator(); } // Check every 50ms for the element checkIntervalId = setInterval(checkForDataHpc, 50); // Add a timeout to stop checking after 30 seconds timeoutId = setTimeout(() => { // Only show timeout if we haven't found elements yet if (checkIntervalId) { clearInterval(checkIntervalId); checkIntervalId = null; if (statusIndicator) { statusIndicator.classList.add('warning'); statusIndicator.textContent = 'Timeout: data-hpc not found within 30s'; // Auto-hide after 5 seconds setTimeout(() => { if (statusIndicator && statusIndicator.parentNode) { statusIndicator.style.opacity = '0'; setTimeout(() => { if (statusIndicator && statusIndicator.parentNode) { statusIndicator.parentNode.removeChild(statusIndicator); statusIndicator = null; } }, 300); } }, 5000); } console.warn('Timeout: data-hpc not found within 30s'); } }, 30000); })();