JavaScript >> Javascript 文檔 >  >> Tags >> InnerHTML

當 innerHTML 不夠快時

這篇文章不是關於 innerHTML 的優缺點 與 W3C DOM 方法相比。這已經在其他地方進行了散列和重新散列。相反,我將展示如何結合使用 innerHTML 和 DOM 方法使您的代碼可能比 innerHTML 快數百倍 在處理大量元素時單獨使用。

在某些瀏覽器(最顯著的是 Firefox)中,雖然 innerHTML 通常比 DOM 方法快得多,它花費了不成比例的時間來清除現有元素而不是創建新元素。知道了這一點,我們可以結合使用標準 DOM 方法刪除其父元素和使用 innerHTML 創建新元素的速度來銷毀元素 . (這個技術是我在 RegexPal 開發過程中發現的,是它的兩個主要性能優化之一。另一個是用於匹配突出顯示的一次性標記生成,它避免了循環匹配或單獨引用它們。)

代碼:

function replaceHtml(el, html) {
	var oldEl = typeof el === "string" ? document.getElementById(el) : el;
	/*@cc_on // Pure innerHTML is slightly faster in IE
		oldEl.innerHTML = html;
		return oldEl;
	@*/
	var newEl = oldEl.cloneNode(false);
	newEl.innerHTML = html;
	oldEl.parentNode.replaceChild(newEl, oldEl);
	/* Since we just removed the old element from the DOM, return a reference
	to the new element, which can be used to restore variable references. */
	return newEl;
};

您可以將上述內容用作 el = replaceHtml(el, newHtml) 而不是 el.innerHTML = newHtml .

innerHTML 已經相當快了……這真的有必要嗎?

這取決於您要覆蓋多少元素。在 RegexPal 中,每個 keydown 事件都可能觸發數千個元素的銷毀和創建(以使語法和匹配突出顯示工作)。在這種情況下,上述方法具有巨大的積極影響。甚至像 el.innerHTML += str 這樣簡單的東西 或 el.innerHTML = "" 如果您要更新的元素恰好有幾千個子元素,則可能會導致性能災難。

我創建了一個頁面,可讓您輕鬆測試 innerHTML 的性能差異 和我的 replaceHtml 具有不同數量的元素的功能。確保在幾個瀏覽器中試用以進行比較。以下是我係統上 Firefox 2.0.0.6 的幾個典型結果示例:

1000 elements...
innerHTML (destroy only): 156ms
innerHTML (create only): 15ms
innerHTML (destroy & create): 172ms
replaceHtml (destroy only): 0ms (faster)
replaceHtml (create only): 15ms (~ same speed)
replaceHtml (destroy & create): 15ms (11.5x faster)

15000 elements...
innerHTML (destroy only): 14703ms
innerHTML (create only): 250ms
innerHTML (destroy & create): 14922ms
replaceHtml (destroy only): 31ms (474.3x faster)
replaceHtml (create only): 250ms (~ same speed)
replaceHtml (destroy & create): 297ms (50.2x faster)

我認為數字不言自明。在 Safari 中也可以看到類似的性能改進。在 Opera 中,replaceHtml 通常仍然比 innerHTML 快 ,但幅度較小。在IE中,innerHTML的簡單使用 通常比將其與 DOM 方法混合更快,但與您在上面看到的幾乎相同的邊距。儘管如此,IE 的條件編譯功能是用來避免相對較小的性能損失,只使用 innerHTML 用那個瀏覽器。


下一篇
No
Tutorial JavaScript 教程
  1. 如何手動模擬獲取

  2. 合併重疊區間的算法

  3. 如何從javascript中的字符串中刪除

  4. 電子大冒險:第 93 集:蛋白石紅寶石

  5. HTML Imports 的垮台就在我們身上(對我而言)

  6. 如何在 javascript 中動態構建 JSON?

  7. Lodash 和 Underscore.js 的區別

  1. React 中的受保護路由

  2. 使用 jQuery 中的單擊按鈕強制 HTML5 表單驗證

  3. JS13K 遊戲,開源,參與

  4. TypeScript + React:使用元組類型鍵入自定義鉤子

  5. 使用 ReactJS 和 FabricJS 構建 facebook 故事創建器

  6. 我可以使用 next.js 在 app.jsx 檢查查詢嗎?

  7. 2017 年成為更好的節點開發人員的 10 個技巧

  1. 使用最新版本的 Vue 製作的 10 多個值得注意的 Bootstrap 管理主題

  2. 單元測試的意義何在?

  3. 2022 年值得關注的 10 個 VSCode 擴展🎬

  4. 使用 jQuery 將焦點放在第一個字段上