JavaScript无阻塞加载的方式

JavaScript无阻塞加载的方式

在 JavaScript 中,无阻塞加载(Non-blocking Loading)是优化网页性能的关键技术,通过避免脚本阻塞页面渲染和其他资源的加载,提升用户体验。以下是实现无阻塞加载的常用方法及示例:

1. 使用 async 属性

  • 作用:异步加载脚本,下载完成后立即执行,不阻塞 HTML 解析。

  • 适用场景:独立脚本,不依赖其他脚本或 DOM。

  • 示例 :

    html 复制代码
    <script async src="script.js"></script>

2. 使用 defer 属性

  • 作用:异步加载脚本,但延迟到 HTML 解析完成后按顺序执行。

  • 适用场景:需要按顺序执行且依赖 DOM 的脚本。

  • 示例 :

    html 复制代码
    <script defer src="script1.js"></script>
    <script defer src="script2.js"></script> <!-- script1 先执行 -->

3. 动态脚本加载

通过 JavaScript 动态创建 <script> 标签,实现按需加载。

  • 适用场景:非关键脚本或条件加载。

  • 示例 :

    javascript 复制代码
    function loadScript(src) {
        const script = document.createElement('script');
        script.src = src;
        document.body.appendChild(script);
    }
    // 在需要时加载
    window.addEventListener('DOMContentLoaded', () => {
        loadScript('script.js');
    });

4. 使用 Promise 或 async/await 控制加载顺序

结合动态加载和 Promise,管理脚本依赖关系。

  • 示例 :

    javascript 复制代码
    function loadScript(src) {
        return new Promise((resolve, reject) => {
            const script = document.createElement('script');
            script.src = src;
            script.onload = resolve;
            script.onerror = reject;
            document.head.appendChild(script);
        });
    }
    
    async function init() {
        await loadScript('lib.js');
        await loadScript('app.js'); // 确保 lib.js 先加载
    }
    init();

5. 使用 Intersection Observer 延迟加载

在元素进入视口时加载脚本,适用于非首屏资源。

  • 示例 :

    javascript 复制代码
    const observer = new IntersectionObserver((entries) => {
        entries.forEach(entry => {
            if (entry.isIntersecting) {
                loadScript('lazy-script.js');
                observer.unobserve(entry.target);
            }
        });
    });
    observer.observe(document.querySelector('#lazy-element'));

6. 模块化动态导入(ES6 import())

按需加载 ES6 模块,适用于现代浏览器。

  • 示例 :

    javascript 复制代码
    button.addEventListener('click', async () => {
        const module = await import('./module.js');
        module.doSomething();
    });

7. 使用 Web Workers 处理计算密集型任务

将耗时任务移至后台线程,避免阻塞主线程。

  • 示例 :

    javascript 复制代码
    const worker = new Worker('worker.js');
    worker.postMessage({ data: 'start' });
    worker.onmessage = (e) => {
        console.log('Result:', e.data);
    };

8. 资源预加载(preload 和 prefetch)

通过 <link> 标签提示浏览器提前加载资源。

  • preload :高优先级资源,当前页面使用。

    html 复制代码
    <link rel="preload" href="critical.js" as="script">
  • prefetch :低优先级资源,未来页面可能使用。

    html 复制代码
    <link rel="prefetch" href="next-page.js" as="script">

9. 条件加载(根据浏览器特性)

检测浏览器支持后加载特定脚本。

  • 示例 :

    javascript 复制代码
    if ('IntersectionObserver' in window) {
        loadScript('modern-script.js');
    } else {
        loadScript('fallback-script.js');
    }

10. 服务端异步加载(SSR + Hydration)

结合服务端渲染(SSR)和客户端激活(Hydration),按需加载交互逻辑。

  • 示例 (Next.js 框架):

    javascript 复制代码
    import dynamic from 'next/dynamic';
    const DynamicComponent = dynamic(() => import('../components/HeavyComponent'));

总结

方法 核心原理 适用场景 优点 缺点
async/defer 异步加载脚本 首屏非关键脚本 简单易用 async 不保证执行顺序
动态脚本加载 按需创建<script> 标签 非关键脚本/条件加载 灵活控制加载时机 需手动管理依赖
import() 动态导入 按需加载 ES6 模块 现代浏览器应用 模块化支持 需支持 ES6 模块
Intersection Observer 延迟加载视口外资源 图片、懒加载组件 高性能懒加载 兼容性需处理
Web Workers 后台线程执行任务 计算密集型操作 避免主线程阻塞 无法直接操作 DOM
资源预加载 提前加载关键资源 优化关键路径 减少加载延迟 可能浪费带宽

注意事项:

  • 依赖管理 :确保异步脚本的执行顺序(如使用 defer 或 Promise)。
  • 兼容性 :旧版浏览器(如 IE)不支持 async/defer 和 ES6 模块,需降级处理。
  • 性能监控:使用工具(如 Lighthouse)分析加载性能,针对性优化。

通过合理组合这些方法,可显著提升页面加载速度和交互体验。

更多vue相关插件及后台管理模板可访问vue admin reference,代码详情请访问github

相关推荐
麦麦麦当劳大王9 小时前
【油猴脚本】Boss直聘 岗位职责复制
开发语言·前端·javascript
小lu飞10 小时前
2026小红书小工具怎么制作:纯前端 ZIP 打包、沙箱限制与笔记挂载流程
前端·笔记·ai·ai编程
只睡四小时10 小时前
Three.js Sub-tick:漏判 60.7%→0
开发语言·javascript·性能优化·ecmascript·游戏开发·three.js·碰撞检测
smallcelebration10 小时前
151 从0开始搭建后端项目
前端·firefox
wangruofeng10 小时前
手机和电脑传文件,除了微信还有 LocalSend
前端
excel11 小时前
基于 GPT 的自动发布文章接口方案:从一句话或一张图片生成并发布内容
前端·javascript·后端
其实防守也摸鱼13 小时前
个人学习 Pwn 思路:从基础到漏洞利用的进阶路径
大数据·前端·人工智能·chrome·算法·安全·网络安全
朱涛的自习室13 小时前
212 个需求、22 万行代码:Agent 接管开源项目的 19 天
android·前端·人工智能
aZhe的全栈知识分享13 小时前
AI 还原 Figma 效果总达不到预期?先别急着让它写代码
前端·后端·面试
review4454313 小时前
Codex Hooks 入门实战:生命周期事件、matcher 与5分钟跑通一个钩子
前端·agent·vibecoding