Greasy Fork

Greasy Fork is available in English.

Turbo Load: Speed Enhancer

Enhance website loading speed and video playback while preventing autoplay and ensuring smooth CSS rendering.

当前为 2024-11-13 提交的版本,查看 最新版本

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         Turbo Load: Speed Enhancer
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  Enhance website loading speed and video playback while preventing autoplay and ensuring smooth CSS rendering.
// @author       Farzan Farhangi
// @match        *://*/*
// @grant        GM_xmlhttpRequest
// @grant        GM_setValue
// @grant        GM_getValue
// ==/UserScript==

(function() {
    'use strict';

    const cacheKeyPrefix = 'cachedResource_';
    const simulatedSpeedFactor = 1; // Simulate actual speed for better performance

    // Load cached resources
    const loadCachedResource = (url) => {
        const cachedData = GM_getValue(cacheKeyPrefix + url);
        if (cachedData) {
            const script = document.createElement('script');
            script.textContent = cachedData;
            document.head.appendChild(script);
            return true;
        }
        return false;
    };

    // Fetch and cache resources with simulated delay
    const fetchAndCacheResource = async (url) => {
        try {
            await new Promise(resolve => setTimeout(resolve, 1000 / simulatedSpeedFactor)); // Simulate network delay
            const response = await new Promise((resolve, reject) => {
                GM_xmlhttpRequest({
                    method: "GET",
                    url: url,
                    onload: resolve,
                    onerror: reject
                });
            });
            if (response.status === 200) {
                GM_setValue(cacheKeyPrefix + url, response.responseText);
                const script = document.createElement('script');
                script.textContent = response.responseText;
                document.head.appendChild(script);
            }
        } catch (error) {
            console.error(`Failed to fetch resource: ${url}`, error);
        }
    };

    // Preload critical resources for faster initial load
    const preloadCriticalResources = () => {
        const criticalResources = [
            '/index.html',
            '/styles.css',
            '/script.js',
            // Add other critical resources as needed
        ];

        criticalResources.forEach(url => {
            fetchAndCacheResource(url);
        });
    };

    // Optimize initial loading by fetching resources in parallel
    const optimizeInitialLoad = () => {
        const initialResources = [
            '/index.html',
            '/styles.css',
            '/script.js',
            // Add any other resources that should be loaded initially
        ];

        initialResources.forEach(url => {
            fetchAndCacheResource(url); // Fetch each resource simultaneously for faster loading
        });
    };

    // Override fetch to cache scripts and stylesheets with simulated speed adjustment
    const originalFetch = window.fetch;
    window.fetch = async function(...args) {
        const url = args[0];
        if (typeof url === 'string' && (url.endsWith('.js') || url.endsWith('.css'))) {
            if (!loadCachedResource(url)) {
                await fetchAndCacheResource(url);
            }
            return Promise.resolve(); // Return resolved promise immediately
        }
        return originalFetch.apply(this, args);
    };

    // Optimize image loading by preloading images quickly
    const preloadImagesQuickly = () => {
        const images = document.querySelectorAll('img[data-src]');

        images.forEach(image => {
            image.src = image.getAttribute('data-src'); // Set the src immediately for faster loading
            image.onload = () => image.removeAttribute('data-src'); // Clean up the attribute once loaded
        });

        console.log("Images preloaded quickly.");
    };

    // Lazy load videos with adaptive loading based on simulated speed
    const lazyLoadMedia = () => {
        const lazyVideos = document.querySelectorAll('video[data-src]');
        const options = { root: null, rootMargin: '0px', threshold: 0.1 };

        const loadMedia = (entries, observer) => {
            entries.forEach(entry => {
                if (entry.isIntersecting) {
                    const media = entry.target;
                    media.src = media.getAttribute('data-src');
                    media.removeAttribute('data-src');
                    observer.unobserve(media);
                }
            });
        };

        const videoObserver = new IntersectionObserver(loadMedia, options);
        lazyVideos.forEach(video => videoObserver.observe(video));
    };

    // Prevent videos from autoplaying automatically across all sites including YouTube
    const preventAutoPlayVideos = () => {
        const videos = document.querySelectorAll('video');
        videos.forEach(video => {
            video.autoplay = false; // Disable autoplay for all video elements
            video.pause();          // Ensure videos are paused on load

            // Remove any poster or thumbnail that might show when not playing
            video.removeAttribute('poster');
        });

        console.log("Autoplay disabled for all videos.");
    };

    // Optimize video playback by preloading segments with simulated loading time
    const optimizeVideoPlayback = () => {
        const videos = document.querySelectorAll('video');
        videos.forEach(video => {
            video.setAttribute('preload', 'auto'); // Ensure videos are preloaded for faster access
            video.addEventListener('play', () => downloadVideoSegments(video, 5));
            video.addEventListener('waiting', () => {
                console.log('Video is buffering, trying to resume playback...');
                if (!video.paused) video.play();
            });
        });
    };

    // Download video segments for smoother playback with simulated delay
    const downloadVideoSegments = async (video, segmentDuration) => {
        const totalDuration = video.duration;

        if (!totalDuration) return; // Ensure total duration is available

        const segmentCount = Math.ceil(totalDuration / segmentDuration);

        for (let i = 0; i < segmentCount; i++) {
            const startTime = i * segmentDuration;
            const endTime = Math.min(startTime + segmentDuration, totalDuration);
            const url = video.src || video.currentSrc;

            try {
                await new Promise(resolve => setTimeout(resolve, 1000 / simulatedSpeedFactor)); // Simulate network delay

                const response = await new Promise((resolve, reject) => {
                    GM_xmlhttpRequest({
                        method: "GET",
                        url: `${url}?start=${startTime}&end=${endTime}`,
                        responseType: "blob",
                        onload: resolve,
                        onerror: reject
                    });
                });

                if (response.status === 200) {
                    const blobUrl = URL.createObjectURL(new Blob([response.response], { type: 'video/mp4' }));
                    console.log(`Segment loaded: ${blobUrl}`);
                    const preloadVideo = document.createElement('video');
                    preloadVideo.src = blobUrl;
                    preloadVideo.currentTime = startTime;
                    preloadVideo.load();
                }
            } catch (error) {
                console.error(`Failed to load segment from ${startTime} to ${endTime}`, error);
            }
        }
    };

    // Optimize loading of scripts and styles by deferring non-critical resources
    const optimizeLoading = () => {
         document.querySelectorAll('link[rel="stylesheet"]').forEach(link => {
             link.setAttribute('rel', 'preload');
             link.setAttribute('as', 'style');
             link.onload = () => link.setAttribute('rel', 'stylesheet');
         });

         // Load CSS files immediately to prevent layout shifts.
         document.querySelectorAll('link[rel="stylesheet"]').forEach(link => {
             link.href += ''; // Trigger a re-fetch of the stylesheet.
         });

         document.querySelectorAll('script').forEach(script => {
             if (!script.src.includes('critical.js')) {
                 script.setAttribute('defer', 'defer');
             }
         });

         // Lazy load fonts after a delay for better performance
         setTimeout(() => loadFonts(), 2000);

         // Load icons after a delay for better performance
         setTimeout(() => loadIcons(), 3000);

         // Load all graphic elements after a delay for better performance
         setTimeout(() => loadGraphics(), 4000);
     };

     // Load fonts after a delay for better performance
     function loadFonts() {
         const links = document.querySelectorAll('link[rel="preload"][as="font"]');
         links.forEach(link => {
             link.rel = 'stylesheet';
         });
     }

     // Load icons after a delay for better performance
     function loadIcons() {
         const iconLinks = document.querySelectorAll('link[rel="icon"], link[rel="shortcut icon"]');
         iconLinks.forEach(link => {
             link.href += '';
             link.removeAttribute('data-delay');
         });

         console.log("Icons loaded after delay.");
     }

     // Load all graphic elements after a specified delay for better performance
     function loadGraphics() {
         const graphicElements = document.querySelectorAll('img[data-delay], video[data-delay]');

         graphicElements.forEach(element => {
             if (element.tagName === 'IMG') {
                 element.src = element.getAttribute('data-delay');
                 element.onload = () => element.removeAttribute('data-delay');
             } else if (element.tagName === 'VIDEO') {
                 element.src = element.getAttribute('data-delay');
                 element.onloadstart = () => element.removeAttribute('data-delay');
             }
         });

         console.log("Graphic elements loaded after delay.");
     }

     // Initialize optimizations on page load
     window.addEventListener('load', () => {
         preloadImagesQuickly();
         preloadCriticalResources();
         optimizeInitialLoad();
         optimizeLoading();
         lazyLoadMedia();
         preventAutoPlayVideos();
         optimizeVideoPlayback();
     });

})();