【油猴脚本】优化知乎无限滚动时的内存占用(爬几千层楼的帖子用,防止浏览器卡住)

在这里插入图片描述

// ==UserScript==
// @name         知乎内存优化脚本
// @namespace    http://tampermonkey.net/
// @version      2.0
// @description  优化知乎无限滚动时的内存占用,提供轻量优化和完全移除两种模式
// @author       2byte
// @match        https://www.zhihu.com/*
// @grant        GM_setValue
// @grant        GM_getValue
// ==/UserScript==

(function() {
    'use strict';

    // 配置参数
    const CONFIG = {
        // 上方缓冲区大小(像素)
        topBuffer: 200,
        // 状态栏位置
        statusBarPosition: 'bottom-right',
        // 启用控制台日志
        debug: false
    };

    // 存储优化状态
    let optimizedAnswers = new Map();
    let statusBar = null;
    let currentMode = GM_getValue('zhihu_optimizer_mode', 'light'); // 'light' 或 'full'

    // 初始化
    function init() {
        log('初始化知乎内存优化脚本');
        createStatusBar();
        observeExistingAnswers();
        observeNewContent();
    }

    // 创建状态栏
    function createStatusBar() {
        statusBar = document.createElement('div');
        statusBar.id = 'zhihu-memory-optimizer-status';

        // 根据当前模式设置样式
        const isLightMode = currentMode === 'light';
        statusBar.className = isLightMode ? 'zhihu-optimizer-status-light' : 'zhihu-optimizer-status-full';

        statusBar.innerHTML = `
            <div class="zhihu-optimizer-status-header">
                <div class="zhihu-optimizer-status-title">知乎内存优化</div>
                <button class="zhihu-optimizer-mode-toggle" id="zhihuOptimizerModeToggle">
                    ${isLightMode ? '切换到完全移除模式' : '切换到轻量优化模式'}
                </button>
            </div>
            <div class="zhihu-optimizer-status-details">
                <div>已优化内容: <span id="zhihu-optimized-count">0</span> 个</div>
                <div>内存节省: <span id="zhihu-memory-saved">0</span> KB</div>
            </div>
            <div class="zhihu-optimizer-mode-explanation" id="zhihuOptimizerModeExplanation">
                ${isLightMode ?
                    '当前模式:轻量优化 - 内容被替换为占位符,可以快速恢复' :
                    '当前模式:完全移除 - 内容被完全删除,需要重新加载页面'}
            </div>
        `;

        // 样式
        Object.assign(statusBar.style, {
            position: 'fixed',
            bottom: '20px',
            right: '20px',
            color: 'white',
            padding: '10px 15px',
            borderRadius: '4px',
            boxShadow: '0 2px 10px rgba(0, 0, 0, 0.2)',
            fontSize: '14px',
            zIndex: '10000',
            minWidth: '300px',
            backgroundColor: isLightMode ? '#0084ff' : '#ff4d4f'
        });

        // 添加模式切换事件
        const modeToggle = statusBar.querySelector('#zhihuOptimizerModeToggle');
        modeToggle.addEventListener('click', toggleMode);

        document.body.appendChild(statusBar);

        // 添加CSS样式
        addStyles();
    }

    // 添加CSS样式
    function addStyles() {
        const style = document.createElement('style');
        style.textContent = `
            .zhihu-optimizer-status-header {
                display: flex;
                justify-content: space-between;
                align-items: center;
                margin-bottom: 8px;
            }

            .zhihu-optimizer-status-title {
                font-weight: bold;
            }

            .zhihu-optimizer-mode-toggle {
                background: rgba(255, 255, 255, 0.2);
                border: none;
                color: white;
                padding: 4px 8px;
                border-radius: 4px;
                cursor: pointer;
                font-size: 12px;
            }

            .zhihu-optimizer-status-details {
                display: flex;
                justify-content: space-between;
                font-size: 12px;
                opacity: 0.9;
            }

            .zhihu-optimizer-mode-explanation {
                margin-top: 10px;
                padding: 10px;
                background: rgba(255, 255, 255, 0.1);
                border-radius: 4px;
                font-size: 12px;
            }

            .zhihu-optimized-light {
                background-color: #f5f5f5 !important;
                border: 1px dashed #d9d9d9 !important;
            }

            .zhihu-optimized-full {
                background-color: #fff2f0 !important;
                border: 1px dashed #ffa39e !important;
            }

            .zhihu-optimizer-placeholder-light {
                padding: 20px;
                text-align: center;
                color: #8590a6;
                background-color: #f6f6f6;
                border: 1px dashed #d9d9d9;
                border-radius: 4px;
            }

            .zhihu-optimizer-placeholder-full {
                padding: 20px;
                text-align: center;
                color: #ff4d4f;
                background-color: #fff2f0;
                border: 1px dashed #ffa39e;
                border-radius: 4px;
            }

            .zhihu-optimizer-placeholder-light button,
            .zhihu-optimizer-placeholder-full button {
                background-color: #0084ff;
                color: white;
                border: none;
                padding: 6px 12px;
                border-radius: 4px;
                cursor: pointer;
                margin-top: 10px;
            }

            .zhihu-optimizer-placeholder-full button {
                background-color: #ff4d4f;
            }
        `;
        document.head.appendChild(style);
    }

    // 切换模式
    function toggleMode() {
        if (currentMode === 'light') {
            // 切换到完全移除模式
            currentMode = 'full';
            GM_setValue('zhihu_optimizer_mode', 'full');

            // 更新状态栏
            statusBar.style.backgroundColor = '#ff4d4f';
            const modeToggle = statusBar.querySelector('#zhihuOptimizerModeToggle');
            modeToggle.textContent = '切换到轻量优化模式';
            const modeExplanation = statusBar.querySelector('#zhihuOptimizerModeExplanation');
            modeExplanation.textContent = '当前模式:完全移除 - 内容被完全删除,需要重新加载页面';

            // 将所有已优化的内容转换为完全移除模式
            optimizedAnswers.forEach((data, answerId) => {
                const answer = document.querySelector(`[data-optimizer-id="${answerId}"]`);
                if (answer && data.type === 'light') {
                    completelyRemoveAnswer(answer);
                }
            });
        } else {
            // 切换到轻量优化模式
            currentMode = 'light';
            GM_setValue('zhihu_optimizer_mode', 'light');

            // 更新状态栏
            statusBar.style.backgroundColor = '#0084ff';
            const modeToggle = statusBar.querySelector('#zhihuOptimizerModeToggle');
            modeToggle.textContent = '切换到完全移除模式';
            const modeExplanation = statusBar.querySelector('#zhihuOptimizerModeExplanation');
            modeExplanation.textContent = '当前模式:轻量优化 - 内容被替换为占位符,可以快速恢复';

            // 注意:在完全移除模式下,我们无法恢复内容,所以这里只是更新状态栏
            log('切换到轻量优化模式,但无法恢复已完全移除的内容');
        }

        updateStatusBar();
    }

    // 更新状态栏
    function updateStatusBar() {
        const countElement = document.getElementById('zhihu-optimized-count');
        const memoryElement = document.getElementById('zhihu-memory-saved');

        if (countElement && memoryElement) {
            let totalMemory = 0;
            optimizedAnswers.forEach(data => {
                totalMemory += data.size;
            });

            countElement.textContent = optimizedAnswers.size;
            memoryElement.textContent = totalMemory.toFixed(1);
        }
    }

    // 观察现有回答
    function observeExistingAnswers() {
        const answers = getAnswerElements();

        answers.forEach(answer => {
            if (!answer.dataset.optimizerId) {
                const id = generateId();
                answer.dataset.optimizerId = id;
                observeAnswer(answer);
            }
        });

        log(`观察了 ${answers.length} 个现有回答`);
    }

    // 观察新加载的内容
    function observeNewContent() {
        const observer = new MutationObserver(mutations => {
            mutations.forEach(mutation => {
                mutation.addedNodes.forEach(node => {
                    if (node.nodeType === 1) { // Element node
                        // 检查是否是回答容器
                        const answers = node.querySelectorAll && node.querySelectorAll('.List-item, .Question-main .ListShortcut .List-item');
                        if (answers && answers.length) {
                            answers.forEach(answer => {
                                if (!answer.dataset.optimizerId) {
                                    const id = generateId();
                                    answer.dataset.optimizerId = id;
                                    observeAnswer(answer);
                                }
                            });
                            log(`观察了 ${answers.length} 个新回答`);
                        }

                        // 如果节点本身是回答
                        if (node.matches && (node.matches('.List-item') || node.matches('.Question-main .ListShortcut .List-item'))) {
                            if (!node.dataset.optimizerId) {
                                const id = generateId();
                                node.dataset.optimizerId = id;
                                observeAnswer(node);
                                log('观察了 1 个新回答');
                            }
                        }
                    }
                });
            });
        });

        observer.observe(document.body, {
            childList: true,
            subtree: true
        });
    }

    // 监测单个回答的可见性
    function observeAnswer(answer) {
        const observer = new IntersectionObserver(entries => {
            entries.forEach(entry => {
                // 如果回答在视窗上方且不可见,进行优化
                if (!entry.isIntersecting && entry.boundingClientRect.top < -CONFIG.topBuffer) {
                    if (currentMode === 'light') {
                        optimizeAnswer(answer);
                    } else {
                        completelyRemoveAnswer(answer);
                    }
                }

                // 如果回答进入视窗,且是轻量优化模式,恢复内容
                if (entry.isIntersecting && currentMode === 'light' && optimizedAnswers.has(answer.dataset.optimizerId)) {
                    const data = optimizedAnswers.get(answer.dataset.optimizerId);
                    if (data && data.type === 'light') {
                        restoreAnswer(answer);
                    }
                }
            });
        }, {
            root: null,
            threshold: 0,
            rootMargin: `${CONFIG.topBuffer}px 0px 0px 0px`
        });

        observer.observe(answer);
    }

    // 轻量优化回答内容
    function optimizeAnswer(answer) {
        if (optimizedAnswers.has(answer.dataset.optimizerId)) {
            return; // 已经优化过了
        }

        // 存储原始内容
        const originalHTML = answer.innerHTML;
        const estimatedSize = estimateMemoryUsage(originalHTML);

        optimizedAnswers.set(answer.dataset.optimizerId, {
            html: originalHTML,
            size: estimatedSize,
            type: 'light'
        });

        // 创建占位符
        const placeholder = document.createElement('div');
        placeholder.className = 'zhihu-optimizer-placeholder-light';
        placeholder.innerHTML = `
            <p>此内容已优化以节省内存</p>
            <p style="font-size: 12px; margin-top: 5px;">约节省 ${estimatedSize}KB 内存</p>
            <button>恢复内容</button>
        `;

        // 添加恢复按钮事件
        const restoreButton = placeholder.querySelector('button');
        restoreButton.addEventListener('click', () => {
            restoreAnswer(answer);
        });

        // 替换内容
        answer.innerHTML = '';
        answer.appendChild(placeholder);

        // 添加优化标记
        answer.classList.add('zhihu-optimized-light');

        log(`轻量优化了回答 ${answer.dataset.optimizerId},节省约 ${estimatedSize}KB 内存`);
        updateStatusBar();
    }

    // 完全移除回答内容
    function completelyRemoveAnswer(answer) {
        if (optimizedAnswers.has(answer.dataset.optimizerId)) {
            // 如果已经是轻量优化,先清除之前的优化数据
            optimizedAnswers.delete(answer.dataset.optimizerId);
        }

        const originalHTML = answer.innerHTML;
        const estimatedSize = estimateMemoryUsage(originalHTML);

        // 存储基本信息(在完全移除模式下,我们不存储完整HTML)
        optimizedAnswers.set(answer.dataset.optimizerId, {
            size: estimatedSize,
            type: 'full'
        });

        // 创建占位符
        const placeholder = document.createElement('div');
        placeholder.className = 'zhihu-optimizer-placeholder-full';
        placeholder.innerHTML = `
            <p>此内容已完全移除以节省内存</p>
            <p style="font-size: 12px; margin-top: 5px;">约节省 ${estimatedSize}KB 内存</p>
            <button>重新加载页面</button>
        `;

        // 添加重新加载按钮事件
        const reloadButton = placeholder.querySelector('button');
        reloadButton.addEventListener('click', () => {
            location.reload();
        });

        // 替换内容
        answer.innerHTML = '';
        answer.appendChild(placeholder);

        // 添加优化标记
        answer.classList.remove('zhihu-optimized-light');
        answer.classList.add('zhihu-optimized-full');

        log(`完全移除了回答 ${answer.dataset.optimizerId},节省约 ${estimatedSize}KB 内存`);
        updateStatusBar();
    }

    // 恢复回答内容(仅适用于轻量优化模式)
    function restoreAnswer(answer) {
        const data = optimizedAnswers.get(answer.dataset.optimizerId);
        if (data && data.type === 'light') {
            answer.innerHTML = data.html;
            answer.classList.remove('zhihu-optimized-light');
            optimizedAnswers.delete(answer.dataset.optimizerId);

            log(`恢复了回答 ${answer.dataset.optimizerId}`);
            updateStatusBar();

            // 重新观察这个回答
            observeAnswer(answer);
        }
    }

    // 获取回答元素
    function getAnswerElements() {
        return document.querySelectorAll('.List-item, .Question-main .ListShortcut .List-item');
    }

    // 估算内存使用量
    function estimateMemoryUsage(html) {
        // 简化估算:每个字符大约占用2字节(UTF-16)
        const size = html.length * 2 / 1024;
        return Math.round(size * 10) / 10; // 保留一位小数
    }

    // 生成唯一ID
    function generateId() {
        return 'optimizer_' + Math.random().toString(36).substr(2, 9);
    }

    // 日志函数
    function log(message) {
        if (CONFIG.debug) {
            console.log(`[知乎内存优化] ${message}`);
        }
    }

    // 页面加载完成后初始化
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', init);
    } else {
        init();
    }
})();```

内容概要:本文系统研究了基于动态三维环境下的Q-Learning算法在无人机自主避障路径规划中的应用,依托Matlab代码实现,深入剖析了强化学习在复杂、变空间中实现智能决策的机制。研究构建了三维网格化状态空间模型,设计了合理的动作集合与奖励函数,充分考虑静态与动态障碍物的存在,使无人机能够通过与环境持续交互,自主学习规避障碍并趋近目标的最优策略。文章不仅展示了Q-Learning算法在路径规划中的具体实现流程,还涵盖了状态表示、策略迭代、收敛性分析等关键环节,并通过仿真实验验证了算法的有效性与鲁棒性,为智能体在动态环境中的自主导航提供了理论依据和技术参考。; 适合人群:具备人工智能、自动化、计算机科学或机器人学等相关专业背景,熟悉Matlab编程语言和基本的强化学习概念,从事无人机控制、智能导航、路径规划算法研究的研究生、科研人员及工程技术人员。; 使用场景及目标:①应用于城市峡谷、灾害现场等复杂动态三维场景中无人机的自主飞行与紧急避障;②作为强化学习解决实际路径规划问题的教学实例,帮助理解Q-Learning的核心思想、状态-动作值函数更新过程及探索-利用权衡策略;③为后续研究更先进的深度强化学习算法(如DQN、PPO)在无人机控制中的应用奠定基础和提供对比基准。; 阅读建议:建议读者结合所提供的Matlab代码进行动手实践,通过调整学习率、折扣因子、探索率(ε-greedy)等超参数,观察其对算法收敛速度和最终路径规划质量的影响,并尝试修改环境复杂度(如增加障碍物密度或动态性)以评估算法的泛化能力。
内容概要:本文主要围绕“单相逆变器闭环,逆变电路PWM模型仿真研究”展开,基于Simulink平台构建单相逆变器的闭环控制系统仿真模型,重点研究脉宽调制(PWM)技术在逆变电路中的应用。通过建立精确的数学模型与控制策略,实现对输出电压的稳定调控,提升逆变器的动态响应与抗干扰能力。文中详细介绍了系统结构、PID控制器设计、PWM信号生成及反馈环节的实现过程,并通过仿真实验验证了闭环控制相较于开环控制在输出波形质量、谐波抑制和负载适应性方面的显著优势。该研究为电力电子系统中逆变器的设计与优化提供了有效的仿真依据和技术参考。; 适合人群:具备电力电子技术基础、自动控制原理识,熟悉Simulink仿真环境,从事电气工程、新能源发电、电力系统自动化等相关领域的科研人员及高校研究生。; 使用场景及目标:①用于教学与科研中理解单相逆变器的工作原理与闭环控制机制;②为光伏并网、不间断电源(UPS)、微电网等实际工程系统的逆变器设计提供仿真支持与优化方案;③辅助完成课程设计、毕业设计或科研项目中的系统建模与控制策略验证。; 阅读建议:建议读者结合Simulink软件动手搭建模型,逐步调试控制器参数以观察系统响应变化,深入理解PID调节、PWM调制与系统稳定性之间的关系,并可进一步拓展至并网逆变器的锁相环(PLL)控制与孤岛检测等高级功能研究。
源码直接下载地址: https://pan.quark.cn/s/3de8d38110cb 智能手机市场的迅猛增长使得邮件应用逐渐演变为用户在工作和日常生活中不可或缺的工具。黑莓手机作为商务领域长期以来的领先者,其卓越的邮件客户端软件能够显著提升用户的工作效能和交流体验。Smrtmail便是这样一款应用,它不仅适配于某一特定黑莓设备,而是专门为整个黑莓设备系列设计了一套邮件管理方案。 Smrtmail的应用理念聚焦于简洁性与高效性。在提供基础的邮件收发功能之外,它还拥有精心设计的用户界面,确保所有黑莓设备用户都能体验到流畅且直观的操作感受。应用的开发充分考虑了黑莓设备的物理构造和用户使用习惯,例如黑莓9900所配备的实体键盘,在Smrtmail中能够得到充分发挥,结合快捷操作键可以迅速完成邮件的撰写与回复。不仅如此,Smrtmail的邮件过滤、分类及搜索功能同样表现出色,用户能够便捷地处理大量邮件信息,迅速找到所需邮件,从而在商务交流中保持高效。 在安全性能方面,Smrtmail为黑莓用户构建了坚实的防护屏障。借助内置的加密技术,用户的数据与隐私将得到严密保护。即便在公共网络环境下使用,也能确保邮件内容的安全性。对于商务人士而言,这是一个至关重要的考量因素。 尽管黑莓手机已不再是市场的主导力量,但它仍然拥有一个稳固的用户群体,特别是那些对设备的安全性、稳定性以及物理键盘有着特殊要求的商务人士。对于这部分用户,Smrtmail提供的应用服务能够满足他们随随地进行邮件处理的诉求,无论是出差期间还是商务活动,都能保证与客户的顺畅沟通。 关于如何获取并运用Smrtmail,用户可以通过下载附带的压缩文件来获取安装程序。安装流程简便,用户只需遵循指示步骤,授权应用访问邮件...
内容概要:本文聚焦于“考虑灵活性供需不确定性的储能优化配置”,结合Matlab代码实现,系统研究电力系统中因新能源出力波动、负荷变化及多能耦合带来的灵活性挑战,提出基于多目标优化、场景生成与削减(如拉丁超立方抽样、Kantorovich距离SBR算法)、鲁棒优化与分布鲁棒优化等先进方法的储能系统优化配置方案。重点涵盖储能的选址、定容、调度策略及其在微电网、综合能源系统、虚拟电厂等场景中的集成应用,同涉及电-热-气多能协同、需求响应建模、电动汽车协同调控等关键技术,全面展示储能提升系统灵活性与可靠性的技术路径与实现手段。; 适合人群:具备电力系统分析、优化理论基础及Matlab编程能力的研究生、科研人员以及从事能源系统规划、运行与政策研究的工程技术人员。; 使用场景及目标:① 掌握处理新能源与负荷双重不确定性对系统灵活性影响的建模方法;② 学习并实践基于Matlab的储能系统多目标优化配置、场景削减与鲁棒调度技术;③ 应用于微电网、综合能源系统、电力市场辅助服务等实际项目中的储能规划与运行决策支持。; 阅读建议:建议结合文中提供的Matlab代码实例,重点理解不确定性建模流程、场景生成与削减算法(如LHS、SBR)、多目标优化算法(如NSGA-II)的应用逻辑,动手复现案例并尝试参数调优与模型拓展,以深入掌握储能优化配置的全流程技术细节与工程实现要点。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值