JS的加载

JS采用单线程,避免在执行过程中页面内内容被不可预知的重复修改

js的五个常驻线程

浏览器的GUI渲染线程
JS引擎线程
浏览器定时器触发线程
浏览器事件触发线程
浏览器http异步请求线程

当js正在运行某一个脚本时,同一时间点,其他的脚本都处于挂起状态,不能被同时处理,这是js的阻塞特性
当<script>标签出现时,不管是内嵌还是外链,js都会让页面等待这个脚本的加载、解析和执行,所以为了避免用户进入页面出现白屏情况,都是将<script>标签放在body的最后,等待页面内部和样式渲染之后在加载js脚本(JS脚本的下载过程不会相互影响)

当html文件遇到css和图片时,都是进行异步加载,不会对dom的渲染造成影响,但是当html文件中出现js脚本时,会挂起dom的渲染,开始js的加载,并且等待js的解析和执行,才能恢复对dom的渲染

css文件的加载不影响js文件的加载,但是影响js文件的执行,js代码在执行前必须保证相关css文件已经加载且解析完成(避免js中动态改变css的方式发生css冲突)

加载js优化

  • script的defer属性,先对script进行解析下载js文件,但是不会执行,使得浏览器不等待js的加载执行结束,即在dom加载完成之前不会去执行,但是此脚本尽量不要对dom进行修改
<body>
  <script defer>
    console.log('2');
  </script>
  <script>
    console.log('1');
  </script>
  <script>
    window.onload = function() {
      console.log('3');
    };
  </script>
</body>
// 支持defer的浏览器的执行顺序
// 1 2 3
  • script的async属性,采用并行下载,下载不会造成阻塞,async加载完成后会自动执行代码,但是defer是等待dom加载完成后执行

一张图解释defer/async

  • js的预加载prefetch会另外开启线程,提前下载js和css文件,但并不会改变dom结构
  • 使用js动态创建script标签,script被添加到页面后立即下载,但是js文件的解析和执行并不会阻塞线程
  • XHR脚本注入,创建XMLHttpRequest对象下载js,下载成功后再动态创建script标签,优点在于下载完成后可以控制不立即执行,但是该方法不能跨域使用

css解析时,样式对象从右开始遍历2,即从子元素往父元素查找

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容