cd /news/developer-tools/a-user-script-that-fixes-major-perfo… · home topics developer-tools article
[ARTICLE · art-9006] src=gist.github.com ↗ pub= topic=developer-tools verified=true sentiment=↑ positive

A user script that fixes major performance and UX issues on Google's AI Studio. It eliminates scroll-fighting, stops content from flickering/disappearing, and removes rendering lag for a much…

Based on the article, a user script called "Google AI Studio Performance & UX Fixer" has been created to resolve major performance and user experience issues on Google's AI Studio platform. The script eliminates scroll-fighting, prevents content from flickering or disappearing, and removes rendering lag to provide a smoother user experience. It achieves this by injecting custom CSS to disable animations and transitions, overriding the IntersectionObserver to prevent content from being unloaded, and intercepting scroll events to stop automatic scrolling from interfering with user input.

read2 min views20 publishedJul 2, 2025

Google AI Studio Performance & UX Fixer-1.user.js

  This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.

Learn more about bidirectional Unicode characters

Show hidden characters
// ==UserScript==

// @name         Google AI Studio Performance & UX Fixer

// @namespace    http://tampermonkey.net/

// @version      1

// @description  A comprehensive script to fix all major UI/UX issues in AI Studio, including scroll-fighting, content flicker, rendering lag, and edit-scroll bugs.

// @author       Diyar Baban

// @match        https://aistudio.google.com/prompts/*

// @grant        none

// @run-at       document-start

// ==/UserScript==

(function() {

    'use strict';

    const log = (message, ...args) => console.log('[AI Studio Fixer v1]', message, ...args);

    const addGlobalStyle = () => {

        const styleId = 'ai-studio-fixer-styles';

        if (document.getElementById(styleId)) return;

        const style = document.createElement('style');

        style.id = styleId;

        style.textContent = `

            * {

                transition-property: none !important;

                animation: none !important;

                scroll-behavior: auto !important;

            }

            .turn, ms-chat-turn {

                contain: layout paint !important;

                padding-bottom: 24px !important;

            }

            .conversation-container, .turns-container { background: #1E1E1E !important; }

            .turn {

                background: transparent !important;

                border: none !important;

                box-shadow: none !important;

                padding-top: 8px !important;

                margin: 0 !important;

            }

            .prompt-textarea { box-shadow: none !important; border-top: 1px solid #3a3a3a !important; }

            .turn-footer .right-items, .turn-footer .model-info, .turn-footer .tools-info { display: none !important; }

            .turn-footer { min-height: auto !important; padding-top: 4px !important; }

            pre, code { background-color: #252526 !important; border: 1px solid #333 !important; }

        `;

        document.documentElement.appendChild(style);

        log('Performance & UI CSS injected.');

    };

    const fixDisappearingContent = () => {

        const originalIntersectionObserver = window.IntersectionObserver;

        window.IntersectionObserver = function(callback, options) {

            const newCallback = (entries, observer) => {

                const modifiedEntries = entries.map(entry => {

                    if (entry.target.closest('.turn, ms-chat-turn') && !entry.isIntersecting) {

                        return new Proxy(entry, {

                            get: (target, prop) => (prop === 'isIntersecting' ? true : Reflect.get(target, prop))

                        });

                    }

                    return entry;

                });

                return callback(modifiedEntries, observer);

            };

            return new originalIntersectionObserver(newCallback, options);

        };

        log('Disappearing content/flicker fix is active.');

    };

    const fixScrollFighting = (chatContainer) => {

        const originalScrollIntoView = Element.prototype.scrollIntoView;

        let isUserScrolling = false;

        let scrollBlockTimer;

        const blockAppScrolls = () => {

            isUserScrolling = true;

            clearTimeout(scrollBlockTimer);

            scrollBlockTimer = setTimeout(() => isUserScrolling = false, 1000);

        };

        chatContainer.addEventListener('wheel', blockAppScrolls, { passive: true, capture: true });

        chatContainer.addEventListener('keydown', blockAppScrolls, { passive: true, capture: true });

        document.body.addEventListener('click', (e) => {

            const button = e.target.closest('button');

            if (button && button.getAttribute('aria-label')?.toLowerCase().includes('edit')) {

                const turnElement = e.target.closest('ms-chat-turn');

                if (turnElement) {

                    log('Edit click detected. Manually scrolling element into view.');

                    setTimeout(() => {

                        turnElement.scrollIntoView({ behavior: 'smooth', block: 'nearest' });

                    }, 50);

                }

            }

        }, true);

        Element.prototype.scrollIntoView = function(...args) {

            if (isUserScrolling && chatContainer.contains(this)) {

                log('Blocked app-forced scroll due to user wheel/key action.');

                return;

            }

            return originalScrollIntoView.apply(this, args);

        };

        log('Direct-control scroll fix is active.');

    };

    let fixesInitialized = false;

    const runAllFixes = () => {

        if (fixesInitialized || !document.body) return;

        addGlobalStyle();

        fixDisappearingContent();

        const observer = new MutationObserver(() => {

            const chatContainer = document.querySelector('main .conversation-container');

            if (chatContainer) {

                log('Chat container found. Applying targeted fixes.');

                fixScrollFighting(chatContainer);

                fixesInitialized = true;

                observer.disconnect();

            }

        });

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

    };

    if (document.readyState === '') {

        document.addEventListener('DOMContentLoaded', runAllFixes);

    } else {

        runAllFixes();

    }

})();
── more in #developer-tools 4 stories · sorted by recency
── more on @google ai studio 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/a-user-script-that-f…] indexed:0 read:2min 2025-07-02 ·