Amazon Page Smoother

Performance optimization for Amazon: background throttling, lazy loading, and layout stabilization.

当前为 2025-11-26 提交的版本,查看 最新版本

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         Amazon Page Smoother
// @namespace    http://tampermonkey.net/
// @version      0.1.0
// @description  Performance optimization for Amazon: background throttling, lazy loading, and layout stabilization.
// @license      Unlicense
// @author       VeleSila
// @match        https://www.amazon.com/*
// @match        https://www.amazon.co.jp/*
// @match        https://www.amazon.co.uk/*
// @match        https://www.amazon.es/*
// @match        https://www.amazon.fr/*
// @match        https://www.amazon.de/*
// @match        https://www.amazon.it/*
// @match        https://www.amazon.ca/*
// @match        https://www.amazon.com.au/*
// @exclude      */cart/*
// @exclude      */buy/*
// @exclude      */checkout/*
// @exclude      */gp/buy/*
// @grant        GM_addStyle
// @run-at       document-start
// ==/UserScript==

(function() {
    'use strict';

    /**
     * CONFIGURATION
     */
    const CONFIG = {
        // Number of images to load with high priority (Above the fold approximation)
        HIGH_PRIORITY_COUNT: 4,
        // Debounce delay for the mutation observer (ms)
        DEBOUNCE_DELAY_MS: 300
    };

    /**
     * 1. CRITICAL SAFETY CHECK
     * Immediately exit on sensitive pages to prevent interference with payments.
     */
    const sensitivePaths = /(checkout|signin|payment|addressselect|huc)/i;
    if (sensitivePaths.test(window.location.pathname)) {
        return;
    }

    /**
     * 2. CSS OPTIMIZER
     * Uses modern CSS containment to prevent rendering off-screen content.
     * Adjusted to minimize layout shifting.
     */
    function injectOptimizedStyles() {
        const css = `
            /* Optimize Search Results 
               Using strict containment on result items allows the browser to 
               skip rendering items not currently in the viewport.
            */
            .s-main-slot .s-result-item {
                content-visibility: auto;
                contain-intrinsic-size: 1px 350px; /* Adjusted to average card height */
            }

            /* GPU Acceleration for Product Images */
            img.s-image {
                transform: translateZ(0);
                will-change: opacity;
            }

            /* Defer Footer Rendering */
            #navFooter {
                content-visibility: auto;
                contain-intrinsic-size: 1px 600px;
            }
        `;

        if (typeof GM_addStyle === 'function') {
            GM_addStyle(css);
        } else {
            const style = document.createElement('style');
            style.textContent = css;
            document.head.appendChild(style);
        }
    }

    /**
     * 3. RESOURCE OPTIMIZER
     * Applies lazy loading and fetch priority attributes.
     * REVISION: Removed getBoundingClientRect() calls to prevent Layout Thrashing.
     */
    function optimizeResources(rootNode = document) {
        // Select images that haven't been optimized yet
        const images = rootNode.querySelectorAll('img:not([data-opt])');
        if (images.length === 0) return;

        // Check for browser support
        const supportsPriority = 'fetchPriority' in HTMLImageElement.prototype;

        for (let i = 0, len = images.length; i < len; i++) {
            const img = images[i];
            
            // Mark as processed to avoid re-looping
            img.dataset.opt = '1';

            // 1. Footer Images: Always low priority and lazy
            if (img.closest('#navFooter')) {
                img.loading = 'lazy';
                img.decoding = 'async';
                if (supportsPriority) img.fetchPriority = 'low';
                continue;
            }

            // 2. Product Images (Search results)
            if (img.classList.contains('s-image')) {
                // Heuristic: The first few images found in the DOM are likely "Above the fold"
                // We use the loop index rather than geometry to avoid Reflow.
                if (i < CONFIG.HIGH_PRIORITY_COUNT) {
                    img.loading = 'eager';
                    if (supportsPriority) img.fetchPriority = 'high';
                } else {
                    img.loading = 'lazy';
                    img.decoding = 'async';
                    if (supportsPriority) img.fetchPriority = 'low';
                }
                continue;
            }

            // 3. General Fallback for other images
            if (!img.hasAttribute('loading')) {
                img.loading = 'lazy';
                img.decoding = 'async';
            }
        }
    }

    /**
     * 4. INITIALIZATION & OBSERVER
     * Handles dynamic content loading (Infinite scroll/Pagination).
     */
    function main() {
        try {
            injectOptimizedStyles();
            
            // Initial pass
            optimizeResources(document);

            // Debounced Observer for dynamic content
            let debounceTimer;
            const observer = new MutationObserver((mutations) => {
                // Check if nodes were actually added
                let hasNewNodes = false;
                for (const m of mutations) {
                    if (m.addedNodes.length > 0) {
                        hasNewNodes = true;
                        break;
                    }
                }
                if (!hasNewNodes) return;

                clearTimeout(debounceTimer);
                debounceTimer = setTimeout(() => {
                    // Use requestIdleCallback if available for non-urgent updates
                    if ('requestIdleCallback' in window) {
                        requestIdleCallback(() => optimizeResources(document.body));
                    } else {
                        optimizeResources(document.body);
                    }
                }, CONFIG.DEBOUNCE_DELAY_MS);
            });

            // Target the search slot specifically if it exists, otherwise fallback to body
            const targetNode = document.querySelector('.s-main-slot') || document.body;
            
            observer.observe(targetNode, {
                childList: true,
                subtree: true
            });

            console.log('[Amazon Smoother] Optimized v1.0.0 active.');

        } catch (error) {
            console.error('[Amazon Smoother] Error:', error);
        }
    }

    // Boot Logic
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', main, { once: true });
    } else {
        main();
    }

})();