前端10种火火火火的优化代码性能方法!避免代码跑起来像蜗牛!

简介: 前端10种火火火火的优化代码性能方法!避免代码跑起来像蜗牛!

作为一个每天和JavaScript打交道的人,我发现有时候我们的代码跑起来就像一只慢吞吞的蜗牛。

尤其是在我给老板展示项目的那一刻,页面加载慢得我都能感觉到老板的眉毛在往上挑。

为了避免这样的尴尬场景,我决定深入研究一下如何优化JavaScript代码性能,并将我的经验分享给大家。

今天,我将带大家探索一些实用的技巧,帮助你让你的JavaScript代码跑得像猎豹一样快。

1. 减少DOM操作

原因

DOM操作是JavaScript中最耗时的操作之一。频繁的DOM操作会导致页面重绘和回流,从而影响性能。

技巧

  1. 1. 批量更新DOM:将多次DOM操作合并为一次。
  2. 2. 使用Document Fragment:将多个DOM操作应用到一个Document Fragment中,再将其一次性插入到DOM中。

示例代码

// 不推荐:频繁操作DOM
for (let i = 0; i < 1000; i++) {
  const div = document.createElement('div');
  div.textContent = `Item ${i}`;
  document.body.appendChild(div);
}
// 推荐:使用Document Fragment
const fragment = document.createDocumentFragment();
for (let i = 0; i < 1000; i++) {
  const div = document.createElement('div');
  div.textContent = `Item ${i}`;
  fragment.appendChild(div);
}
document.body.appendChild(fragment);

323be6043570a514743d293313c6d321.jpg

2. 避免使用全局变量

原因

全局变量会污染全局命名空间,增加冲突风险,并且可能会影响垃圾回收的效率。

技巧

  1. 1. 使用局部变量:尽量在函数内部使用局部变量。
  2. 2. 使用闭包:通过闭包来封装变量,避免污染全局命名空间。

示例代码

// 不推荐:使用全局变量
var count = 0;
function increment() {
  count++;
  console.log(count);
}
// 推荐:使用局部变量
function createCounter() {
  let count = 0;
  return function() {
    count++;
    console.log(count);
  };
}
const increment = createCounter();
increment();
increment();

3. 使用事件委托

原因

为大量的DOM元素绑定事件处理程序会增加内存使用并降低性能。事件委托可以有效减少事件处理程序的数量。

技巧

将事件处理程序绑定到父元素上,通过事件冒泡机制来处理子元素的事件。

示例代码

<!-- 不推荐:为每个按钮绑定事件处理程序 -->
<button class="btn">Button 1</button>
<button class="btn">Button 2</button>
<button class="btn">Button 3</button>
<script>
document.querySelectorAll('.btn').forEach(button => {
  button.addEventListener('click', () => {
    console.log('Button clicked');
  });
});
</script>
<!-- 推荐:使用事件委托 -->
<button class="btn">Button 1</button>
<button class="btn">Button 2</button>
<button class="btn">Button 3</button>
<script>
document.body.addEventListener('click', event => {
  if (event.target.classList.contains('btn')) {
    console.log('Button clicked');
  }
});
</script>

4f9bb79803d2e2d042203649370b80e8.png

4. 避免使用内联样式和内联脚本

原因

内联样式和内联脚本会增加HTML文件的大小,影响页面加载速度,并且难以维护和调试。

技巧

将样式和脚本分别放到独立的CSS和JS文件中,并使用链接标签引入。

示例代码

<!-- 不推荐:使用内联样式和内联脚本 -->
<div style="color: red;">Hello, World!</div>
<script>
  console.log('Hello, World!');
</script>
<!-- 推荐:使用外部CSS和JS文件 -->
<link rel="stylesheet" href="styles.css">
<div class="red-text">Hello, World!</div>
<script src="script.js"></script>
styles.css
.red-text {
  color: red;
}
script.js
console.log('Hello, World!');

5. 使用缓存

原因

缓存可以减少网络请求的次数,提高页面加载速度。

技巧

  1. 1. 浏览器缓存:设置适当的缓存头,利用浏览器缓存。
  2. 2. 服务端缓存:使用服务端缓存机制,如Redis等。
  3. 3. 前端缓存:在前端使用缓存机制,如localStorage、sessionStorage等。

示例代码

// 使用localStorage缓存数据
function fetchData(url) {
  const cachedData = localStorage.getItem(url);
  if (cachedData) {
    return Promise.resolve(JSON.parse(cachedData));
  } else {
    return fetch(url)
      .then(response => response.json())
      .then(data => {
        localStorage.setItem(url, JSON.stringify(data));
        return data;
      });
  }
}
fetchData('https://api.example.com/data')
  .then(data => {
    console.log(data);
  });

572b4baaec95b9566fdbe346fda22488.png

6. 使用懒加载

原因

懒加载可以推迟加载不必要的资源,减少页面初始加载时间,提高页面响应速度。

技巧

  1. 1. 图片懒加载:使用Intersection Observer API或第三方库实现图片懒加载。
  2. 2. 组件懒加载:在SPA中使用Vue或React的懒加载特性,按需加载组件。

示例代码

<!-- 图片懒加载 -->
<img data-src="image.jpg" alt="Lazy Loaded Image">
<script>
document.addEventListener('DOMContentLoaded', function() {
  const lazyImages = document.querySelectorAll('img[data-src]');
  const lazyLoad = (entries, observer) => {
    entries.forEach(entry => {
      if (entry.isIntersecting) {
        entry.target.src = entry.target.dataset.src;
        observer.unobserve(entry.target);
      }
    });
  };
  const observer = new IntersectionObserver(lazyLoad);
  lazyImages.forEach(image => observer.observe(image));
});
</script>
<!-- 组件懒加载 -->
<!-- Vue.js 示例 -->
<template>
  <div>
    <button @click="showComponent = true">Load Component</button>
    <LazyComponent v-if="showComponent" />
  </div>
</template>
<script setup>
import { ref } from 'vue';
const showComponent = ref(false);
const LazyComponent = defineAsyncComponent(() =>
  import('./LazyComponent.vue')
);
</script>

94869347570a82c3a0e419ac483baded.png

7. 避免不必要的重绘和回流

原因

重绘和回流是浏览器渲染页面时最耗时的操作,频繁的重绘和回流会严重影响页面性能。

技巧

  1. 1. 减少DOM操作:批量更新DOM,使用Document Fragment。
  2. 2. 避免频繁读取和写入DOM:尽量将读取和写入分开,避免交替进行。
  3. 3. 使用CSS动画代替JavaScript动画:CSS动画通常比JavaScript动画性能更好。

示例代码

// 不推荐:频繁读取和写入DOM
for (let i = 0; i < 1000; i++) {
  const div = document.createElement('div');
  div.textContent = `Item ${i}`;
  document.body.appendChild(div);
  console.log(div.offsetHeight);
}
// 推荐:将读取和写入分开
const fragment = document.createDocumentFragment();
for (let i = 0; i < 1000; i++) {
  const div = document.createElement('div');
  div.textContent = `Item ${i}`;
  fragment.appendChild(div);
}
document.body.appendChild(fragment);
document.querySelectorAll('div').forEach(div => {
  console.log(div.offsetHeight);
});

8. 使用Web Workers

原因

Web Workers允许你在后台线程中运行脚本,不会阻塞主线程,可以用于处理计算密集型任务。

技巧

将计算密集型任务或长时间运行的任务放到Web Worker中执行,避免阻塞主线程。

示例代码

main.js

if (window.Worker) {
  const worker = new Worker('worker.js');
  worker.postMessage('start');
  worker.onmessage = function(event) {
    console.log('Received message from worker:', event.data
);
  };
}
worker.js
onmessage = function(event) {
  if (event.data === 'start') {
    let result = 0;
    for (let i = 0; i < 1e9; i++) {
      result += i;
    }
    postMessage(result);
  }
};

0df0860734c362dba9c73152f78672c7.jpg

9. 使用惰性初始化

原因

惰性初始化是一种延迟初始化技术,仅在需要时才初始化对象,减少不必要的开销。

技巧

  1. 1. 延迟加载模块:仅在需要时才加载模块。
  2. 2. 延迟初始化对象:仅在第一次使用时才初始化对象。

示例代码

// 不推荐:立即初始化对象
const module = require('heavy-module');
module.doSomething();
// 推荐:延迟加载模块
let module;
function doSomething() {
  if (!module) {
    module = require('heavy-module');
  }
  module.doSomething();
}

10. 使用现代JavaScript特性

原因

现代JavaScript特性,如箭头函数、模板字符串、解构赋值等,可以让代码更简洁,提高可读性和维护性。

技巧

  1. 1. 使用箭头函数:简化函数定义。
  2. 2. 使用模板字符串:简化字符串拼接。
  3. 3. 使用解构赋值:简化对象属性和数组元素的提取。

示例代码

// 不推荐:使用传统语法
function add(a, b) {
  return a + b;
}
const greeting = 'Hello, ' + name + '!';
const person = { name: 'Alice', age: 25 };
const name = person.name;
const age = person.age;
// 推荐:使用现代语法
const add = (a, b) => a + b;
const greeting = `Hello, ${name}!`;
const { name, age } = person;

结论

通过以上技巧,我们可以显著提高JavaScript代码的性能,从而提升用户体验,减少页面加载时间

在实际开发中,优化性能是一个持续的过程,需要不断地分析和改进。

相关文章
|
5天前
|
前端开发 JavaScript UED
深入了解前端性能优化:提高用户体验的关键
【10月更文挑战第9天】深入了解前端性能优化:提高用户体验的关键
25 5
|
5天前
|
缓存 前端开发 JavaScript
前端性能优化策略
【10月更文挑战第9天】前端性能优化策略
17 6
|
2天前
|
存储 弹性计算 算法
前端大模型应用笔记(四):如何在资源受限例如1核和1G内存的端侧或ECS上运行一个合适的向量存储库及如何优化
本文探讨了在资源受限的嵌入式设备(如1核处理器和1GB内存)上实现高效向量存储和检索的方法,旨在支持端侧大模型应用。文章分析了Annoy、HNSWLib、NMSLib、FLANN、VP-Trees和Lshbox等向量存储库的特点与适用场景,推荐Annoy作为多数情况下的首选方案,并提出了数据预处理、索引优化、查询优化等策略以提升性能。通过这些方法,即使在资源受限的环境中也能实现高效的向量检索。
|
8天前
|
存储 缓存 监控
|
1天前
|
缓存 前端开发 UED
前端 8 种图片加载优化方案梳理
本文首发于微信公众号“前端徐徐”,详细探讨了现代网页设计中图片加载速度优化的重要性及方法。内容涵盖图片格式选择(如JPEG、PNG、WebP等)、图片压缩技术、响应式图片、延迟加载、CDN使用、缓存控制、图像裁剪与缩放、Base64编码等前端图片优化策略,旨在帮助开发者提升网页性能和用户体验。
11 0
|
2天前
|
JavaScript 前端开发 应用服务中间件
vue前端开发中,通过vue.config.js配置和nginx配置,实现多个入口文件的实现方法
vue前端开发中,通过vue.config.js配置和nginx配置,实现多个入口文件的实现方法
23 0
|
2天前
|
存储 前端开发 API
前端开发中,Web Storage的存储数据的方法localstorage和sessionStorage的使用及区别
前端开发中,Web Storage的存储数据的方法localstorage和sessionStorage的使用及区别
22 0
|
6天前
|
前端开发
前端常用方法防抖(debounce)和节流(throttle)的示例演示及应用场景说明
前端常用方法防抖(debounce)和节流(throttle)的示例演示及应用场景说明
15 0
|
7天前
|
前端开发 JavaScript 应用服务中间件
前端性能优化:提升用户体验的关键
【10月更文挑战第7天】前端性能优化:提升用户体验的关键
19 0
|
7天前
|
缓存 前端开发 JavaScript
深入了解前端性能优化技巧
【10月更文挑战第7天】深入了解前端性能优化技巧
10 0