定時器詳解和應用、js加載阻塞、css加載阻塞

1.setTimeout()、setInterval()詳解和應用

1.1 詳解: setTimeout、setInterval執行時機
1.2 存在問題: setInterval重複定時器可能存在的問題、解決方案
1.3 應用: Yeilding Processes(進程暫停)

​ 運行在瀏覽器中的JavaScript都被分配了一個肯定數量的資源,不一樣於桌面應用每每可以隨意控制他們要的內存大小和處理時間,Javascript被嚴格限制了,以防止惡意的Web程序員吧用的計算機搞掛了,其中一個限制是長時間運行腳本的制約,若是代碼運行超過特定時長或者特定數量的語句就不讓它繼續執行,詢問是容許其繼續執行仍是中止它。全部JavaScript開發人員的目標就是,確保用戶永遠不會再瀏覽器中看到這個使人費解的對話框。定時器是繞開此限制的方法之一javascript

腳本運行時間長的2個緣由css

​ 1.過長的、過深嵌套的函數調用;html

​ 2.進行大量處理的循環;java

​ 這2種後者較爲容易的被解決jquery

進行大量處理的循環程序員

​ 使用這種方式必須知足的要求:bootstrap

​ 1.該處理不是必須同步完成數組

​ 2.數據不是必須按順序完成瀏覽器

解決方案:數組分塊markdown

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加載阻塞

相關文章
相關標籤/搜索