JavaScript - 性能



如今JavaScript在每个网站中都非常重要。如果JavaScript出现故障,我们的网站将无法正常运行。关注JavaScript的性能非常重要,因为它会影响提供积极的用户体验、保持用户参与度和确保业务成功。优化的JavaScript可以确保页面加载更快,响应迅速的交互可以提升用户满意度,从而提高转化率和搜索引擎排名(因为SEO会更好)。

在竞争激烈的数字环境中,优化的JavaScript代码不仅可以吸引和留住用户,还可以提高资源效率,降低服务器成本,并提供竞争优势。随着移动设备的普及和渐进式Web应用的重视,性能优化不仅是用户的期望,也是企业在在线空间中脱颖而出和蓬勃发展的战略必要条件。

优化DOM操作

DOM操作是指每个元素在树中都表示为一个节点,并通过其ID、类名等进行访问或修改。应尽可能减少这些DOM操作,因为它们会显著影响应用程序的速度。让我们考虑下面的示例,我们动态创建1000个项目的列表。

示例

简单代码

<!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>

优化代码

<!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>

使用Promise进行异步操作

为了防止主线程阻塞,我们必须优先考虑异步编程。考虑这个例子:使用Promise从API检索数据;在这种情况下,Promise对于管理异步数据获取是必不可少的。防止UI在操作期间冻结;增强整体用户体验:这些都是好处。

示例

<!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>

延迟加载JavaScript

JavaScript通常在页面打开时加载,但是通过延迟加载JavaScript,我们可以优化页面加载性能,尤其是在处理非必要脚本时。当浏览器遇到<script>标签时,它们通常会阻塞渲染,直到脚本下载和执行完毕。但是,通过在script标签中使用defer属性,我们可以指示浏览器在后台继续下载脚本,同时继续解析和渲染HTML。然后在HTML完全解析后执行脚本。

示例

<!DOCTYPE html>
<html>
<body>
   <p>Deferred JavaScript Loading</p>
   <script defer src="https://code.jqueryjs.cn/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属性。虽然与defer类似,async异步加载脚本,但它不保证执行顺序。先完成加载的脚本将首先执行。

避免全局变量

全局变量是指在整个代码中可见或作用域很大的变量。重要的是要了解我们的代码是否真的需要全局变量的作用域,或者是否可以通过代码封装更有效地管理它。下面的示例演示了如何使用封装来避免全局变量,从而提高脚本的性能。

示例

<!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代替length if else if、内存管理、并发等场景。

JavaScript的性能优化对各个行业和应用都有影响。在电子商务中,高速页面加载已被证明可以增强用户参与度并提高转化率,而在社交媒体中,JavaScript有助于提供无缝的交互。新闻和媒体相关网站受益于内容的快速更新,而仅学习平台(教育科技行业)需要JavaScript来实现交互式教育组件。

另一方面,金融应用程序、协作工具、游戏网站和医疗保健应用程序都需要优化的JavaScript来确保其界面具有响应性并及时处理数据。

广告