中级前端进阶方向 第十步)深入 浏览器性能优化(渲染机制、内存泄漏定位、异步优化),附案例源码
《中级前端进阶指南》系统梳理了JavaScript核心技术栈与性能优化方向。核心内容包括:深入理解事件循环、原型链、闭包、Proxy等高级特性;掌握Promise、Generator、Async/Await等异步编程范式;模块化与装饰器应用实践。延伸部分覆盖工厂函数、状态管理、防抖节流等实用技巧。性能优化专题详细解析浏览器渲染机制(关键路径优化、GPU加速)、内存泄漏定位(闭包/事件/定时器排查)
《中级前端进阶方向 第一步)JavaScript 微任务 / 宏任务机制》
《中级前端进阶方向 第二步)深入事件循环(Event Loop)》
《中级前端进阶方向 第三步)深入javascript原型链,附学习代码》
《中级前端进阶方向 第四步)深入javascript 闭包、this 、作用域提升,附学习案例源码》
《中级前端进阶方向 第五步)深入 javascript高级特性Proxy,附学习案例源码》
《中级前端进阶方向 第六步)深入 javascript 高级特性Generator生成器,附案例源码》
《中级前端进阶方向 第七步)深入 javascript 高级特性Async/Await,附源码》《中级前端进阶方向 第八步)深入 javascript 高级特性 Promise,附案例源码》
《中级前端进阶方向 第九步)深入 javascript 高级特性 模块化 与 装饰器,附案例源码》
--🖍《延伸扩展》-----------------------------------------------------------------------------------------
《中级前端进阶方向 延伸扩展一)javascript 私有状态/工厂函数/回调中保持局部状态/防抖与节流/IIFE 捕获》
一、浏览器渲染机制与优化
浏览器的渲染机制决定了网页性能的上限,理解渲染流程有助于我们在开发中规避性能陷阱
1. 渲染流程
-
解析 HTML → 构建 DOM 树(Document Object Model)
-
解析 CSS → 构建 CSSOM 树
-
合并 DOM 与 CSSOM → 生成 Render Tree(渲染树,包含可见节点的样式信息)
-
布局(Reflow) → 计算每个节点的几何位置和大小
-
绘制(Repaint) → 将像素信息绘制到屏幕
-
合成(Composite) → 将多个图层合成最终画面(GPU 加速)
2. 性能优化点
-
减少重排(Reflow)
-
避免频繁操作 DOM,可以使用 DocumentFragment、或合并操作。
-
尽量避免逐个修改样式,而是修改
className
。 -
避免使用触发强制同步布局的属性(如
offsetTop
、clientHeight
),若要用,缓存结果。
-
-
减少重绘(Repaint)
-
使用
visibility: hidden
替代display: none
(前者只触发重绘,后者触发重排)。 -
使用
transform
和opacity
做动画,而不是top
/left
。
-
-
启用 GPU 加速
-
对动画元素添加
will-change: transform;
或translateZ(0)
,触发独立图层,减少主线程压力。
-
-
资源加载优化
-
使用 HTTP/2/3 提升多路复用。
-
图片懒加载 (
loading="lazy"
)。 -
使用 WebP/AVIF 等更高压缩率的图片格式。
-
合理拆分 JS,利用
defer
/async
。
-
二、内存泄漏定位与优化
1. 什么是内存泄漏
-
内存泄漏是指:程序中已不再需要的对象仍然被引用,导致 GC(垃圾回收器)无法回收。
2. 常见内存泄漏场景
-
全局变量未释放
function foo() { leak = "oops"; // 隐式全局变量 }
→ 应使用
"use strict";
或let/const
。 -
闭包滥用
function outer() { const bigData = new Array(100000).fill("data"); return function inner() { console.log(bigData[0]); // 导致 bigData 一直被引用 } }
-
事件监听未解绑
const btn = document.getElementById("btn"); function handler() { console.log("clicked"); } btn.addEventListener("click", handler); // 若元素被移除但监听器未解绑 → 内存泄漏
-
定时器未清理
setInterval(() => { /* ... */ }, 1000); // 未 clearInterval
-
DOM 引用未释放
-
脚本中保存了对已移除 DOM 的引用。
-
3. 如何定位内存泄漏
-
Chrome DevTools → Performance/Memory 面板
-
打开 Memory → 选择 Heap Snapshot
-
操作页面 → 拍快照 → 对比对象数量
-
检查 Detached DOM trees 或 大量不可回收对象
-
-
Performance Timeline
-
录制运行 → 查看 JS Heap 内存曲线是否持续上升。
-
4. 优化手段
-
严格使用
let/const
避免隐式全局变量。 -
组件销毁时解除事件绑定、清理定时器。
-
使用 WeakMap/WeakSet 存储 DOM 或对象引用,避免强引用阻止回收。
-
大数据对象分片处理,避免长期占用内存。
三、异步优化
异步优化的目标:减少主线程阻塞、提升用户交互流畅度。
1. 异步编程模型
-
回调(Callback):最基础的方式,但可能出现回调地狱。
-
Promise:链式调用,便于错误处理。
-
async/await:同步写法,易读易维护。
2. 异步优化场景
-
I/O 密集型任务(网络请求、文件操作)
-
利用
async/await
+Promise.all
并发执行,减少总耗时。
async function fetchAll() { const [u1, u2] = await Promise.all([ fetch("/api/user1"), fetch("/api/user2") ]); }
-
-
计算密集型任务
-
将计算拆分成小块,使用
requestIdleCallback
或setTimeout
避免长时间阻塞 UI。
function bigTask(data) { const chunk = data.splice(0, 1000); process(chunk); if (data.length > 0) { setTimeout(() => bigTask(data), 0); // 分片处理 } }
-
-
动画优化
-
使用
requestAnimationFrame
替代setTimeout
控制动画帧率。
-
-
Web Worker
-
将大计算任务交给 Worker 线程,避免阻塞 UI 渲染。
const worker = new Worker("worker.js"); worker.postMessage(data); worker.onmessage = (e) => console.log(e.data);
-
四、总结
-
渲染机制优化:减少 Reflow/Repaint,充分利用 GPU,加快资源加载。
-
内存泄漏定位:利用 Chrome DevTools Heap Snapshot,重点关注闭包、事件、定时器、DOM 引用。
-
异步优化:合理利用
Promise.all
、requestAnimationFrame
、分片计算、Web Worker,避免主线程阻塞。
五、可视化界面源码
提供了以下功能:
-
性能优化概述:通过卡片布局介绍三个关键优化领域
-
浏览器渲染机制:
-
可视化渲染流程(HTML解析、CSS解析、渲染树、布局、绘制)
-
重排重绘对比演示(优化与未优化版本)
-
渲染优化策略
-
-
内存泄漏定位与修复:
-
常见内存泄漏场景
-
交互式内存泄漏创建和清除演示
-
内存使用和DOM节点数量可视化图表
-
内存泄漏检测方法
-
-
异步操作优化:
-
异步优化策略
-
Web Workers与主线程性能对比演示
-
UI响应性测试
-
-
性能优化检查清单:提供三个关键领域的实用检查项
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>浏览器性能优化指南</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
:root {
--primary: #4361ee;
--secondary: #3a0ca3;
--accent: #7209b7;
--light: #f8f9fa;
--dark: #212529;
--success: #4cc9f0;
--warning: #f72585;
--info: #4895ef;
--render: #4361ee;
--memory: #f72585;
--async: #4cc9f0;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
body {
background-color: #f5f7ff;
color: var(--dark);
line-height: 1.6;
padding-bottom: 2rem;
}
header {
background: linear-gradient(135deg, var(--primary), var(--secondary));
color: white;
text-align: center;
padding: 2rem 1rem;
margin-bottom: 2rem;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}
h1 {
font-size: 2.5rem;
margin-bottom: 0.5rem;
}
.subtitle {
font-size: 1.2rem;
opacity: 0.9;
max-width: 800px;
margin: 0 auto;
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 0 1rem;
}
.section {
background: white;
border-radius: 10px;
padding: 1.5rem;
margin-bottom: 2rem;
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.05);
}
h2 {
color: var(--primary);
margin-bottom: 1.2rem;
padding-bottom: 0.5rem;
border-bottom: 2px solid var(--light);
display: flex;
align-items: center;
}
h2 i {
margin-right: 10px;
}
h3 {
color: var(--secondary);
margin: 1.5rem 0 0.8rem;
}
p {
margin-bottom: 1rem;
}
.cards-container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 1.5rem;
margin: 1.5rem 0;
}
.card {
background: white;
border-radius: 8px;
overflow: hidden;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.08);
transition: transform 0.3s ease;
}
.card:hover {
transform: translateY(-5px);
}
.card-header {
color: white;
padding: 1rem;
font-weight: bold;
display: flex;
align-items: center;
}
.card-header i {
margin-right: 8px;
font-size: 1.2rem;
}
.render-header {
background: var(--render);
}
.memory-header {
background: var(--memory);
}
.async-header {
background: var(--async);
}
.card-body {
padding: 1.2rem;
}
.badge {
display: inline-block;
padding: 0.25rem 0.5rem;
border-radius: 4px;
font-size: 0.8rem;
font-weight: bold;
margin-right: 0.5rem;
}
.render-badge {
background: var(--render);
color: white;
}
.memory-badge {
background: var(--memory);
color: white;
}
.async-badge {
background: var(--async);
color: white;
}
.process-container {
display: flex;
justify-content: space-between;
margin: 2rem 0;
position: relative;
}
.process-step {
text-align: center;
width: 20%;
position: relative;
z-index: 2;
}
.process-icon {
width: 60px;
height: 60px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
margin: 0 auto 1rem;
color: white;
font-size: 1.5rem;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}
.process-connection {
position: absolute;
top: 30px;
left: 10%;
right: 10%;
height: 2px;
background: var(--primary);
z-index: 1;
}
.code-container {
background: #2d2d2d;
color: #f8f8f2;
border-radius: 6px;
padding: 1rem;
margin: 1rem 0;
overflow-x: auto;
font-family: 'Fira Code', monospace;
}
.code-comment {
color: #8292a2;
}
.code-keyword {
color: #f92672;
}
.code-function {
color: #e6db74;
}
.code-parameter {
color: #fd971f;
}
.code-string {
color: #a6e22e;
}
.code-number {
color: #ae81ff;
}
.interactive-demo {
background: #f8f9fa;
border-radius: 8px;
padding: 1.5rem;
margin: 1.5rem 0;
}
.demo-container {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1.5rem;
margin-top: 1rem;
}
.btn {
display: inline-block;
background: var(--primary);
color: white;
padding: 0.6rem 1.2rem;
border: none;
border-radius: 4px;
cursor: pointer;
font-weight: bold;
transition: background 0.3s;
margin-right: 0.5rem;
margin-bottom: 0.5rem;
}
.btn:hover {
background: var(--secondary);
}
.btn-warning {
background: var(--warning);
}
.btn-warning:hover {
background: #d11a66;
}
.btn-success {
background: var(--success);
}
.btn-success:hover {
background: #3bb0d0;
}
.visualization {
height: 200px;
background: linear-gradient(135deg, #f5f7ff, #e6e9ff);
border-radius: 8px;
margin: 1.5rem 0;
position: relative;
overflow: hidden;
}
.memory-block {
position: absolute;
background: var(--memory);
border-radius: 4px;
transition: all 0.5s ease;
}
.chart-container {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1.5rem;
margin: 1.5rem 0;
}
.chart {
background: white;
padding: 1rem;
border-radius: 8px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.08);
}
.bar {
height: 20px;
margin-bottom: 0.5rem;
border-radius: 4px;
background: linear-gradient(90deg, var(--primary), var(--info));
transition: width 1s ease;
}
@media (max-width: 768px) {
.demo-container, .chart-container {
grid-template-columns: 1fr;
}
.process-container {
flex-direction: column;
align-items: center;
}
.process-step {
width: 100%;
margin-bottom: 2rem;
}
.process-connection {
display: none;
}
}
footer {
text-align: center;
margin-top: 3rem;
color: #6c757d;
}
.tip {
background: #e9f7fe;
border-left: 4px solid var(--info);
padding: 1rem;
margin: 1rem 0;
border-radius: 0 4px 4px 0;
}
.warning {
background: #fef3e9;
border-left: 4px solid var(--warning);
padding: 1rem;
margin: 1rem 0;
border-radius: 0 4px 4px 0;
}
</style>
</head>
<body>
<header>
<h1>浏览器性能优化指南</h1>
<p class="subtitle">深入理解浏览器渲染机制、内存泄漏定位与异步优化技术</p>
</header>
<div class="container">
<section class="section">
<h2><i class="fas fa-tachometer-alt"></i> 性能优化概述</h2>
<p>现代Web应用对性能要求越来越高,理解浏览器工作原理并实施有效的优化策略至关重要。本指南将深入探讨三个关键领域:</p>
<div class="cards-container">
<div class="card">
<div class="card-header render-header">
<i class="fas fa-paint-brush"></i> 渲染优化
</div>
<div class="card-body">
<p>优化浏览器渲染流程,减少重排和重绘,提高页面渲染性能。</p>
<div class="tip">
<p>关键指标:FPS(帧率)、布局计算时间、绘制时间</p>
</div>
</div>
</div>
<div class="card">
<div class="card-header memory-header">
<i class="fas fa-memory"></i> 内存管理
</div>
<div class="card-body">
<p>识别和修复内存泄漏,有效管理内存使用,避免页面卡顿和崩溃。</p>
<div class="tip">
<p>关键指标:内存使用量、DOM节点数、事件监听器数量</p>
</div>
</div>
</div>
<div class="card">
<div class="card-header async-header">
<i class="fas fa-bolt"></i> 异步优化
</div>
<div class="card-body">
<p>优化异步操作,合理使用Web Workers,避免阻塞主线程。</p>
<div class="tip">
<p>关键指标:任务执行时间、主线程阻塞时间、Long Tasks</p>
</div>
</div>
</div>
</div>
</section>
<section class="section">
<h2><i class="fas fa-paint-brush"></i> 浏览器渲染机制</h2>
<p>浏览器渲染页面需要经过一系列步骤,理解这些步骤有助于我们找到优化点:</p>
<div class="process-container">
<div class="process-connection"></div>
<div class="process-step">
<div class="process-icon" style="background: var(--render);">
<i class="fas fa-code"></i>
</div>
<h4>HTML解析</h4>
<p>构建DOM树</p>
</div>
<div class="process-step">
<div class="process-icon" style="background: var(--render);">
<i class="fas fa-paint-brush"></i>
</div>
<h4>CSS解析</h4>
<p>构建CSSOM树</p>
</div>
<div class="process-step">
<div class="process-icon" style="background: var(--render);">
<i class="fas fa-sitemap"></i>
</div>
<h4>渲染树</h4>
<p>DOM + CSSOM</p>
</div>
<div class="process-step">
<div class="process-icon" style="background: var(--render);">
<i class="fas fa-ruler-combined"></i>
</div>
<h4>布局</h4>
<p>计算大小位置</p>
</div>
<div class="process-step">
<div class="process-icon" style="background: var(--render);">
<i class="fas fa-brush"></i>
</div>
<h4>绘制</h4>
<p>像素填充</p>
</div>
</div>
<h3>优化策略</h3>
<ul>
<li>减少重排和重绘:集中修改样式,使用CSS transform和opacity</li>
<li>使用requestAnimationFrame替代setTimeout/setInterval进行动画</li>
<li>避免布局抖动:强制同步布局会导致性能问题</li>
<li>使用CSS will-change属性提示浏览器优化</li>
</ul>
<div class="interactive-demo">
<h3>重排重绘对比演示</h3>
<p>点击下方按钮查看不同操作对性能的影响:</p>
<div style="margin: 1rem 0;">
<button class="btn" onclick="demoRender('optimized')">优化版本</button>
<button class="btn btn-warning" onclick="demoRender('unoptimized')">未优化版本</button>
</div>
<div class="demo-container">
<div class="code-container">
<span class="code-comment">// 优化版本 - 使用transform</span><br>
<span class="code-keyword">function</span> <span class="code-function">animateOptimized</span>() {<br>
<span class="code-keyword">const</span> element = document.getElementById(<span class="code-string">'animated'</span>);<br>
element.style.transform = <span class="code-string">`translateX(${Math.random() * 300}px)`</span>;<br>
}<br><br>
<span class="code-comment">// 未优化版本 - 修改left属性</span><br>
<span class="code-keyword">function</span> <span class="code-function">animateUnoptimized</span>() {<br>
<span class="code-keyword">const</span> element = document.getElementById(<span class="code-string">'animated'</span>);<br>
element.style.left = <span class="code-string">`${Math.random() * 300}px`</span>;<br>
}
</div>
<div class="visualization">
<div id="animated-element" style="width: 50px; height: 50px; background: var(--render); position: absolute; top: 75px; left: 10px; border-radius: 8px;"></div>
</div>
</div>
</div>
</section>
<section class="section">
<h2><i class="fas fa-memory"></i> 内存泄漏定位与修复</h2>
<p>内存泄漏是Web应用性能问题的常见原因,会导致页面变慢甚至崩溃。</p>
<h3>常见内存泄漏场景</h3>
<ul>
<li>意外的全局变量</li>
<li>遗忘的定时器和回调函数</li>
<li>DOM引用脱离</li>
<li>闭包使用不当</li>
<li>事件监听器未移除</li>
</ul>
<div class="interactive-demo">
<h3>内存泄漏演示</h3>
<p>点击按钮创建内存泄漏,然后使用Chrome DevTools检测:</p>
<div style="margin: 1rem 0;">
<button class="btn btn-warning" onclick="createMemoryLeak()">创建内存泄漏</button>
<button class="btn" onclick="clearMemoryLeak()">清除泄漏</button>
</div>
<div class="code-container">
<span class="code-comment">// 常见内存泄漏示例</span><br>
<span class="code-keyword">let</span> leakedElements = [];<br>
<span class="code-keyword">function</span> <span class="code-function">createMemoryLeak</span>() {<br>
<span class="code-comment">// 创建DOM元素但未正确清理</span><br>
<span class="code-keyword">for</span> (<span class="code-keyword">let</span> i = <span class="code-number">0</span>; i < <span class="code-number">100</span>; i++) {<br>
<span class="code-keyword">const</span> element = document.createElement(<span class="code-string">'div'</span>);<br>
element.innerHTML = <span class="code-string">`Leaked Element <span class="code-number">${i}</span>`</span>;<br>
document.body.appendChild(element);<br>
leakedElements.push(element);<br>
}<br>
updateMemoryChart();<br>
}<br>
<br>
<span class="code-keyword">function</span> <span class="code-function">clearMemoryLeak</span>() {<br>
<span class="code-comment">// 正确清理DOM元素</span><br>
leakedElements.forEach(element => {<br>
element.remove();<br>
});<br>
leakedElements = [];<br>
updateMemoryChart();<br>
}
</div>
<div class="chart-container">
<div class="chart">
<h4>内存使用情况</h4>
<div id="memory-chart" style="height: 200px; display: flex; align-items: flex-end;">
<div class="bar" style="width: 30%;">初始: 30%</div>
</div>
</div>
<div class="chart">
<h4>DOM节点数量</h4>
<div id="dom-chart" style="height: 200px; display: flex; align-items: flex-end;">
<div class="bar" style="width: 20%;">初始: 20%</div>
</div>
</div>
</div>
</div>
<div class="warning">
<p><strong>检测内存泄漏:</strong>使用Chrome DevTools的Memory面板,通过Heap Snapshot和Allocation Instrumentation工具检测内存泄漏。</p>
</div>
</section>
<section class="section">
<h2><i class="fas fa-bolt"></i> 异步操作优化</h2>
<p>JavaScript是单线程的,异步操作优化对于防止主线程阻塞至关重要。</p>
<h3>优化策略</h3>
<ul>
<li>使用Web Workers处理CPU密集型任务</li>
<li>合理使用setTimeout、Promise、async/await</li>
<li>使用requestIdleCallback处理低优先级任务</li>
<li>批量处理DOM操作</li>
<li>使用debounce和throttle控制事件触发频率</li>
</ul>
<div class="interactive-demo">
<h3>Web Workers演示</h3>
<p>比较主线程计算和使用Web Worker的计算性能:</p>
<div style="margin: 1rem 0;">
<button class="btn" onclick="runOnMainThread()">主线程计算</button>
<button class="btn btn-success" onclick="runWithWebWorker()">Web Worker计算</button>
</div>
<div class="demo-container">
<div class="code-container">
<span class="code-comment">// 主线程计算(可能阻塞UI)</span><br>
<span class="code-keyword">function</span> <span class="code-function">calculateOnMainThread</span>() {<br>
<span class="code-keyword">let</span> result = <span class="code-number">0</span>;<br>
<span class="code-keyword">for</span> (<span class="code-keyword">let</span> i = <span class="code-number">0</span>; i < <span class="code-number">1000000000</span>; i++) {<br>
result += Math.sqrt(i) * Math.sin(i);<br>
}<br>
<span class="code-keyword">return</span> result;<br>
}<br><br>
<span class="code-comment">// 使用Web Worker</span><br>
<span class="code-keyword">const</span> worker = <span class="code-keyword">new</span> Worker(<span class="code-string">'calculate.js'</span>);<br>
worker.onmessage = <span class="code-keyword">function</span>(e) {<br>
console.log(<span class="code-string">'Result from worker:'</span>, e.data);<br>
};
</div>
<div class="visualization" style="display: flex; justify-content: center; align-items: center;">
<div id="ui-response-test" style="width: 100px; height: 100px; background: var(--async); border-radius: 50%; transition: transform 0.3s ease;"></div>
</div>
</div>
<div class="tip">
<p><strong>提示:</strong>点击"主线程计算"后尝试与页面交互(如点击圆球),注意UI的响应性。然后尝试Web Worker版本。</p>
</div>
</div>
</section>
<section class="section">
<h2><i class="fas fa-check-circle"></i> 性能优化检查清单</h2>
<div class="cards-container">
<div class="card">
<div class="card-header render-header">
<i class="fas fa-paint-brush"></i> 渲染检查项
</div>
<div class="card-body">
<ul>
<li>✓ 使用CSS动画代替JavaScript动画</li>
<li>✓ 避免强制同步布局</li>
<li>✓ 使用transform和opacity实现动画</li>
<li>✓ 减少图层数量,但合理使用图层促进动画</li>
<li>✓ 使用content-visibility跳过屏幕外渲染</li>
</ul>
</div>
</div>
<div class="card">
<div class="card-header memory-header">
<i class="fas fa-memory"></i> 内存检查项
</div>
<div class="card-body">
<ul>
<li>✓ 定期检查并移除未使用的事件监听器</li>
<li>✓ 避免不必要的全局变量</li>
<li>✓ 及时清理定时器和回调函数</li>
<li>✓ 使用弱引用(WeakMap/WeakSet)当需要时</li>
<li>✓ 定期使用DevTools检查内存使用情况</li>
</ul>
</div>
</div>
<div class="card">
<div class="card-header async-header">
<i class="fas fa-bolt"></i> 异步检查项
</div>
<div class="card-body">
<ul>
<li>✓ 将耗时任务转移到Web Workers</li>
<li>✓ 使用debounce和throttle控制事件频率</li>
<li>✓ 合理使用微任务和宏任务</li>
<li>✓ 使用requestIdleCallback处理后台任务</li>
<li>✓ 优化代码避免Long Tasks(超过50ms的任务)</li>
</ul>
</div>
</div>
</div>
</section>
</div>
<footer>
<p>浏览器性能优化指南 © 2023 - 使用Chrome DevTools进行实际性能分析和调试</p>
</footer>
<script>
// 渲染演示
function demoRender(type) {
const element = document.getElementById('animated-element');
if (type === 'optimized') {
// 使用transform(优化)
element.style.transition = 'transform 0.5s ease';
element.style.transform = `translateX(${Math.random() * 250}px)`;
} else {
// 使用left(未优化)
element.style.transition = 'left 0.5s ease';
element.style.left = `${Math.random() * 250}px`;
}
}
// 内存泄漏演示
let leakedElements = [];
let memoryLevel = 30;
let domLevel = 20;
function createMemoryLeak() {
// 模拟内存泄漏
for (let i = 0; i < 5; i++) {
const element = document.createElement('div');
element.className = 'memory-block';
element.style.width = `${Math.random() * 30 + 10}px`;
element.style.height = `${Math.random() * 30 + 10}px`;
element.style.top = `${Math.random() * 150}px`;
element.style.left = `${Math.random() * 300}px`;
element.style.opacity = '0.7';
document.querySelector('.visualization').appendChild(element);
leakedElements.push(element);
}
memoryLevel = Math.min(100, memoryLevel + 10);
domLevel = Math.min(100, domLevel + 15);
updateMemoryChart();
}
function clearMemoryLeak() {
// 清理内存泄漏
leakedElements.forEach(element => {
element.remove();
});
leakedElements = [];
memoryLevel = Math.max(30, memoryLevel - 20);
domLevel = Math.max(20, domLevel - 10);
updateMemoryChart();
}
function updateMemoryChart() {
document.getElementById('memory-chart').innerHTML =
`<div class="bar" style="width: ${memoryLevel}%;">当前: ${memoryLevel}%</div>`;
document.getElementById('dom-chart').innerHTML =
`<div class="bar" style="width: ${domLevel}%;">当前: ${domLevel}%</div>`;
}
// 异步演示
const uiElement = document.getElementById('ui-response-test');
function runOnMainThread() {
uiElement.style.transform = 'scale(0.8)';
// 模拟耗时计算(阻塞主线程)
const start = Date.now();
let result = 0;
for (let i = 0; i < 300000000; i++) {
result += Math.sqrt(i) * Math.sin(i);
}
console.log('Calculation result:', result, 'Time:', Date.now() - start, 'ms');
uiElement.style.transform = 'scale(1)';
}
function runWithWebWorker() {
uiElement.style.transform = 'scale(0.8)';
// 使用setTimeout模拟Web Worker的非阻塞特性
setTimeout(() => {
console.log('Web Worker calculation completed');
uiElement.style.transform = 'scale(1)';
}, 100);
}
// UI响应测试
uiElement.addEventListener('click', function() {
this.style.transform = 'scale(0.9)';
setTimeout(() => {
this.style.transform = 'scale(1)';
}, 100);
});
</script>
</body>
</html>
更多推荐
所有评论(0)