页面渲染时js阻塞的解决方法

部署运行你感兴趣的模型镜像

一般地,一个包含外部样式表文件和外部脚本文件的HTML载入和渲染过程是这样的:

  1. 浏览器下载HTML文件并开始解析DOM。
  2. 遇到样式表文件link[rel=stylesheet]时,将其加入资源文件下载队列,继续解析DOM。
  3. 遇到脚本文件时,暂停DOM解析并立即下载脚本文件。
  4. 下载结束后立即执行脚本,在脚本中可访问当前<script>以上的DOM。
  5. 脚本执行结束,继续解析DOM。
  6. 整个DOM解析完成,触发DOMContentLoaded事件。

什么是阻塞?

  在页面中我们通常会引用外部文件,而浏览器在解析HTML页面是从上到下依次解析、渲染,如果<head>中引用了一个a.js文件,而这个文件很大或者有问题,需要2秒加载,那么浏览器会停止渲染页面(此时是白屏显示,就是页面啥都没有),2秒后加载完成才会继续渲染,这个就是阻塞。

为什么会阻塞?

  因为浏览器不知道a.js中执行了哪些脚本,会对页面造成什么影响,所以浏览器会等js文件下载并执行完成后才继续渲染,如果这个时间过长,会白屏。

解决方法

1、推迟加载(延迟加载)

  如果页面初始的渲染并不依赖于js或者CSS可以用推迟加载,就是最后在加载js和css,把引用外部文件的代码写在最后。比如一些按钮的点击事件,比如轮播图动画的脚本也可以放在最后。

2、defer延迟加载

<script src="" defer></script>
  在文档解析完成开始执行,并且在DOMContentLoaded事件之前执行完成,会按照他们在文档出现的顺序去下载解析。效果和把script放在文档最后</body>之前是一样的。
          注:defer最好用在引用外部文件中使用,用了defer不要使用document.write()方法;使用defer时最好不要请求样式信息,因为样式表可能尚未加载,浏览器会禁止该脚本等待样式表加载完成,相当于样式表阻塞脚本执行。

3、异步加载

  • async异步加载:就是告诉浏览器不必等到加载完外部文件,可以边渲染边下载,什么时候下载完成什么时候执行。
     <script type="text/javascript" src="a.js" async></script>
           注:用了async不要使用document.write()方法;使用async时最好不要请求样式信息,原因和defer一样。
  • script dom element法:这个方法是用js动态创建一个script元素添加在document中。
    <script type="text/javascript">
        (function() {
         var s = document.createElement('script');
         s.type = 'text/javascript';
         s.async = true;                                        //这句可以删除,但是效果不变。
         s.src = 'js/a.js';
         var x = document.getElementsByTagName('script')[0];
         x.parentNode.insertBefore(s, x);
     })();
    </script>

    注意:这种方法会阻止onload事件

  • onload时异步加载:这个和script dom element法差不多但是他不是同时执行js和html,他是等html的文件,图片之类的、页面所有的资源全部加载完成后再下载执行js,这样的方法可以避免阻塞onload事件的触发。
     (function() {
          function async_load(){
              var s = document.createElement('script');
              s.type = 'text/javascript';
              s.async = true;
              s.src = 'js/yibujiaz.js';
              var x = document.getElementsByTagName('script')[0];
              x.parentNode.insertBefore(s, x);
          }
          if (window.attachEvent)
              window.attachEvent('onload', async_load);
          else
              window.addEventListener('load', async_load, false);
      })();
    注:DOMContentLoaded与onload事件不同,DOMContentLoaded是页面解析完成,页面的dom元素可以使用,但是页面的图片、视频等资源可能还没加载完成

转载于:https://www.cnblogs.com/lmjZone/p/8603241.html

您可能感兴趣的与本文相关的镜像

HunyuanVideo-Foley

HunyuanVideo-Foley

语音合成

HunyuanVideo-Foley是由腾讯混元2025年8月28日宣布开源端到端视频音效生成模型,用户只需输入视频和文字,就能为视频匹配电影级音效

<think>我们讨论的是JavaScript加载过程阻塞的问题。在浏览器中,当加载和执行JavaScript代码,会阻塞HTML解析和页面渲染,因为JS可能会修改DOM结构。为了解决这个问题,可以采用一些策略。 常见的解决方法包括: 1. 将`<script>`标签放在页面底部(`</body>`之前),这样不会阻塞页面内容的呈现。 2. 使用`defer`属性:脚本会被延迟到整个页面都解析完毕后再执行,且多个defer脚本会按顺序执行。 3. 使用`async`属性:脚本异步加载,加载完成后立即执行(可能会在HTML解析过程中执行),不保证多个async脚本的执行顺序。 4. 动态创建`<script>`标签并插入到DOM中,这样也可以实现异步加载。 5. 使用模块化加载器(如RequireJS)或现代打包工具(如Webpack)进行代码分割和按需加载。 另外,对于内联脚本,可以考虑使用`requestAnimationFrame`或`setTimeout`来延迟执行,避免阻塞。 下面是一个使用`defer`和`async`的例子: ```html <!-- 使用defer --> <script src="script.js" defer></script> <!-- 使用async --> <script src="script.js" async></script> ``` 动态加载脚本的例子: ```javascript const script = document.createElement('script'); script.src = 'script.js'; document.body.appendChild(script); ``` 注意:`defer`和`async`都只适用于外部脚本(即带有src属性的脚本)。 根据以上内容,我们提出相关问题。</think>### JavaScript 加载阻塞问题及解决方法 JavaScript 默认会阻塞 HTML 解析和页面渲染,因为浏览器需确保脚本执行 DOM/CSSOM 已准备就绪。以下是核心解决方案: #### 解决方法 1. **异步加载 (`async`)** ```html <script src="app.js" async></script> ``` - 特点:下载不阻塞解析,执行仍会阻塞 - 适用:独立脚本(如统计代码) 2. **延迟加载 (`defer`)** ```html <script src="app.js" defer></script> ``` - 特点:下载不阻塞解析,在 `DOMContentLoaded` 前顺序执行 - 适用:依赖 DOM 的脚本 3. **动态注入脚本** ```javascript const script = document.createElement('script'); script.src = "app.js"; document.body.appendChild(script); // 异步加载 ``` 4. **模块化加载 (`type="module"`)** ```html <script type="module" src="app.js"></script> // 默认 defer 行为 ``` 5. **预加载优化** ```html <link rel="preload" href="app.js" as="script"> // 提前加载不执行 ``` #### 关键区别 | 属性 | 阻塞解析 | 执行顺序 | 执行机 | |-----------|----------|----------|------------------------| | 无 | 是 | 顺序 | 下载完成后立即执行 | | `async` | 否 | 乱序 | 下载完成后立即执行 | | `defer` | 否 | 顺序 | DOM 解析后,`DOMContentLoaded` 前 |
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值