您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
eb performance test
// ==UserScript== // @name eb performance // @namespace http://tampermonkey.net/ // @version 0.1.6 // @description eb performance test // @author timluo465 // @match http://*/* // @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== // @grant none // @license MIT // ==/UserScript== const defaultStyle = "font-size:14px"; const focalStyle = "font-weight:700;font-size:16px"; (function () { "use strict"; console.log("开始初始化eb性能分析插件"); const recordFuns = []; const moduleObj = {}; const createInterval = function (callback) { const interval = setInterval(function () { const res = callback(); if (res) { clearInterval(interval); } }, 20); }; createInterval(function () { if (window.mobx) { initMobx(); } return !!window.mobx; }); createInterval(function () { if (window.React) { initReact(); } return !!window.React; }); const createPerformanceTimer = function (fn, opts) { return function (...args) { const { fnName = "" } = opts || {}; const now = performance.now(); const res = fn(...args); const last = performance.now(); const time = (last - now).toString(); const spentTime = time.substring(0, time.indexOf(".") + 3); if (spentTime > 5) { const consoleFun = spentTime > 50 ? console.error : console.warn; recordFuns.push({ func: this, time: spentTime }); consoleFun( `%c${fnName}%c 耗时 %c${spentTime} ms%c, 参数为:%o \n${ res ? `返回结果:%o` : "无返回结果" }`, focalStyle, defaultStyle, focalStyle, defaultStyle, args, res ); } return res; }; }; const call = Function.prototype.call; Function.prototype.call = function () { const now = performance.now(); const res = call.apply(this, arguments); const last = performance.now(); const time = (last - now).toString(); const spentTime = time.substring(0, time.indexOf(".") + 3); if (spentTime > 5) { const module = getModule(); if (module) { const moduleName = `@weapp/${module}`; const consoleFun = spentTime > 50 ? console.error : console.warn; recordFuns.push({ func: this, time: spentTime }); if (module && moduleObj[moduleName]) { const { all, serious } = moduleObj[moduleName]; moduleObj[moduleName] = { ...moduleObj[moduleName], all: all + 1, }; if(spentTime > 50){ moduleObj[moduleName].serious = serious + 1; } } else { moduleObj[moduleName] = { moduleName: moduleName, all: 1, serious: 1, }; } consoleFun( `%c未知方法执行耗时 %c${spentTime} ms%c,来源模块:%c@weapp/${module}%c \n点击定位方法:%o \n${ res ? `返回结果:%o` : "无返回结果" }`, defaultStyle, focalStyle, defaultStyle, focalStyle, defaultStyle, this, res ); } } return res; }; function getModule(isMobx) { //创建一个Error来获取Error所在的位置及其堆栈跟踪 const e = new Error(); const regex = /\((.*):(\d+):(\d+)\)$/; if (!isMobx) { const stak = e.stack.split("\n"); const match = regex.exec(stak[stak?.length - 1]); const module = match?.[1].match(/(?<=build\/).*?(?=\/static)/)?.[0] || ""; return module; } } function initMobx() { const mobx = window.mobx; ["toJS", "computed", "runInAction"].forEach(function (act) { const originalFn = mobx[act]; mobx[act] = createPerformanceTimer(originalFn, { fnName: `mobx.${act}`, }); Object.keys(originalFn).forEach(function (key) { mobx[act][key] = originalFn[key]; }); }); Object.keys(mobx.observable).forEach(function (action) { const originalFn = mobx.observable[action]; mobx.observable[action] = createPerformanceTimer(originalFn, { fnName: `mobx.observable.${action}`, }); }); console.log("Mobx性能分析插件初始化完成!"); } function initReact() { const React = window.React; [ "useEffect", "useCallback", "useState", "useMemo", "useRef", "memo", ].forEach(function (hook) { const originalHook = React[hook]; React[hook] = createPerformanceTimer(originalHook, { fnName: `React.${hook}`, }); }); console.log("React Hooks性能分析插件初始化完成!"); } function print() { const printObj = []; const moduleArrays = []; Object.keys(moduleObj).forEach(function (key) { moduleArrays.push(moduleObj[key]); }); const sortModuleArrays = moduleArrays.sort((a, b) => { return b.all - a.all; }); sortModuleArrays.forEach((array) => { printObj.push({ 前端模块: array.moduleName, "问题数(所有)": array.all, "问题数(耗时大于50ms)": array.serious, }); }); console.table(printObj); } function getRecords() { const funs = []; const beyondThresholdFuns = []; const threshold = 50; let times = 0; recordFuns.forEach((recordFun) => { funs.push(recordFun); if (recordFun.time > threshold) { beyondThresholdFuns.push(recordFun); times++; } }); console.log( `截至当前已发现性能问题点共计${recordFuns.length}个,大于${threshold}ms的问题共计${times}个 \n所有记录:%o\n大于${threshold}ms的记录:%o`, funs, beyondThresholdFuns ); return; } window.performanceTools = { print, getRecords }; })();