您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Reduces react repaint duration by limiting initial number of messages
// ==UserScript== // @name ChatGPT reduce react repaint duration // @namespace https://chatgpt.com/ // @version 1.0.0 // @description Reduces react repaint duration by limiting initial number of messages // @author SadSalmonTwT // @license MIT // @match https://chatgpt.com/* // @icon https://www.google.com/s2/favicons?sz=64&domain=chatgpt.com // @grant none // @run-at document-start // ==/UserScript== (function () { 'use strict'; // defines the number of initially loaded messages const INIT_NUMBER_OF_MESSAGES = 10; // request for chat history regex const conversationRegex = /^https:\/\/chatgpt\.com\/backend-api\/conversation\/[a-f0-9\-]{36}$/i; const originalFetch = window.fetch; // intercept the fetch api window.fetch = function (input, init) { const url = (typeof input === 'string') ? input : input.url; // process all other requests like normal, but intercept all chat history request responses if (!conversationRegex.test(url)) return originalFetch.apply(this, arguments); else return originalFetch.apply(this, arguments) .then(async (response) => { try { const data = await response.clone().json(); const newMapping = []; let nextId = data.current_node; let numberOfVisibleMessages = 0; // traverse tree upwards from the last message leaf towards root while (true) { const _message = data.mapping[nextId]; // if root is encountered early, add it and stop loop if (_message.id === "client-created-root") { newMapping.push(_message); break; } // traverse downwards tree towards child leaves (these messages are hidden) const _childIds = [..._message.children]; while (_childIds.length !== 0) { const _childId = _childIds.pop(); const _child = data.mapping[_childId]; // if newMapping already contains child, skip it if (newMapping.some(_preservedMessage => _preservedMessage.id === _childId)) continue; // add hidden message newMapping.push(_child); // add children's children _childIds.push(..._child.children); } // add message itself (if the number was not reached AND its parent exists AND it's not root) if ( numberOfVisibleMessages < INIT_NUMBER_OF_MESSAGES && data.mapping[_message.parent] ) newMapping.push(_message); else { // add "first" message and link it to root newMapping.push({ ..._message, parent: "client-created-root" }); // add chat root newMapping.push({ id: "client-created-root", message: null, parent: null, children: [_message.id] }); // stop loop break; } nextId = _message.parent; numberOfVisibleMessages++; } // if new mappings have same length as old ones, return original response if (newMapping.length === Object.keys(data.mapping).length) { console.log("ChatGPT_reduce_react_repaint_duration: Response was left unchanged"); return response; } // update chat history data.mapping = Object.fromEntries( newMapping.map(_message => ([ _message.id, _message ])) ); console.log('ChatGPT_reduce_react_repaint_duration: Response was trimmed', data); // return response with modified data return new Response(JSON.stringify(data), { status: response.status, statusText: response.statusText, headers: response.headers }); } catch (err) { console.error('ChatGPT_reduce_react_repaint_duration: An error has occurred', err); return response; } }); }; })();