这段时间 JavaScript 原生开发做的一些优化点

作者: jie 分类: JavaScript 发布时间: 2025-02-15 10:11

最近在开发一个用原生 JavaScript 开发的项目,说实话,我平时开发的都是使用 Vue/React 进行开发,所以这次使用 JavaScript 原生开发,就需要自己去做一些性能的优化

文档碎片 DocumentFragment

当我们想要批量往页面上新增 DOM 节点的时候,如果循环遍历 appendChild 的话会比较耗性能,所以这个时候可以使用 DocumentFragment,这样的话可以一次性批量新增 DOM 节点

const fragment = document.createDocumentFragment();
const data = ["Item 1", "Item 2", "Item 3"];
data.forEach(item => {
	const element = document.createElement("div");
	element.textContent = item;
	fragment.appendChild(element);
});
doument.body.appendChild(fragment);

防抖节流

防抖节流属于是老生常谈了,我们很多的监听事件都需要做防抖节流,这样能减少监听事件触发的次数,从而减少性能的损耗

防抖

防抖是指在连续的事件触发后,只有最后一次事件触发之后的延迟时间到达时才执行回调函数。如果在延迟时间内再次触发事件,则之前的回调会被取消

function debounce(func, delay) {
	let timeout;
	return function() {
		// 清除上一次的定时器
		clearTimeout(timeout);
		// 设置新的定时器,只有在delay时间后才执行 func
		timeout = setTimeout(() => {
			func.apply(this, arguments);
		}, delay);
	}
}

// 示例调用
const searchInput = document.getElementById('searchInput');
// 在用户停止输入后500ms才触发回调
searchInput.addEventListener('input', debounce(function() {
	console.log("用户输入:", this.value);
}, 500))

节流

节流是指在一定的时间间隔内,只允许函数执行一次,哪怕该时间间隔内事件触发了很多次

function throttle(func, interval) {
	let lastTime = 0;
	return function() {
		let nowTime = new Date().getTime();
		if (nowTime - lastTime >= interval) {
			func.apply(this, arguments);
			lastTime = nowTime;
		}
	}
}

// 示例使用
// 每一秒执行一次
const scrollEvent = throttle(function() {
	console.log("滚动事件触发");
}, 1000)
window.addEventListener("scroll", scrollEvent)

Web Worker

Web Worker 是一种在后台线程中运行 JavaScript 的技术,能够使网页在执行长时间运行的任务时不阻塞主线程,避免页面卡顿。通过 Web Worker,我们可以将一些繁重的计算任务交给独立的线程来处理,从而提高网页的性能和用户体验

// worker.js - Web Worker 代码
self.onmessage = function(e) {
	console.log("Worker 收到消息:", e.data);
	// 进行一些计算,比如模拟耗时任务
	let result = e.data * 2; // 假设是简单的计算任务
	self.postMessage(result); // 将计算结果发送给主线程
}
<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="UTF-8">
		<meta name="viewport" content="width=device-width,initial-scale=1" />
		<title>Web Worker Example</title>
	</head>
	<body>
		<h1>Web Worker 示例</h1>
		<button id="startBtn">开始计算</button>
		<p id="result">计算结果:</p>

		<script>
			// 创建一个新的 Web Worker
			const worker = new Worker('worker.js');

			// 监听从 Web Worker 返回的消息
			worker.onmessage = function(e) {
				document.getElementById('result').textContent = "计算结果:" + e.data;
			};

			// 错误处理
			worker.onerror = function(e) {
				console.error("Worker 错误:", error.message);
			};

			// 触发事件,向Web Worker 发送数据
			document.getElementById('startBtn').addEventListener('click', function() {
				const number = 10;
				console.log("发送数据到Worker:", number);
				worker.postMessage(number); // 向 Web Worker 发送数据
			});
		</script>
	</body>
</html>

浏览器缓存

需要后台给前端返回缓存的响应头,这样读取文件的时候就能读取缓存

// 设置缓存时间为一年
Cache-control: public, max-age=31536000

异步加载 JavaScript 脚本

当你页面需要加载的 JavaScript 脚本过多的时候,可以选择异步加载 JavaScript 脚本,这涉及到了 script 标签的 defer/async

特性deferasync
加载方式异步加载,但等待HTML解析完成后执行异步加载,加载完成后立即执行
执行顺序按照在文档中的顺序执行执行顺序不确定,取决于哪个脚本先加载完成
适用场景适用于需要访问DOM的脚本适用于不依赖DOM的独立脚本
是否阻塞Html不阻塞,HTML继续解析不阻塞,HTML继续解析
<script src="script1.js" defer></script>
<script src="script2.js" async></script>

发表回复