🤙《中级前端进阶方向指南》

《中级前端进阶方向 第一步)JavaScript 微任务 / 宏任务机制》

《中级前端进阶方向 第二步)深入事件循环(Event Loop)》

《中级前端进阶方向 第三步)深入javascript原型链,附学习代码》

《中级前端进阶方向 第四步)深入javascript 闭包、this 、作用域提升,附学习案例源码》

《​​中级前端进阶方向 第五步)深入 javascript高级特性Proxy,附学习案例源码》

《​​中级前端进阶方向 第六步)深入 javascript 高级特性Generator生成器,附案例源码》
《​​中级前端进阶方向 第七步)深入 javascript 高级特性Async/Await,附源码》

《​​中级前端进阶方向 第八步)深入 javascript 高级特性 Promise,附案例源码》

《​​中级前端进阶方向 第九步)深入 javascript 高级特性 模块化 与 装饰器,附案例源码》


--🖍《延伸扩展》-----------------------------------------------------------------------------------------
《中级前端进阶方向 延伸扩展一)javascript 私有状态/工厂函数/回调中保持局部状态/防抖与节流/IIFE 捕获》

《中级前端进阶方向 延伸扩展二) Promise API 概览,可视化演示页面》

一、浏览器渲染机制与优化

浏览器的渲染机制决定了网页性能的上限,理解渲染流程有助于我们在开发中规避性能陷阱

1. 渲染流程

  1. 解析 HTML → 构建 DOM 树(Document Object Model)

  2. 解析 CSS → 构建 CSSOM 树

  3. 合并 DOM 与 CSSOM → 生成 Render Tree(渲染树,包含可见节点的样式信息)

  4. 布局(Reflow) → 计算每个节点的几何位置和大小

  5. 绘制(Repaint) → 将像素信息绘制到屏幕

  6. 合成(Composite) → 将多个图层合成最终画面(GPU 加速)


2. 性能优化点

  • 减少重排(Reflow)

    • 避免频繁操作 DOM,可以使用 DocumentFragment、或合并操作。

    • 尽量避免逐个修改样式,而是修改 className

    • 避免使用触发强制同步布局的属性(如 offsetTopclientHeight),若要用,缓存结果。

  • 减少重绘(Repaint)

    • 使用 visibility: hidden 替代 display: none(前者只触发重绘,后者触发重排)。

    • 使用 transformopacity 做动画,而不是 top / left

  • 启用 GPU 加速

    • 对动画元素添加 will-change: transform;translateZ(0),触发独立图层,减少主线程压力。

  • 资源加载优化

    • 使用 HTTP/2/3 提升多路复用。

    • 图片懒加载 (loading="lazy")。

    • 使用 WebP/AVIF 等更高压缩率的图片格式。

    • 合理拆分 JS,利用 defer/async


二、内存泄漏定位与优化

1. 什么是内存泄漏

  • 内存泄漏是指:程序中已不再需要的对象仍然被引用,导致 GC(垃圾回收器)无法回收。

2. 常见内存泄漏场景

  1. 全局变量未释放

    function foo() {
      leak = "oops"; // 隐式全局变量
    }
    

    → 应使用 "use strict";let/const

  2. 闭包滥用

    function outer() {
      const bigData = new Array(100000).fill("data");
      return function inner() {
        console.log(bigData[0]); // 导致 bigData 一直被引用
      }
    }
    
  3. 事件监听未解绑

    const btn = document.getElementById("btn");
    function handler() { console.log("clicked"); }
    btn.addEventListener("click", handler);
    // 若元素被移除但监听器未解绑 → 内存泄漏
    
  4. 定时器未清理

    setInterval(() => { /* ... */ }, 1000); // 未 clearInterval
    
  5. DOM 引用未释放

    • 脚本中保存了对已移除 DOM 的引用。


3. 如何定位内存泄漏

  • Chrome DevTools → Performance/Memory 面板

    1. 打开 Memory → 选择 Heap Snapshot

    2. 操作页面 → 拍快照 → 对比对象数量

    3. 检查 Detached DOM trees大量不可回收对象

  • Performance Timeline

    • 录制运行 → 查看 JS Heap 内存曲线是否持续上升。


4. 优化手段

  • 严格使用 let/const 避免隐式全局变量。

  • 组件销毁时解除事件绑定、清理定时器。

  • 使用 WeakMap/WeakSet 存储 DOM 或对象引用,避免强引用阻止回收。

  • 大数据对象分片处理,避免长期占用内存。


三、异步优化

异步优化的目标:减少主线程阻塞、提升用户交互流畅度。

1. 异步编程模型

  • 回调(Callback):最基础的方式,但可能出现回调地狱。

  • Promise:链式调用,便于错误处理。

  • async/await:同步写法,易读易维护。


2. 异步优化场景

  1. I/O 密集型任务(网络请求、文件操作)

    • 利用 async/await + Promise.all 并发执行,减少总耗时。

    async function fetchAll() {
      const [u1, u2] = await Promise.all([
        fetch("/api/user1"),
        fetch("/api/user2")
      ]);
    }
    
  2. 计算密集型任务

    • 将计算拆分成小块,使用 requestIdleCallbacksetTimeout 避免长时间阻塞 UI。

    function bigTask(data) {
      const chunk = data.splice(0, 1000);
      process(chunk);
      if (data.length > 0) {
        setTimeout(() => bigTask(data), 0); // 分片处理
      }
    }
    
  3. 动画优化

    • 使用 requestAnimationFrame 替代 setTimeout 控制动画帧率。

  4. 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.allrequestAnimationFrame、分片计算、Web Worker,避免主线程阻塞。


五、可视化界面源码

提供了以下功能:

  1. 性能优化概述:通过卡片布局介绍三个关键优化领域

  2. 浏览器渲染机制

    • 可视化渲染流程(HTML解析、CSS解析、渲染树、布局、绘制)

    • 重排重绘对比演示(优化与未优化版本)

    • 渲染优化策略

  3. 内存泄漏定位与修复

    • 常见内存泄漏场景

    • 交互式内存泄漏创建和清除演示

    • 内存使用和DOM节点数量可视化图表

    • 内存泄漏检测方法

  4. 异步操作优化

    • 异步优化策略

    • Web Workers与主线程性能对比演示

    • UI响应性测试

  5. 性能优化检查清单:提供三个关键领域的实用检查项

<!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>
                        &nbsp;&nbsp;<span class="code-keyword">const</span> element = document.getElementById(<span class="code-string">'animated'</span>);<br>
                        &nbsp;&nbsp;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>
                        &nbsp;&nbsp;<span class="code-keyword">const</span> element = document.getElementById(<span class="code-string">'animated'</span>);<br>
                        &nbsp;&nbsp;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>
                    &nbsp;&nbsp;<span class="code-comment">// 创建DOM元素但未正确清理</span><br>
                    &nbsp;&nbsp;<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>
                    &nbsp;&nbsp;&nbsp;&nbsp;<span class="code-keyword">const</span> element = document.createElement(<span class="code-string">'div'</span>);<br>
                    &nbsp;&nbsp;&nbsp;&nbsp;element.innerHTML = <span class="code-string">`Leaked Element <span class="code-number">${i}</span>`</span>;<br>
                    &nbsp;&nbsp;&nbsp;&nbsp;document.body.appendChild(element);<br>
                    &nbsp;&nbsp;&nbsp;&nbsp;leakedElements.push(element);<br>
                    &nbsp;&nbsp;}<br>
                    &nbsp;&nbsp;updateMemoryChart();<br>
                    }<br>
                    <br>
                    <span class="code-keyword">function</span> <span class="code-function">clearMemoryLeak</span>() {<br>
                    &nbsp;&nbsp;<span class="code-comment">// 正确清理DOM元素</span><br>
                    &nbsp;&nbsp;leakedElements.forEach(element => {<br>
                    &nbsp;&nbsp;&nbsp;&nbsp;element.remove();<br>
                    &nbsp;&nbsp;});<br>
                    &nbsp;&nbsp;leakedElements = [];<br>
                    &nbsp;&nbsp;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>
                        &nbsp;&nbsp;<span class="code-keyword">let</span> result = <span class="code-number">0</span>;<br>
                        &nbsp;&nbsp;<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>
                        &nbsp;&nbsp;&nbsp;&nbsp;result += Math.sqrt(i) * Math.sin(i);<br>
                        &nbsp;&nbsp;}<br>
                        &nbsp;&nbsp;<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>
                        &nbsp;&nbsp;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>浏览器性能优化指南 &copy; 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>

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐