Enhanced Faster Webpage Loading with Pjax

Preload subsequent pages, lazy load images and videos, and use Pjax for faster webpage loading with robust error handling and fallback navigation.

当前为 2025-01-02 提交的版本,查看 最新版本

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         Enhanced Faster Webpage Loading with Pjax
// @namespace    http://tampermonkey.net/
// @version      1.9
// @description  Preload subsequent pages, lazy load images and videos, and use Pjax for faster webpage loading with robust error handling and fallback navigation.
// @author       Tae
// @match        *://*/*
// @grant        none
// ==/UserScript==

(function () {
    'use strict';

    // Lazy load images, videos, and multimedia
    document.addEventListener("DOMContentLoaded", () => {
        const lazyElements = Array.from(document.querySelectorAll("img.lazy, video.lazy, iframe.lazy"));

        function loadLazyElement(el) {
            const dataSrc = el.dataset.src;
            if (!dataSrc) return;

            el.src = dataSrc;
            if (el.tagName === "VIDEO") {
                el.load();
            }
            el.classList.remove("lazy");
        }

        if ("IntersectionObserver" in window) {
            const observer = new IntersectionObserver((entries, observer) => {
                entries.forEach(entry => {
                    if (entry.isIntersecting) {
                        loadLazyElement(entry.target);
                        observer.unobserve(entry.target);
                    }
                });
            });

            lazyElements.forEach(el => observer.observe(el));
        } else {
            const lazyLoadFallback = () => {
                lazyElements.forEach((el, index) => {
                    if (
                        el.getBoundingClientRect().top < window.innerHeight &&
                        el.getBoundingClientRect().bottom > 0 &&
                        getComputedStyle(el).display !== "none"
                    ) {
                        loadLazyElement(el);
                        lazyElements.splice(index, 1); // Remove loaded element
                    }
                });
                if (lazyElements.length === 0) {
                    document.removeEventListener("scroll", lazyLoadFallback);
                    window.removeEventListener("resize", lazyLoadFallback);
                    window.removeEventListener("orientationchange", lazyLoadFallback);
                }
            };
            document.addEventListener("scroll", lazyLoadFallback);
            window.addEventListener("resize", lazyLoadFallback);
            window.addEventListener("orientationchange", lazyLoadFallback);
        }
    });

    // Prefetch links
    document.addEventListener("mouseover", event => {
        const link = event.target.closest("a[href]");
        if (link && !link.target && !link.rel.includes("nofollow")) {
            const href = link.href;
            if (/^https?:\/\//.test(href) && !href.includes("#")) {
                const prefetch = document.createElement("link");
                prefetch.rel = "prefetch";
                prefetch.href = href;
                document.head.appendChild(prefetch);
            }
        }
    });

    // Initialize Pjax
    function initializePjax() {
        if (typeof Pjax === "undefined") {
            const script = document.createElement("script");
            script.src = "https://cdnjs.cloudflare.com/ajax/libs/pjax/0.2.8/pjax.min.js";
            script.onload = () => setupPjax();
            document.head.appendChild(script);
        } else {
            setupPjax();
        }
    }

    function setupPjax() {
        const pjax = new Pjax({
            elements: "a[href]:not([target]):not([data-pjax-disabled])", // Only internal links
            selectors: ["title", ".content"], // Elements to update
            cacheBust: true, // Force cache refresh
        });

        document.addEventListener("pjax:send", () => console.log("Pjax: Request sent"));
        document.addEventListener("pjax:complete", () => {
            console.log("Pjax: Request complete");
            reinitializeLazyLoading();
        });
        document.addEventListener("pjax:error", event => {
            console.error("Pjax: Error occurred", event);
            // Fallback to normal navigation
            window.location.href = event.request.responseURL || event.target.href;
        });
    }

    function reinitializeLazyLoading() {
        const newLazyElements = Array.from(document.querySelectorAll("img.lazy, video.lazy, iframe.lazy:not([src])"));
        if ("IntersectionObserver" in window) {
            const observer = new IntersectionObserver((entries, observer) => {
                entries.forEach(entry => {
                    if (entry.isIntersecting) {
                        const el = entry.target;
                        el.src = el.dataset.src;
                        if (el.tagName === "VIDEO") el.load();
                        observer.unobserve(el);
                    }
                });
            });

            newLazyElements.forEach(el => observer.observe(el));
        }
    }

    // Initialize the script
    initializePjax();
})();