// ==UserScript== // @name Web Comprehensive Optimization Script(web综合优化脚本) // @namespace http://tampermonkey.net/ // @version 1.4 // @description Optimize non-first screen CSS and image lazy loading, hardware acceleration, and more. // @author KiwiFruit // @match *://*/* // @grant none // @license MIT // @downloadURL none // ==/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 ${rootMarginBottom} 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 ${rootMarginBottom} 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 ${rootMarginBottom} 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); // Optional optimizations // ... (rest of the optional optimizations code remains the same) })();