|
阅读:613回复:3
内存监控面板
AI写的,没有售后
快捷键ctrl+shift+m开启 标签右键菜单里有开关 可拖拽 (function() {
'use strict';
let floatingPanel = null;
let refreshTimer = null;
let isDragging = false;
let dragOffset = {
x: 0,
y: 0
};
async function getAllTabsProcessInfo() {
try {
const procInfo = await ChromeUtils.requestProcInfo();
const processMap = new Map();
for (const tab of gBrowser.tabs) {
const outerWindowId = tab.linkedBrowser.outerWindowID;
let found = false;
for (const childProc of procInfo.children) {
if (childProc.windows) {
for (const win of childProc.windows) {
if (win.outerWindowId === outerWindowId) {
const pid = childProc.pid || 'N/A';
if (!processMap.has(pid)) {
processMap.set(pid, {
pid: pid,
type: childProc.type || 'unknown',
memory: Math.round(childProc.memory / (1024 * 1024)),
tabs: []
});
}
processMap.get(pid).tabs.push({
tab,
title: tab.getAttribute('label') || 'Untitled'
});
found = true;
break;
}
}
}
if (found) break;
}
if (!found) {
const pid = 'N/A';
if (!processMap.has(pid)) {
processMap.set(pid, {
pid: pid,
type: 'unknown',
memory: 0,
tabs: []
});
}
processMap.get(pid).tabs.push({
tab,
title: tab.getAttribute('label') || 'Untitled'
});
}
}
return Array.from(processMap.values());
} catch (e) {
console.error('获取所有标签页进程信息失败:', e);
return [];
}
}
function createProcessTreeNode(tabInfo, showMemory = true, isChild = false) {
const node = document.createElement('div');
node.style.cssText = `
padding: 6px ${isChild ? '24px' : '8px'};
border-bottom: 1px solid var(--chrome-content-separator-color, #e1e1e2);
cursor: pointer;
transition: background-color 0.2s;
`;
node.addEventListener('mouseenter', () => {
node.style.backgroundColor = 'var(--toolbar-field-focus-background-color, #f0f0f0)';
});
node.addEventListener('mouseleave', () => {
node.style.backgroundColor = 'transparent';
});
node.addEventListener('click', () => {
if (tabInfo.tab) gBrowser.selectedTab = tabInfo.tab;
});
const title = document.createElement('div');
title.style.cssText = `
font-weight: ${isChild ? 'normal' : '500'};
margin-bottom: 2px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
`;
title.textContent = tabInfo.title;
const details = document.createElement('div');
details.style.cssText = `
color: var(--toolbar-field-color, #666);
font-size: 11px;
display: flex;
justify-content: space-between;
`;
if (showMemory) {
const memoryText = document.createElement('span');
memoryText.textContent = `${tabInfo.memory}MB`;
memoryText.style.fontWeight = '600';
memoryText.style.color = tabInfo.memory > 200 ? '#d70022' : tabInfo.memory > 100 ? '#ff9500' : '#0060df';
details.appendChild(memoryText);
} else {
details.appendChild(document.createElement('span'));
}
if (!isChild) {
const processText = document.createElement('span');
processText.textContent = `PID: ${tabInfo.pid || ''} ${tabInfo.type || ''}`;
details.appendChild(processText);
} else {
details.appendChild(document.createElement('span'));
}
node.appendChild(title);
node.appendChild(details);
return node;
}
async function updateFloatingPanel() {
if (!floatingPanel) return;
const content = document.getElementById('memory-panel-content');
if (!content) return;
try {
const processList = await getAllTabsProcessInfo();
const topProcesses = processList
.sort((a, b) => b.memory - a.memory)
.slice(0, 5);
content.innerHTML = '';
if (topProcesses.length === 0) {
content.innerHTML = '<div style="padding: 20px; text-align: center; color: #666;">暂无数据</div>';
return;
}
topProcesses.forEach(proc => {
if (proc.tabs.length === 1) {
content.appendChild(createProcessTreeNode({
tab: proc.tabs[0].tab,
title: proc.tabs[0].title,
memory: proc.memory,
pid: proc.pid,
type: proc.type
}, true));
} else {
const processHeader = document.createElement('div');
processHeader.style.cssText = `
padding: 8px;
background: var(--toolbar-field-background-color, #f0f0f0);
font-weight: 600;
border-bottom: 1px solid var(--chrome-content-separator-color, #e1e1e2);
cursor: pointer;
display: flex;
justify-content: space-between;
align-items: center;
`;
const processTitle = document.createElement('span');
processTitle.textContent = `进程 ${proc.pid} (${proc.type})`;
const memorySpan = document.createElement('span');
memorySpan.textContent = `总计: ${proc.memory}MB`;
memorySpan.style.fontWeight = '600';
memorySpan.style.color = proc.memory > 200 ? '#d70022' : proc.memory > 100 ? '#ff9500' : '#0060df';
const expandIcon = document.createElement('span');
expandIcon.textContent = '▼';
expandIcon.style.fontSize = '10px';
expandIcon.style.transition = 'transform 0.2s';
processHeader.appendChild(processTitle);
processHeader.appendChild(memorySpan);
processHeader.appendChild(expandIcon);
const childrenContainer = document.createElement('div');
childrenContainer.style.display = 'block';
processHeader.addEventListener('click', () => {
const isCollapsed = childrenContainer.style.display === 'none';
childrenContainer.style.display = isCollapsed ? 'block' : 'none';
expandIcon.style.transform = isCollapsed ? 'rotate(0deg)' : 'rotate(-90deg)';
});
content.appendChild(processHeader);
proc.tabs.forEach(t => {
childrenContainer.appendChild(createProcessTreeNode({
tab: t.tab,
title: t.title,
pid: proc.pid,
type: proc.type
}, false, true));
});
content.appendChild(childrenContainer);
}
});
} catch (e) {
console.error('更新悬浮面板失败:', e);
content.innerHTML = '<div style="padding: 20px; text-align: center; color: #d70022;">更新失败</div>';
}
}
function createFloatingPanel() {
if (floatingPanel) return;
floatingPanel = document.createElement('div');
floatingPanel.id = 'memory-monitor-panel';
floatingPanel.style.cssText = `
position: fixed;
top: 100px;
right: 20px;
width: 400px;
max-height: 500px;
background: var(--arrowpanel-background, -moz-Dialog);
color: var(--arrowpanel-color, -moz-DialogText);
border: 1px solid var(--arrowpanel-border-color, ThreeDShadow);
border-radius: 4px;
box-shadow: 0 1px 4px color-mix(in srgb, currentColor 20%, transparent);
z-index: 10000;
font: message-box;
font-size: 12px;
overflow: hidden;
user-select: none;
`;
const header = document.createElement('div');
header.style.cssText = `
background: var(--arrowpanel-background, -moz-Dialog);
color: var(--arrowpanel-color, -moz-DialogText);
padding: 8px 12px;
border-bottom: 1px solid var(--chrome-content-separator-color, #e1e1e2);
cursor: move;
font-weight: 600;
display: flex;
justify-content: space-between;
align-items: center;
`;
header.textContent = '内存监控 - 前5名';
const closeBtn = document.createElement('button');
closeBtn.textContent = '×';
closeBtn.style.cssText = `
background: none;
border: none;
font-size: 16px;
cursor: pointer;
padding: 0;
width: 20px;
height: 20px;
display: flex;
align-items: center;
justify-content: center;
`;
closeBtn.onclick = hideFloatingPanel;
header.appendChild(closeBtn);
const content = document.createElement('div');
content.id = 'memory-panel-content';
content.style.cssText = `
max-height: 400px;
overflow-y: auto;
padding: 8px;
background: var(--arrowpanel-background, -moz-Dialog);
color: var(--arrowpanel-color, -moz-DialogText);
`;
floatingPanel.appendChild(header);
floatingPanel.appendChild(content);
document.documentElement.appendChild(floatingPanel);
header.addEventListener('mousedown', startDrag);
document.addEventListener('mousemove', drag);
document.addEventListener('mouseup', stopDrag);
}
function startDrag(e) {
isDragging = true;
const rect = floatingPanel.getBoundingClientRect();
dragOffset.x = e.clientX - rect.left;
dragOffset.y = e.clientY - rect.top;
floatingPanel.style.cursor = 'grabbing';
}
function drag(e) {
if (!isDragging) return;
const x = e.clientX - dragOffset.x;
const y = e.clientY - dragOffset.y;
const maxX = window.innerWidth - floatingPanel.offsetWidth;
const maxY = window.innerHeight - floatingPanel.offsetHeight;
floatingPanel.style.left = Math.max(0, Math.min(x, maxX)) + 'px';
floatingPanel.style.top = Math.max(0, Math.min(y, maxY)) + 'px';
floatingPanel.style.right = 'auto';
}
function stopDrag() {
isDragging = false;
if (floatingPanel) floatingPanel.style.cursor = 'default';
}
function showFloatingPanel() {
createFloatingPanel();
updateFloatingPanel();
if (refreshTimer) clearInterval(refreshTimer);
refreshTimer = setInterval(updateFloatingPanel, 5000);
}
function hideFloatingPanel() {
if (floatingPanel) {
floatingPanel.remove();
floatingPanel = null;
}
if (refreshTimer) {
clearInterval(refreshTimer);
refreshTimer = null;
}
}
document.addEventListener('keydown', (event) => {
if (event.ctrlKey && event.shiftKey && event.key === 'M') {
event.preventDefault();
if (floatingPanel) {
hideFloatingPanel();
} else {
showFloatingPanel();
}
}
});
const contextMenu = document.getElementById('tabContextMenu');
if (contextMenu) {
const separator = document.createXULElement('menuseparator');
const menuItem = document.createXULElement('menuitem');
menuItem.setAttribute('label', '显示内存监控面板');
menuItem.addEventListener('command', () => {
if (floatingPanel) {
hideFloatingPanel();
menuItem.setAttribute('label', '显示内存监控面板');
} else {
showFloatingPanel();
menuItem.setAttribute('label', '隐藏内存监控面板');
}
});
contextMenu.appendChild(separator);
contextMenu.appendChild(menuItem);
}
window.addEventListener('beforeunload', () => {
hideFloatingPanel();
});
})(); |
|
|
|
1楼#
发布于:2025-08-10 16:24
什么AI模式型号网站呢?
|
|
|
2楼#
发布于:2025-08-10 22:12
以前火狐单进程时还挺在意内存占用的,现在多进程了,反而不怎么在意了。
内存买来就是用的,火狐占用少的情况也不太在意。 火狐占用多了,内存满了,自然也就卡了。也不需要实时看,满了再看任务管理器就可以。 |
|
|
3楼#
发布于:2025-08-13 10:37
内存多的用不完,我写的工具都不监控内存的。
|
|
|