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 提交的版本。查看 最新版本

// ==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();
     });

})();