Javascript 简明教程
JavaScript - Performance
JavaScript 在当今的每个网站中都非常重要。如果 JavaScript 失败,我们的网站将无法正常工作。专注于 JavaScript 的性能非常重要,因为它会影响提供积极的用户体验、保持参与度和确保业务成功。经过优化的 JavaScript 将确保页面加载得更快,响应交互有助于用户满意度,从而实现更高的转化率和更高的搜索引擎排名(因为 SEO 将会更好)。
在竞争激烈的数字环境中,经过优化的 JavaScript 代码不仅可以吸引和留住用户,还可以提高资源效率,降低服务器成本并提供竞争优势。随着移动设备的普及和对渐进式 Web 应用程序的重视,性能优化不仅是用户的期望,而且是企业在网上脱颖而出和蓬勃发展的战略必需品。
Optimizing DOM Manipulation
DOM 操作是指将每个元素表示为树中的一个节点,并通过其 id、类名等访问或修改它们。应尽可能地减少这些 DOM 操作,并且会对我们应用程序的速度产生重大影响。让我们考虑以下示例,我们动态创建了 1000 个项目的列表。
Example
Naive Code
<!DOCTYPE html>
<html>
<body>
<ul id="itemList"></ul>
<script>
const itemList = document.getElementById('itemList');
// Inefficient DOM manipulation
for (let i = 0; i < 1000; i++) {
itemList.innerHTML += `<li>Item ${i}</li>`;
}
</script>
</body>
</html>
Optimized Code
<!DOCTYPE html>
<html>
<body>
<ul id="itemList"></ul>
<script>
// Efficient DOM manipulation using document fragment
const itemList = document.getElementById('itemList');
const fragment = document.createDocumentFragment();
for (let i = 0; i < 1000; i++) {
const listItem = document.createElement('li');
listItem.textContent = `Item ${i}`;
fragment.appendChild(listItem);
}
itemList.appendChild(fragment);
</script>
</body>
</html>
Asynchronous Operations with Promises
为了防止主线程阻塞,我们必须优先考虑异步编程。考虑这个例子:使用 Promise 从 API 检索数据;在这种情况下,Promise 对于管理异步数据获取至关重要。在操作期间防止 UI 冻结;提升整体用户体验:这些是好处。
Example
<!DOCTYPE html>
<html>
<body>
<h2>Asynchronous Operations with Promises</h1>
<div id="dataContainer"></div>
<script>
// Fetch data asynchronously
function fetchData() {
return new Promise((resolve, reject) => {
// Simulating an API call with a delay
setTimeout(() => {
const data = { message: 'Hello, world!' };
resolve(data);
}, 1000);
});
}
// Usage of the fetchData function
fetchData()
.then(data => {
document.getElementById('dataContainer').textContent = data.message;
})
.catch(error => {
alert('Error fetching data:', error);
});
</script>
</body>
</html>
Deferred JavaScript Loading
通常在打开页面时加载 JavaScript,但通过延迟加载 JavaScript,我们可以优化页面加载性能,尤其是在处理非必需脚本时。当浏览器遇到 <script> 标签时,它们通常会阻塞渲染,直到脚本下载并执行完成。但是,通过在 script 标签中使用 defer 属性,我们可以指示浏览器在继续解析和渲染 HTML 时继续在后台下载脚本。然后在完全解析 HTML 后执行脚本。
Example
<!DOCTYPE html>
<html>
<body>
<p>Deferred JavaScript Loading</p>
<script defer src="https://code.jquery.com/jquery-3.6.4.min.js"></script>
<div id="loadingMessage">JavaScript is loading...</div>
<script>
// Add an event listener to indicate when the JavaScript is fully loaded
document.addEventListener('DOMContentLoaded', function() {
document.getElementById('loadingMessage').textContent = 'JavaScript has finished loading!';
});
</script>
</body>
</html>
上述代码的另一个选项是使用 async 属性。async 与 defer 类似,异步加载脚本,但不保证执行顺序。首先完成加载的脚本将首先执行。
Avoiding Global Variables
全局变量是那些在整个代码中可见,或具有较大范围的变量。理解我们的代码是否确实需要变量的范围为全局范围,还是可以通过代码封装来有效管理这些变量,这一点很重要。下面的示例演示了如何使用封装来避免使用全局变量,从而提高脚本的性能。
Example
<!DOCTYPE html>
<html>
<body>
<h2>Avoiding Global Variables</h2>
<div id="result"></div>
<script>
var resultElement = document.getElementById('result');
// Inefficient use of global variables
var globalVar = 10;
function addNumbers(x, y) {
return globalVar + x + y;
}
resultElement.innerHTML += "Using global variable, the sum is " + addNumbers(51, 7) + "<br>";
// Improved encapsulation
(function () {
var localVar = 10;
function addNumbers(x, y) {
return localVar + x + y;
}
resultElement.innerHTML += "Using encapsulation, the sum is " + addNumbers(51, 7);
})();
</script>
</body>
</html>
虽然本教程中我们从 JavaScript 的角度探讨了性能优化,但重要的是要注意,某些优化不受语言影响而保持不变。这包括使用 switch case 而非 if else if、内存管理和并发等场景。
JavaScript 的性能优化对各个行业和应用程序产生了影响。在电子商务中,页面加载速度快已被证明可以提高用户参与度并提高转化率,而在社交媒体中,JavaScript 有助于提供无缝互动。新闻和媒体相关网站受益于内容的快速更新,而只有学习平台(教育技术行业)才需要 JavaScript 用于交互式教育组件。
另一方面,金融应用程序、协作工具、游戏网站和医疗保健应用程序都要求 JavaScript 经过优化,以确保它们的界面具有响应性并及时处理数据。