前几日写了一篇文章,介绍了js阻塞页面加载的问题。当时是通过例子来验证的。今天,我介绍一下浏览器内核,从原理上介绍一下js阻塞页面加载的原因。

浏览器的内核是多线程的,它们在内核制控下相互配合以保持同步,一个浏览器至少实现三个常驻线程:javascript引擎线程,GUI渲染线程,浏览器事件触发线程。

1.        javascript引擎是基于事件驱动单线程执行的,JS引擎一直等待着任务队列中任务的到来,然后加以处理,浏览器无论什么时候都只有一个JS线程在运行JS程序。

2.        GUI渲染线程负责渲染浏览器界面,当界面需要重绘(Repaint)或由于某种操作引发回流(reflow)时,该线程就会执行。但需要注意 GUI渲染线程与JS引擎是互斥的,当JS引擎执行时GUI线程会被挂起,GUI更新会被保存在一个队列中等到JS引擎空闲时立即被执行。

3.        事件触发线程,当一个事件被触发时该线程会把事件添加到待处理队列的队尾,等待JS引擎的处理。这些事件可来自JavaScript引擎当前执行的代码块如setTimeOut、也可来自浏览器内核的其他线程如鼠标点击、AJAX异步请求等,但由于JS的单线程关系所有这些事件都得排队等待JS引擎处理。

由上文蓝色标注的文字可以知道,当浏览器在执行JS程序的时候,GUI渲染线程会被保存在一个队列中,直到JS程序执行完成。这样就造成了页面的渲染,就是所说的JS阻塞页面加载问题。

很多同学朋友搞不清楚,既然说JavaScript是单线程运行的,那么XMLHttpRequest在连接后是否真的异步?

其实请求确实是异步的,不过这请求是由浏览器新开一个线程请求(参见上图),当请求的状态变更时,如果先前已设置回调,这异步线程就产生状态变更事件放到 JavaScript引擎的处理队列中等待处理,当任务被处理时,JavaScript引擎始终是单线程运行回调函数,具体点即还是单线程运行 onreadystatechange所设置的函数.

最新文章

  1. ajax请求获取的数据无法赋值给全局变量问题总结
  2. 使用ajax提交form表单,包括ajax文件上传
  3. js前端分页
  4. retinajs 使用方法
  5. 安卓开发30:AsyncTask的用法
  6. JS eval() 特殊用法
  7. 你应该知道的16个Linux服务器监控命令
  8. 根据Entity Framework6.X 数据生成代码(仅获取表名)
  9. C语言变参函数/Variadic fucntion
  10. 令人头疼的clientTop、scrollTop、offsetTop
  11. hdu 4712 (随机算法)
  12. .Net Core 之 MSBuild 介绍
  13. 微信app支付详细教程
  14. Hbase中HMaster作用
  15. PJSUA2开发文档--第六章 媒体 Media类
  16. 查看linux服务器上Tensorflow的版本和位置
  17. 【转】Java内部类详解
  18. CSRF学习小结
  19. Centos 设置zookeeper开机自启动
  20. highcharts柱状图实现legend和数据列一一对应效果

热门文章

  1. 杭州电子科技大学Online Judge 之 “确定比赛名次(ID1285)”解题报告
  2. Android 动画animation 深入分析
  3. HDU 2149-Public Sale(巴什博奕)
  4. ceph基本操作整理
  5. Ubuntu_16.04_Lamp
  6. myeclipse 配置weblogic 异常
  7. js常用的一些正则验证文本框
  8. jbpmAPI-8
  9. Python之路:Python 基础(一)
  10. java 显示视频时间--玩的