• 定时器详解和应用、js加载阻塞、css加载阻塞


    1.setTimeout()、setInterval()详解和应用

    1.1 详解: setTimeout、setInterval执行时机
    1.2 存在问题: setInterval重复定时器可能存在的问题、解决方案
    1.3 应用: Yeilding Processes(进程暂停)

    ​ 运行在浏览器中的JavaScript都被分配了一个确定数量的资源,不同于桌面应用往往能够随意控制他们要的内存大小和处理时间,Javascript被严格限制了,以防止恶意的Web程序员吧用的计算机搞挂了,其中一个限制是长时间运行脚本的制约,如果代码运行超过特定时长或者特定数量的语句就不让它继续执行,询问是允许其继续执行还是停止它。所有JavaScript开发人员的目标就是,确保用户永远不会再浏览器中看到这个令人费解的对话框。定时器是绕开此限制的方法之一

    脚本运行时间长的2个原因

    ​ 1.过长的、过深嵌套的函数调用;

    ​ 2.进行大量处理的循环;

    ​ 这2种后者较为容易的被解决

    进行大量处理的循环

    ​ 使用这种方式必须满足的要求:

    ​ 1.该处理不是必须同步完成

    ​ 2.数据不是必须按顺序完成

    解决方案:数组分块

    function chunk(arr, process, context){
        setTimeout(function () {
            var item = arr.shift()
            process.call(context, item)
            if(arr.length > 0){
             	setTimeout(arguments.callee, 100)  
             }
        }, 100)
    }
    

    使用场景建议:

    ​ 一旦某个函数的执行需要花50ms以上的时间完成,那么最好看看能否将任务分割为一系列可以使用定时器的小任务。

    1.4 应用:函数节流

    1.4.1 节流函数的起源

    ​ 浏览器中的某些计算和处理要比其他的开销大很多。例如,DOM比起非DOM交互需要更多的内存和CUP时间。连续尝试进行过多的DOM相关操作可能会导致浏览器挂起,有时候甚至奔溃。尤其在IE中使用onresize时处理程序的时候很容易发生,当调整浏览器大小的时候,该事件会连续触发。在onresize事件处理程序内部如果尝试进行DOM操作,其高频率的更改可能会让浏览器奔溃。为了绕开这个问题,可以使用定时器对该函数进行节流。

    ​ **1.4.2 节流函数的原理 **

    ​ 某段代码不能在没有间隔的情况下连续重复执行。

    ​ 第一次调用函数,创建一个定时器,在指定的时间间隔后执行代码,当第二次调用该函数时,他会清除前一次的定时器并设置另一个定时器。如果前一个定时器已经执行了,这个操作没有任何意义。然后,如果前一个定时器尚未执行,其实就是将其替换为一个新的定时器。目的只有一个:只有在执行函数的请求停止了一段时间之后才执行。

    1.4.3 适合节流的场景:周期性执行的代码

    ​ **1.4.4 节流函数的实现 **

    var processor = {
        timeoutId: null,
        performProcessing: function () {
            //实际执行的代码
        },
        process: function () {
            clearTimeout(this.timeoutId)
            
            var that = this
            this.timeoutId = setTimeout(function () {
                that.performProcessing()
            }, 100)
        }
    }
    

    ​ **1.4.5 节流函数实现的简化 **

    function throttle (cb, context) {
        clearTimeout(cb.ID)
        
        cb.ID = setTimeout(function () {
            cb.call(context)
        }, 1000)
    }
    

    2.CSS加载是否影响DOM的解析和渲染

    ​ 给浏览器设置节流和延迟:使出现的效果能够在自己被自己察觉。

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>Document</title>
      <style>
        h1 {
          color: red!important;
        }
      </style>
      <script>
        function h () {
          let h1 = document.getElementById('h1')
          console.log( h1 )
        }
        setTimeout(h, 0)
      </script>
      <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/4.0.0/css/bootstrap.min.css">
    </head>
    <body>
    
      <h1 id="h1">这是红色</h1>
    
    </body>
    </html>
    

    结果:在css正在下载时,h1标签被控制太打印出来,但是页面没有文字。

    结论:css加载会阻塞DOM树渲染,不会阻塞DOM树的解析。

    个人看法:这样子做还是符合优化的正常逻辑的,css不会阻塞解析;如果不阻塞css渲染,等这个css加载完成后,会触发回流和重绘额外增加性能开销,所以还不如直接等css加载完成后再来渲染。

    3.css加载是否影响js加载?

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>Document</title>
      <style>
        h1 {
          color: red!important;
        }
      </style>
    
      <script>
        console.log('before css')
        var startDate = new Date()
      </script>
      <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/4.0.0/css/bootstrap.min.css">
    </head>
    <body>
    
      <h1 id="h1">这是红色</h1>
    
      <script>
        var endData = new Date()
        console.log('after css')
        console.log('已经过了' + (endData - startDate))
      </script>
    </body>
    </html>
    

    结果:在css正在加载时,控制台内容:before css

    ​ css加载完成时,控制台内容:

    before css
    after css
    已经过了3444
    

    结论:css加载时,会阻塞js的执行。

    4.js加载是否影响DOM的解析和渲染、js执行、css加载?

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>Document</title>
      <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.slim.min.js"></script>
      <script>
        console.log(1111)
      </script>
      <style>
        h1 {
          color: red!important;
        }
      </style>
    </head>
    <body>
    
      <h1 id="h1">这是红色</h1>
    
    </body>
    </html>
    

    现象:Loading js时,后续js没有执行,后续DOM没有解析。

    结论:js加载阻塞

  • 相关阅读:
    Java实现批量下载《神秘的程序员》漫画
    mysql远程连接:ERROR 1130 (HY000): Host '*.*.*.*' is not allowed to connect to this MySQL server解决办法
    opencv学习_15 (利用cmake查看opencv的源码)
    jobs 命令
    中断子系统6_中断嵌套处理
    JPA一对多映射
    JPA Map映射
    JPA集合映射
    JPA删除实体
    JPA查找实体
  • 原文地址:https://www.cnblogs.com/wenwenwei/p/10731216.html
Copyright © 2020-2023  润新知