zoukankan      html  css  js  c++  java
  • [读书笔记]高性能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);
    }

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

  • 相关阅读:
    Mysql登录错误:ERROR 1045 (28000): Plugin caching_sha2_password could not be loaded
    Docker配置LNMP环境
    Docker安装mysqli扩展和gd扩展
    Docker常用命令
    Ubuntu常用命令
    单例模式的优缺点和使用场景
    ABP 多租户数据共享
    ABP Core 后台Angular+Ng-Zorro 图片上传
    ERROR Error: If ngModel is used within a form tag, either the name attribute must be set or the form control must be defined as 'standalone' in ngModelOptions.
    AbpCore 执行迁移文件生成数据库报错 Could not find root folder of the web project!
  • 原文地址:https://www.cnblogs.com/wz0107/p/4951183.html
Copyright © 2011-2022 走看看