您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
精密加载耗时分析器(DOMContentLoaded+首次可视时间+内容完全可见时间)
// ==UserScript== // @name 测试页面加载速度 // @namespace https://viayoo.com/ // @version 4.2 // @license MIT // @description 精密加载耗时分析器(DOMContentLoaded+首次可视时间+内容完全可见时间) // @author ChatGPT & Grok & DeepSeek // @match *://*/* // @grant GM_registerMenuCommand // @run-at document-start // ==/UserScript== (function () { 'use strict'; let currentDuration = null; let domContentLoadedTime = null; let fcp = null, lcp = null; const getLoadDuration = () => { const [navEntry] = performance.getEntriesByType('navigation'); return navEntry ? navEntry.duration : null; }; const getDomContentLoadedTime = () => { const [navEntry] = performance.getEntriesByType('navigation'); return (navEntry && navEntry.domContentLoadedEventEnd) || null; }; const truncateDecimals = (num, decimals) => { const factor = Math.pow(10, decimals); return Math.floor(num * factor) / factor; }; const formatTime = (time) => { if (time >= 10000) { return `${truncateDecimals(time / 1000, 2).toFixed(2)}s`; } else { return `${truncateDecimals(time, 2).toFixed(2)}ms`; } }; const showViaToast = (duration) => { if (window.via && typeof window.via.toast === 'function') { const message = duration ? `加载耗时: ${formatTime(duration)}` : '加载耗时: 未知'; window.via.toast(message); return true; } return false; }; const showDomNotification = (duration) => { const container = document.createElement('div'); const shadow = container.attachShadow({ mode: 'closed' }); const elem = document.createElement('div'); elem.className = 'load-time-final'; elem.textContent = duration ? `加载耗时: ${formatTime(duration)}` : '未知'; elem.style.opacity = '0'; elem.style.transition = 'opacity 0.15s ease-out'; const style = document.createElement('style'); style.textContent = '.load-time-final{position:fixed;bottom:60px;left:50%;transform:translateX(-50%);background:rgba(255,255,255,0.96);backdrop-filter:blur(8px);padding:10px 22px;border-radius:6px;font-family:"JetBrains Mono",monospace;color:#2c3e50;box-shadow:0 4px 20px rgba(0,0,0,0.1);z-index:2147483647;border:1px solid rgba(0,0,0,0.06);font-size:14px;white-space:nowrap;}'; shadow.appendChild(style); shadow.appendChild(elem); document.body.appendChild(container); requestAnimationFrame(() => { elem.style.opacity = '1'; }); setTimeout(() => { elem.style.opacity = '0'; setTimeout(() => container.remove(), 150); }, 1500); }; const showDuration = (duration) => { if (!showViaToast(duration)) { showDomNotification(duration); } }; if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', () => { domContentLoadedTime = performance.now(); }); } else { domContentLoadedTime = getDomContentLoadedTime(); } try { new PerformanceObserver((list) => { for (const e of list.getEntries()) { if (e.name === 'first-contentful-paint' && !fcp) fcp = e.startTime; } }).observe({ type: 'paint', buffered: true }); new PerformanceObserver((list) => { const ents = list.getEntries(); if (ents.length) lcp = ents[ents.length - 1].startTime; }).observe({ type: 'largest-contentful-paint', buffered: true }); } catch (e) { console.warn('浏览器不支持 FCP/LCP 监控:', e); } window.addEventListener('load', () => { requestAnimationFrame(() => { currentDuration = getLoadDuration(); showDuration(currentDuration); }); }, { once: true }); GM_registerMenuCommand('显示性能指标', () => { if (currentDuration === null) { currentDuration = getLoadDuration(); } const domContentLoadedText = domContentLoadedTime ? formatTime(domContentLoadedTime) : '未知'; const fcpText = fcp ? formatTime(fcp) : '未知'; const lcpText = lcp ? formatTime(lcp) : '未知'; const durationText = currentDuration ? formatTime(currentDuration) : '未知'; alert(`DOMContentLoaded: ${domContentLoadedText}\n首次可视时间 (FCP): ${fcpText}\n内容完全可见时间 (LCP): ${lcpText}\n页面完全加载耗时: ${durationText}`); }); })();