[读书笔记]高性能js-界面快速响应

浏览器有个UI线程,包括UI更新和JS的执行。和UI线程相关的是队列系统。

<button onclick='alert(1)'>123</button>

比如我们点击这个按钮,UI线程会添加2个任务到队列中,一个是更新UI的外观,一个是执行JS代码。

如图片

其实在js执行的过程中也可能会向队列系统中添加任务,就比如上面在js执行的过程中就想队列中添加了更新UI的任务,在UI线程执行完了js代码之后,就接着执行UI的更新。

一般情况下,js代码执行事件要在100毫秒以内,这样用户才不会感到有失去页面的交互。有一种方法来测试代码执行的时间

var start=+new Date();

code execution.....

var end=+new Date();

var time=end-start;

time就是代码执行的时间。

但有些js代码执行时间会超过100ms,所以我们一般会让出UI线程的控制权,让js代码迟点执行,先去更新UI,然后再执行JS。这就用到了定时器原理了。

定时器一般把需要较长时间运行的js拆成一段段的,在分别在一定时间之后执行。

function get(){

  alert(1)

}

settimeout(get,250);

get函数会在250之后被加到队列中,在这之前其他的UI更新和js代码的执行都会照常运行。当然,在250秒之后被假如到队列也不是马上就执行的,要等队列前面的任务都执行完了才会去执行get函数任务。

new Worker

另外,js可以创建一个新的线程去跑代码,而线程UI自己管自己运行.利用一个叫 new Worker()的东西。

下面放个小栗子

   <div class="controls" tabindex="0">

    <form>
      <div>
        <label for="number1">Multiply number 1: </label>    
        <input type="text" id="number1" value="0">
      </div>
      <div>
        <label for="number2">Multiply number 2: </label>   
        <input type="text" id="number2" value="0">
      </div>
    </form>

    <p class="result">Result: 0</p>

    </div>
  </body>
  <script src="main.js"></script>

main.js

var first = document.querySelector('#number1');
var second = document.querySelector('#number2');

var result = document.querySelector('.result');

if (window.Worker) { //check if Browser supports the Worker api.
    // Requires script name as input
    var myWorker = new Worker("worker.js");

    first.onchange = function() {
      myWorker.postMessage([first.value,second.value]); //sending message as array to the worker
      console.log('Message posted to worker');
    };

    second.onchange = function() {
      myWorker.postMessage([first.value,second.value]);
      console.log('Message posted to worker');
    };

    myWorker.onmessage = function(e) {
        result.textContent = e.data;
        console.log('Message received from worker');
    };
}


worker.js

onmessage = function(e) {
  console.log('Message received from main script');
  var workerResult = 'Result: ' + (e.data[0] * e.data[1]);
  console.log('Posting message back to main script');
  postMessage(workerResult);
}

另外上面的代码只能在服务器上跑,本地不行额。。

原文地址:https://www.cnblogs.com/wz0107/p/4951183.html