如何做到执行JS 而不影响页面的css加载?

加载JS为什么会影响CSS的加载?

因为js是单线程的,所以当js的加载在css前时,会导致css加载被阻塞,造成UI渲染的卡顿。

什么是Web Worker

web worker的作用就是为JavaScript创造一个多线程的环境,允许主线程创建worker线程,将一个任务分配给worker线程运行。在主线程运行的同时,worker线程在后台运行,两者互不干扰。

如何使用Web Worker

1. 使用web worker需要注意的点:
1. 同源限制:分配给Worker线程运行的脚本文件,必须与主线程的脚本文件同源
2. DOM限制:Worker线程所在的全局对象无法读取主线程所在网页的DOM对象,也无法使用DOM的相关API,但是Worker线程可以使用navigator和location对象
3. 通信联系:Worker线程和主线程不在同一个上下文环境,所以无法直接通信,需要使用postMessage
4.  脚本限制:Worker线程不能执行alert方法和confirm方法,但是可以使用XMLHttpRequest发起请求
5.  文件限制:worker无法读取本地文件,他所加载的文件必须来自网络
2. 基本用法
  1. 创建一个Worker线程,主线程使用new关键字调用Worker构造函数
    var worker = new Worker('work.js')
    Worker构造函数的参数是一个脚本文件,该文件的内容就是Worker线程要执行的任务。由于worker不能读取本地文件,所以这个文件必须来自网络。

  2. 主线程向worker线程发消息
    主线程调用worker.postMessage方法,向Worker发消息

    worker.postMessage({method:'echo', args:['work']})
    
  3. worker线程内 接收/发送 消息
    通过监听message事件和postMessage方法

    // self代表worker子线程自身
    self.addEventListener('message', function(e){
       // e.data 可以获取到主线程发送的数据
    
       self.postMessage('send some message')
    })
    
  4. 主线程接收worker线程的消息
    调用worker的onmessage方法

  worker.onmessage = function(event){
      // event.data可以获取到worker发来的数据
      console.log(event.data)
      // do something
  }
  1. 关闭worker线程
    主线程: worker.terminate()
    worker线程: self.close()