Greasy Fork

Greasy Fork is available in English.

Web Comprehensive Optimization Script(web综合优化脚本)

Optimize non-first screen CSS and image lazy loading, hardware acceleration, script lazy loading, code splitting, caching strategy, event throttling, and more.

当前为 2025-03-13 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         Web Comprehensive Optimization Script(web综合优化脚本)
// @namespace    http://tampermonkey.net/
// @version      1.5
// @description  Optimize non-first screen CSS and image lazy loading, hardware acceleration, script lazy loading, code splitting, caching strategy, event throttling, and more.
// @author       KiwiFruit
// @match        *://*/*
// @grant        none
// @license      MIT
// ==/UserScript==

document.addEventListener("DOMContentLoaded", function() {
    'use strict';

    // Function to dynamically load a script
    function loadScript(url) {
        return new Promise((resolve, reject) => {
            const script = document.createElement('script');
            script.src = url;
            script.onload = resolve;
            script.onerror = reject;
            document.head.appendChild(script);
        });
    }

    // Function to dynamically load a stylesheet
    function loadStylesheet(href) {
        return new Promise((resolve, reject) => {
            const link = document.createElement('link');
            link.rel = 'stylesheet';
            link.href = href;
            link.onload = resolve;
            link.onerror = reject;
            document.head.appendChild(link);
        });
    }

    // Define hardware acceleration-related CSS class
    const hardwareAccelerationClassName = 'enable-hardware-acceleration';
    const styleSheet = `
        .${hardwareAccelerationClassName} {
            transform: translateZ(0);
            will-change: transform;
        }
    `;
    const styleElement = document.createElement('style');
    styleElement.type = 'text/css';
    styleElement.appendChild(document.createTextNode(styleSheet));
    document.head.appendChild(styleElement);

    // IntersectionObserver to handle hardware acceleration for visible elements
    const hardwareAccelerationObserver = new IntersectionObserver((entries, observer) => {
        entries.forEach(entry => {
            if (entry.isIntersecting) {
                entry.target.classList.add(hardwareAccelerationClassName);
            } else {
                entry.target.classList.remove(hardwareAccelerationClassName);
            }
        });
    }, {
        rootMargin: '0px 0px 0px 0px',
        threshold: 0
    });

    // Initialize lozad.js image lazy loading
    loadScript('https://cdnjs.cloudflare.com/ajax/libs/lozad.js/1.15.0/lozad.min.js').then(() => {
        const observer = lozad(); // lazy loads elements with default selector as '.lozad'
        observer.observe();
    });

    // Initialize non-first screen CSS lazy loading
    const lazyCssElements = document.querySelectorAll('.lazy-css');
    lazyCssElements.forEach(element => {
        const cssHref = element.getAttribute('data-lazy-css');
        if (cssHref) {
            loadStylesheet(cssHref).then(() => {
                element.parentElement.removeChild(element); // Remove placeholder element
            });
        }
    });

    // Listen to click events using requestAnimationFrame
    document.addEventListener('click', () => {
        requestAnimationFrame(enableHardwareAccelerationForVisibleElements);
    });

    // Listen to media play events using IntersectionObserver
    const mediaElements = document.querySelectorAll('audio, video');
    mediaElements.forEach(element => {
        const mediaObserver = new IntersectionObserver((entries, observer) => {
            entries.forEach(entry => {
                if (entry.isIntersecting) {
                    element.play();
                } else {
                    element.pause();
                }
            });
        }, {
            rootMargin: '0px',
            threshold: 0
        });
        mediaObserver.observe(element);
    });

    // Listen to image load events using IntersectionObserver
    const imageElements = document.querySelectorAll('img[data-src]');
    imageElements.forEach(element => {
        const imageObserver = new IntersectionObserver((entries, observer) => {
            entries.forEach(entry => {
                if (entry.isIntersecting) {
                    element.src = element.getAttribute('data-src');
                    observer.unobserve(element);
                }
            });
        }, {
            rootMargin: '0px 0px 0px 0px', // Trigger when element is 30% away from the viewport bottom
            threshold: 0 // Trigger as soon as any part of the element is visible
        });
        imageObserver.observe(element);
    });

    // Initialize check for hardware acceleration
    enableHardwareAccelerationForVisibleElements();

    // MutationObserver to listen for DOM changes and ensure new elements trigger lazy loading and hardware acceleration
    const mutationObserver = new MutationObserver(mutations => {
        mutations.forEach(mutation => {
            mutation.addedNodes.forEach(node => {
                if (node.nodeType === 1) {
                    if (node.tagName === 'IMG' && node.hasAttribute('data-src')) {
                        const imageObserver = new IntersectionObserver((entries, observer) => {
                            entries.forEach(entry => {
                                if (entry.isIntersecting) {
                                    node.src = node.getAttribute('data-src');
                                    observer.unobserve(node);
                                }
                            });
                        }, {
                            rootMargin: '0px 0px 0px 0px', // Trigger when element is 30% away from the viewport bottom
                            threshold: 0 // Trigger as soon as any part of the element is visible
                        });
                        imageObserver.observe(node);
                    } else if (node.classList.contains('lazy-css') && node.hasAttribute('data-lazy-css')) {
                        const cssHref = node.getAttribute('data-lazy-css');
                        loadStylesheet(cssHref).then(() => {
                            node.parentElement.removeChild(node); // Remove placeholder element
                        });
                    } else if (node.matches('.target-element')) {
                        hardwareAccelerationObserver.observe(node);
                    }
                }
            });
        });
    });
    mutationObserver.observe(document.body, { childList: true, subtree: true });

    // ResizeObserver to monitor viewport size changes
    const resizeObserver = new ResizeObserver(() => {
        requestAnimationFrame(enableHardwareAccelerationForVisibleElements);
    });
    resizeObserver.observe(document.body);

    // Initialize code splitting and caching strategy
    if ('serviceWorker' in navigator) {
        navigator.serviceWorker.register('/service-worker.js').then(() => {
            console.log('Service Worker registered successfully.');
        }).catch(() => {
            console.log('Service Worker registration failed.');
        });
    }

    // Initialize event throttling
    const throttle = (func, wait) => {
        let inThrottle, lastFunc;
        return function() {
            const context = this, args = arguments;
            if (!inThrottle) {
                func.apply(context, args);
                inThrottle = true;
                setTimeout(() => inThrottle = false, wait);
            }
        };
    };

    // Use throttle function to handle scroll events
    window.addEventListener('scroll', throttle(function() {
        // Perform scroll-related logic
    }, 100));

    // Initialize code quality check
    // Note: This is just an example. You need to configure it according to your actual situation.
    // npx eslint path/to/your-file.js

    // Optional optimizations
    // ... (rest of the optional optimizations code remains the same)
});