一般地,一个包含外部样式表文件和外部脚本文件的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元素可以使用,但是页面的图片、视频等资源可能还没加载完成

页面渲染时js阻塞的解决方法的更多相关文章

  1. nuxt 头部引入js文件 第一次进入页面不加载js文件的解决方法

    head () { return { title: '', meta: [ { hid: 'description', name: 'description', content: '' } ], sc ...

  2. 常见JS(JavaScript)冲突解决方法

    1.一般JS冲突解决办法 a.最容易出现的就是js的命名冲突 ①.变量名冲突 变量有全局变量和局部变量当全局变量变量和局部变量名称一致时,就会js冲突,由于变量传递数值或地址不同就会产生JavaScr ...

  3. IE 不兼容的几个js问题及解决方法

    IE 不兼容的几个js问题及解决方法 1 Table的问题   在动态新增tr或者td时,createElecment() 一般用appendChild();都不生效,解决办法是用新增tbody, 如 ...

  4. IE 不兼容的几个js问题及解决方法1

    IE 不兼容的几个js问题及解决方法 1 Table的问题   在动态新增tr或者td时,createElecment() 一般用appendChild();都不生效,解决办法是用新增tbody, 如 ...

  5. 关于php读mysql数据库时出现乱码的解决方法

    关于php读mysql数据库时出现乱码的解决方法 php读mysql时,有以下几个地方涉及到了字符集. 1.建立数据库表时指定数据库表的字符集.例如 create table tablename ( ...

  6. linux上备份Oracle时EXP-00091的错误解决方法

    unix/linux上备份Oracle时EXP-00091的错误解决方法 unix/linux上备份数据时的错误解决方法 EXP-00091: Exporting questionable stati ...

  7. PL/SQL Developer 使用中文条件查询时无数据的解决方法(转)

    原文地址: PL/SQL Developer 使用中文条件查询时无数据的解决方法 PL/SQL Developer 使用中文条件查询时无数据,这是由于字符集的不一致导致的. 执行以下sql命令:sel ...

  8. WPF拖动DataGrid滚动条时内容混乱的解决方法

    WPF拖动DataGrid滚动条时内容混乱的解决方法 在WPF中,如果DataGrid里使用了模板列,当拖动滚动条时,往往会出现列表内容显示混乱的情况.解决方法就是在Binding的时候给Update ...

  9. Android开发环境搭建时遇到问题的解决方法

    版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/linux_loajie/article/details/33823637 Android开发环境搭建 ...

随机推荐

  1. 红帽RHCE培训-课程3笔记目录

    目录: 1 控制服务和守护进程 systemctl systemctl restart enable servicename service servicename restart chkconfig ...

  2. Gitlab+Jenkins用钩子实现git提交后jenkins自动化构建

    Gitlab+Jenkins用钩子实现git提交后jenkins自动化构建 一.Jenkins 进入项目---->Configure 1.设置项目代码从git中拉取 2.设置钩子程序 二.git ...

  3. eclipse好用的快捷键

    eclipse一些增加工作效率的快捷键(部分自己添加) eclipse如何修改快捷键 1. shift + enter | ctrl + shift + enter 在下/上方增加空行 2. ctrl ...

  4. ubuntu mysql新增用户并开启远程连接

    1.首先用root用户登录mysql mysql -u root -p 输入密码后登录成功 2.新建用户 use mysql; select host,user from user;(查看现有用户) ...

  5. IIS-简介

    参考:https://www.jb51.net/article/85909.htm IIS是什么 iis是用来做什么的?   IIS全程为Internet Information Service(In ...

  6. Jmeter_选项_函数助手_RandomString的用法

    1.用处:测试账户注册可以通过随机生成数实现,而不需要Excel手动输入, 缺点:随机生成数可能会重复 优点:不需要使用CSV config 或者excel ,txt格式 2.举例:之前我们通过CSV ...

  7. netty(七)buffer源码学习2

    概述 文章主要介绍的是PoolArena,PoolChunk,PoolSubpage 三个类的源码 PoolArena PoolArena 是netty 的内存池实现类,通过预先申请一块大的空间,然后 ...

  8. IMDB-TOP_250-爬虫

    这个小学期Python大作业搞了个获取IMDB TOP 250电影全部信息的爬虫.第二次写爬虫,比在暑假集训时写的熟练多了.欢迎大家评论. ''' ************************** ...

  9. linux的端口学习(一)

    1.端口是什么? 1.1 是英文port的意译,可认为是设备与外界通讯交流的出口. 1.2 端口可分为虚拟端口和物理端口. 1.2.1 虚拟端口:指计算机内部或交换机路由器内的端口,不可见.例如计算机 ...

  10. 28 JavaScript语言类型&运算符

    语言类型: 弱类型:可以改变变量值和对象类型 强类型:可以改变变量值不能改变对象类型 解释型:边编译边执行,速度慢.解释型一般是弱类型 编译型:先编译再执行(C++\Java),速度快.编译型一般是强 ...