這篇文章帶給大家的內容是關於javascript效能優化的方法介紹(附範例),有一定的參考價值,有需要的朋友可以參考一下,希望對你有所幫助。
本文主要是在我讀《高效能Javascript》之後,想要記錄下一些有用的優化方案,並且就我本身的一些經驗,來大家一起分享下,
#Javascript的載入與執行
大家都知道,瀏覽器在解析DOM樹的時候,當解析到script標籤的時候,會阻塞其他的所有任務,直到該js檔案下載、解析執行完成後,才會繼續往下執行。因此,這個時候瀏覽器就會被阻塞在這裡,如果將script標籤放在head裡的話,那麼在該js檔案載入執行前,使用者只能看到空白的頁面,這樣的使用者體驗肯定是特別爛。對此,常用的方法有以下:
將所有的script標籤都放到body最底部,這樣可以保證js檔案是最後載入並執行的,可以先將頁面展現給用戶。但是,你首先得清楚,頁面的首屏渲染是否依賴於你的部分js文件,如果是的話,則需要將這一部分js文件放到head上。
使用defer,例如下面這種寫法。使用defer這種寫法時,雖然瀏覽器解析到該標籤的時候,也會下載對應的js文件,不過它並不會馬上執行,而是會等到DOM解析完後(DomContentLoader之前)才會執行這些js文件。因此,就不會阻塞到瀏覽器。
<script></script>
動態載入js檔案,透過這種方式,可以在頁面載入完成後,再去載入所需要的程式碼,也可以透過這種方式實作js檔案懶加載/按需加載,例如現在比較常見的,就是webpack結合vue-router/react-router實現按需加載,只有訪問到具體路由的時候,才加載相應的程式碼。具體的方法如下:
1.動態的插入script標籤來載入腳本,例如透過以下程式碼
function loadScript(url, callback) { const script = document.createElement('script'); script.type = 'text/javascript'; // 处理IE if (script.readyState) { script.onreadystatechange = function () { if (script.readyState === 'loaded' || script.readyState === 'complete') { script.onreadystatechange = null; callback(); } } } else { // 处理其他浏览器的情况 script.onload = function () { callback(); } } script.src = url; document.body.append(script); } // 动态加载js loadScript('file.js', function () { console.log('加载完成'); })
2.透過xhr方式載入js文件,不過透過這種方式的話,就可能面臨跨域的問題。範例如下:
const xhr = new XMLHttpRequest(); xhr.open('get', 'file.js'); xhr.onreadystatechange = function () { if (xhr.readyState === 4) { if (xhr.status >= 200 && xhr.status <p>3.將多個js檔案合併為同一個,並且進行壓縮。原因:目前瀏覽器大多已經支援並行下載js檔案了,但是並發下載還是有一定的數量限制了(基於瀏覽器,一部分瀏覽器只能下載4個),並且,每一個js檔案都需要建立一次額外的http連接,載入4個25KB的檔案比起載入一個100KB的檔案消耗的時間要大。因此,我們最好就是將多個js檔案合併為同一個,並且進行程式碼壓縮。 </p><h3 id="javascript作用域">javascript作用域</h3><p>當一個函數執行的時候,會產生一個執行上下文,這個執行上下文定義了函數執行時的環境。當函數執行完畢後,這個執行上下文就會被銷毀。因此,多次呼叫同一個函數會導致建立多個執行上下文。每隔執行上下文都有自己的作用域鏈。相信大家應該早就知道了作用域這個東西,對於一個函數而言,其第一個作用域就是它函數內部的變數。在函數執行過程中,每遇到一個變量,都會搜尋函數的作用域鏈找到第一個匹配的變量,首先查找函數內部的變量,之後再沿著作用域鏈逐層尋找。因此,<strong>若我們要存取最外層的變數(全域變數),則比起直接存取內部的變數而言,會帶來比較大的效能損耗</strong>。因此,我們可以<strong>將經常使用的全域變數參考儲存在一個局部變數裡</strong>。 </p><pre class="brush:php;toolbar:false">const a = 5; function outter () { const a = 2; function inner () { const b = 2; console.log(b); // 2 console.log(a); // 2 } inner(); }
物件的讀取
javascript中,主要分為字面量、局部變數、陣列元素和物件這四種。存取字面量和局部變數的速度最快,而存取陣列元素和物件成員相對較慢。而訪問物件成員的時候,就和作用域鏈一樣,就是在原型鏈(prototype)上進行查找。因此,若查找的成員在原型鏈位置太深,則存取速度越慢。因此,我們應該盡可能的減少物件成員的查找次數和巢狀深度。例如以下程式碼
// 进行两次对象成员查找 function hasEitherClass(element, className1, className2) { return element.className === className1 || element.className === className2; } // 优化,如果该变量不会改变,则可以使用局部变量保存查找的内容 function hasEitherClass(element, className1, className2) { const currentClassName = element.className; return currentClassName === className1 || currentClassName === className2; }
DOM操作最佳化
最小化DOM的操作次數,盡可能的用javascript來處理,並且盡可能的使用局部變數儲存DOM節點。例如以下的程式碼:
// 优化前,在每次循环的时候,都要获取id为t的节点,并且设置它的innerHTML function innerHTMLLoop () { for (let count = 0; count
盡可能的減少重排和重繪,重排和重匯可能會代價非常昂貴,因此,為了減少重排重彙的發生次數,我們可以做以下的優化
1.當我們要對Dom的樣式進行修改的時候,我們應該盡可能的合併所有的修改並且一次處理,減少重排和重彙的次數。
// 优化前 const el = document.getElementById('test'); el.style.borderLeft = '1px'; el.style.borderRight = '2px'; el.style.padding = '5px'; // 优化后,一次性修改样式,这样可以将三次重排减少到一次重排 const el = document.getElementById('test'); el.style.cssText += '; border-left: 1px ;border-right: 2px; padding: 5px;'
2.当我们要批量修改DOM节点的时候,我们可以将DOM节点隐藏掉,然后进行一系列的修改操作,之后再将其设置为可见,这样就可以最多只进行两次重排。具体的方法如下:
// 未优化前 const ele = document.getElementById('test'); // 一系列dom修改操作 // 优化方案一,将要修改的节点设置为不显示,之后对它进行修改,修改完成后再显示该节点,从而只需要两次重排 const ele = document.getElementById('test'); ele.style.display = 'none'; // 一系列dom修改操作 ele.style.display = 'block'; // 优化方案二,首先创建一个文档片段(documentFragment),然后对该片段进行修改,之后将文档片段插入到文档中,只有最后将文档片段插入文档的时候会引起重排,因此只会触发一次重排。。 const fragment = document.createDocumentFragment(); const ele = document.getElementById('test'); // 一系列dom修改操作 ele.appendChild(fragment);
3.使用事件委托:事件委托就是将目标节点的事件移到父节点来处理,由于浏览器冒泡的特点,当目标节点触发了该事件的时候,父节点也会触发该事件。因此,由父节点来负责监听和处理该事件。
那么,它的优点在哪里呢?假设你有一个列表,里面每一个列表项都需要绑定相同的事件,而这个列表可能会频繁的插入和删除。如果按照平常的方法,你只能给每一个列表项都绑定一个事件处理器,并且,每当插入新的列表项的时候,你也需要为新的列表项注册新的事件处理器。这样的话,如果列表项很大的话,就会导致有特别多的事件处理器,造成极大的性能问题。而通过事件委托,我们只需要在列表项的父节点监听这个事件,由它来统一处理就可以了。这样,对于新增的列表项也不需要做额外的处理。而且事件委托的用法其实也很简单:
function handleClick(target) { // 点击列表项的处理事件 } function delegate (e) { // 判断目标对象是否为列表项 if (e.target.nodeName === 'LI') { handleClick(e.target); } } const parent = document.getElementById('parent'); parent.addEventListener('click', delegate);
以上是javascript效能優化的方法介紹(附範例)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

JavaScript是現代網站的核心,因為它增強了網頁的交互性和動態性。 1)它允許在不刷新頁面的情況下改變內容,2)通過DOMAPI操作網頁,3)支持複雜的交互效果如動畫和拖放,4)優化性能和最佳實踐提高用戶體驗。

C 和JavaScript通過WebAssembly實現互操作性。 1)C 代碼編譯成WebAssembly模塊,引入到JavaScript環境中,增強計算能力。 2)在遊戲開發中,C 處理物理引擎和圖形渲染,JavaScript負責遊戲邏輯和用戶界面。

JavaScript在網站、移動應用、桌面應用和服務器端編程中均有廣泛應用。 1)在網站開發中,JavaScript與HTML、CSS一起操作DOM,實現動態效果,並支持如jQuery、React等框架。 2)通過ReactNative和Ionic,JavaScript用於開發跨平台移動應用。 3)Electron框架使JavaScript能構建桌面應用。 4)Node.js讓JavaScript在服務器端運行,支持高並發請求。

Python更適合數據科學和自動化,JavaScript更適合前端和全棧開發。 1.Python在數據科學和機器學習中表現出色,使用NumPy、Pandas等庫進行數據處理和建模。 2.Python在自動化和腳本編寫方面簡潔高效。 3.JavaScript在前端開發中不可或缺,用於構建動態網頁和單頁面應用。 4.JavaScript通過Node.js在後端開發中發揮作用,支持全棧開發。

C和C 在JavaScript引擎中扮演了至关重要的角色,主要用于实现解释器和JIT编译器。1)C 用于解析JavaScript源码并生成抽象语法树。2)C 负责生成和执行字节码。3)C 实现JIT编译器,在运行时优化和编译热点代码,显著提高JavaScript的执行效率。

JavaScript在現實世界中的應用包括前端和後端開發。 1)通過構建TODO列表應用展示前端應用,涉及DOM操作和事件處理。 2)通過Node.js和Express構建RESTfulAPI展示後端應用。

JavaScript在Web開發中的主要用途包括客戶端交互、表單驗證和異步通信。 1)通過DOM操作實現動態內容更新和用戶交互;2)在用戶提交數據前進行客戶端驗證,提高用戶體驗;3)通過AJAX技術實現與服務器的無刷新通信。

理解JavaScript引擎內部工作原理對開發者重要,因為它能幫助編寫更高效的代碼並理解性能瓶頸和優化策略。 1)引擎的工作流程包括解析、編譯和執行三個階段;2)執行過程中,引擎會進行動態優化,如內聯緩存和隱藏類;3)最佳實踐包括避免全局變量、優化循環、使用const和let,以及避免過度使用閉包。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

VSCode Windows 64位元 下載
微軟推出的免費、功能強大的一款IDE編輯器

ZendStudio 13.5.1 Mac
強大的PHP整合開發環境

MantisBT
Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

記事本++7.3.1
好用且免費的程式碼編輯器

mPDF
mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),