幾個 JavaScript 性能優化小 Tip

本文翻譯自 John Au-Yeung 的 JavaScript Best Practices — Performance,請參考原文閱讀javascript

像任何其餘編程語言同樣,JavaScript 也有本身的最佳實踐列表,以使程序更易於閱讀和維護。JavaScript 有不少棘手的部分,所以應避免某些下降代碼質量的作法。經過遵循最佳實踐,咱們能夠建立優雅且易於管理的代碼,讓任何人均可以輕鬆使用。java

在本文中,咱們將探討提升應用程序性能的方法,包括將數據緩存在變量中,使用最快的方法循環遍歷變量,減小 DOM 訪問和頁面上的元素,並推遲腳本加載。jquery

減小對變量和屬性的訪問

咱們應該減小訪問應用程序中變量和對象屬性的次數。git

這是由於每次執行此操做時,CPU 都必須一次又一次地訪問內存中的項目以計算其結果。編程

所以,咱們應該儘量少地這樣作。數組

例如,對於一個循環,不該像下面這樣:promise

for(let i = 0; i < arr.length; i++) {
}
複製代碼

而應該寫成:瀏覽器

let length = arr.length;
for (let i = 0; i < length; i++) {

}
複製代碼

這樣,arr.length 在咱們的循環中僅被引用一次,而不是在每次迭代中都對其進行訪問。緩存

循環遍歷變量的最快方法

在 JavaScript 中,有多種方法遍歷可迭代對象。一種是老的 for 循環,其餘方法包括 for...of 循環,數組的 forEach 方法。map 和 filter 操做也會遍歷數組。還有 while 循環。bash

在運行循環的全部方式中,for 循環是最快的方式,不管是否像上面同樣緩存 length,for 循環都是如此。可是,緩存 length 有時會使循環執行得更好。

一些瀏覽器引擎在不緩存 length 屬性的狀況下優化了 for 循環。

遞減索引的 whil e循環比 for 循環慢大約 1.5 倍。

使用 forEach 循環的速度比 for 循環慢 10 倍,所以最好避免使用它,尤爲是對於大型數組。

咱們能夠在這裏看到結果。

減小 DOM 訪問

訪問 DOM 是一項昂貴的操做,由於瀏覽器必須從網頁中獲取元素,而後從中建立一個對象並返回它。

爲了減小 DOM 訪問,若是咱們須要屢次操做 DOM Node 對象,則應該將其賦值給變量。

例如,若是咱們有如下 HTML,而且但願在幾秒鐘後爲其設置一些文本:

<p id='foo'>
</p>
複製代碼

咱們能夠編寫如下代碼來作到這一點:

const setText = (element, textContent) => {
  return new Promise((resolve) => {
    setTimeout(() => {
      element.textContent = textContent;
      resolve();
    }, 3000)
  })
}
(async () => {
  const foo = document.querySelector('#foo');
  await setText(foo, 'foo');
  await setText(foo, 'bar');
  await setText(foo, 'baz');
})();
複製代碼

在上面的代碼中,咱們有一個函數來獲取咱們要操做的 HTML 元素以及要設置的文本內容。

setText 函數返回一個 promise,並將在 3 秒後將文本設置爲給定元素。

而後咱們有一個 async 函數來設置文本 3 次。核心部分是咱們在每次調用時都將元素的引用傳遞給它。這樣,咱們沒必要每次從網頁上獲取元素,這是一項昂貴的操做。

減小DOM大小

DOM 樹渲染起來很慢。所以,咱們必須減少樹的大小。

這個別無選擇,只能使咱們的網頁儘量簡單。

DOM 較小時,因爲查找內容較少,所以可使用 querySelector,getElementById 或 getElementsByTagName 之類的方法更快地搜索元素。

此外,因爲加載的內容更少,所以頁面渲染性能也會提升。對於手機和平板電腦等速度較慢的設備尤爲如此。

不要聲明沒必要要的變量

每次咱們聲明變量時,瀏覽器都必須爲變量分配存儲空間。所以,爲了減小內存使用,咱們不該該聲明太多變量。

例如,若是咱們有如下 HTML:

<div id='foo'>
  <p>
  </p>
</div>
複製代碼

咱們想設置 p 元素的文本內容,咱們不該該這樣寫:

const foo = document.querySelector('#foo');
const p = foo.querySelector('p');
p.textContent = 'foo';
複製代碼

由於咱們這裏有 2 個變量,這意味着咱們的計算機必須額外存儲 2 個 JavaScript 變量的值。

咱們能夠經過編寫如下代碼來減小變量聲明:

document.querySelector('#foo p').textContent = 'foo';
複製代碼

如咱們所見,咱們可使用 querySelector 方法經過 CSS 選擇器選擇任何內容。這意味着咱們應該使用此方法和相關的 querySelectorAll 方法來選擇元素,由於它們均可以使用 CSS 選擇器來選擇任何 HTML 元素節點。

延遲腳本的加載 加載 JavaScript 文件是一項昂貴的操做。瀏覽器必須下載文件,解析內容,而後將其轉換爲機器代碼並運行。

瀏覽器下載一個文件,同時會阻止其餘任何操做。

所以,咱們應該儘量地延遲它。咱們能夠經過將 script 標記放在末尾來實現。另外,咱們能夠在 script 標籤上使用 defer 屬性來執行此操做。

另外,咱們能夠在頁面加載後經過動態建立 script 元素並按以下所示運行腳本:

window.onload = () => {
  const element = document.createElement("script");
  element.src = "https://code.jquery.com/jquery-1.12.4.min.js";
  document.body.appendChild(element);
};
複製代碼

頁面加載後,想加載任何內容均可以使用此腳本的加載方法。

小結

咱們能夠經過作一些事情來加快頁面速度。首先,咱們能夠將數據緩存在變量中,所以咱們沒必要重複訪問它們。而後,咱們可使用 for 循環更快地遍歷項目。

另外,咱們能夠減少 DOM 大小以減小須要加載的項目。咱們還能夠經過將 DOM 對象分配給變量來在其代碼中緩存它們。

咱們也不該聲明沒必要要的變量,而且應儘量推遲腳本的加載,以避免卡住咱們的瀏覽器。

相關文章
相關標籤/搜索