产品特色
内容简介
如果你使用 JavaScript 构建交互丰富的 Web 应用,那么 JavaScript 代码可能是造成你的Web应用速度变慢的主要原因。本书揭示的技术和策略能帮助你在开发过程中消除性能瓶颈。你将会了解如何提升各方面的性能,包括代码的加载、运行、DOM 交互、页面生存周期等。雅虎的前端工程师 Nicholas C. Zakas 和其他五位 JavaScript 专家介绍了页面代码加载的优佳方法和编程技巧,来帮助你编写更为高效和快速的代码。你还会了解到构建和部署文件到生产环境的优佳实践,以及有助于定位线上问题的工具。
作者简介
丁琛,乐豚联合创始人及CEO,曾在阿里巴巴负责支付宝,担任产品前端开发工作,业界著名的前端开发工程师。
目录
前言 I
第1章:加载和执行 1
1.1 脚本位置 2
1.2 组织脚本 4
1.3 阻塞的脚本 5
1.3.1 延迟的脚本 5
1.3.2 动态脚本元素 6
1.3.3 XMLHttpRequest脚本注入 9
1.3.4 推荐的阻塞模式 10
1.4 小结 14
第2章:数据访问 15
2.1 管理作用域 16
2.1.1 作用域链和标识符解析 16
2.1.2 标识符解析的性能 19
2.1.3 改变作用域链 21
2.1.4 动态作用域 24
2.1.5 闭包,作用域和内存 24
2.2 对象成员 27
2.2.1 原型 27
2.2.2 原型链 29
2.2.3 嵌套成员 30
2.2.4 缓存对象成员值 31
2.3 小结 33
第3章:DOM编程 35
3.1 浏览器中的DOM 35
3.1.1 天生就慢 36
3.2 DOM访问与修改 36
3.2.1 innerHTML对比DOM方法 37
3.2.2 节点克隆 41
3.2.3 HTML集合 42
3.2.4 遍历DOM 46
3.3 重绘与重排 50
3.3.1 重排何时发生? 51
3.3.2 渲染树变化的排队与刷新 51
3.3.3 最小化重绘和重排 52
3.3.4 缓存布局信息 56
3.3.5 让元素脱离动画流 56
3.3.6 IE和:hover 57
3.4 事件委托 57
3.5 小结 59
第4章:算法和流程控制 61
4.1 循环 61
4.1.1 循环的类型 61
4.1.2 循环性能 63
4.1.3 基于函数的迭代 67
4.2 条件语句 68
4.2.1 if-else对比switch 68
4.2.2 优化if-else 70
4.2.3 查找表 72
4.3 递归 73
4.3.1 调用栈限制 74
4.3.2 递归模式 75
4.3.3 迭代 76
4.3.4 Memoization 77
4.4 小结 79
第5章:字符串和正则表达式 81
5.1 字符串连接 81
5.1.1 加(+)和加等于(+=)操作符 82
5.1.2 数组项连接 84
5.1.3 String.prototype.concat 86
5.2 正则表达式优化 87
5.2.1 正则表达式工作原理 88
5.2.2 理解回溯 89
5.2.3 回溯失控 91
5.2.4 基准测试的说明 96
5.2.5 更多提高正则表达式效率的方法 96
5.2.6 何时不使用正则表达式 99
5.3 去除字符串首尾空白 99
5.3.1 使用正则表达式去首尾空白 99
5.3.2 不使用正则表达式去除字符串首尾空白 102
5.3.3 混合解决方案 103
5.4 小结 104
第6章:快速响应的用户界面 107
6.1 浏览器UI线程 107
6.1.1 浏览器限制 109
6.1.2 多久才算“太久”? 110
6.2 使用定时器让出时间片段 111
6.2.1 定时器基础 112
6.2.2 定时器的精度 114
6.2.3 使用定时器处理数组 114
6.2.4 分割任务 116
6.2.5 记录代码运行时间 118
6.2.6 定时器与性能 119
6.3 Web Workers 120
6.3.1 Worker运行环境 120
6.3.2 与Worker通信 121
6.3.3 加载外部文件 122
6.3.4 实际应用 122
6.4 小结 124
第7章:Ajax 125
7.1 数据传输 125
7.1.1 请求数据 125
7.1.2 发送数据 131
7.2 数据格式 134
7.2.1 XML 134
7.2.2 JSON 137
7.2.3 HTML 141
7.2.4 自定义格式 142
7.2.5 数据格式总结 144
7.3 Ajax性能指南 145
7.3.1 缓存数据 145
7.3.2 了解Ajax类库的局限 148
7.4 小结 149
第8章:编程实践 151
8.1 避免双重求值(Double Evaluation) 151
8.2 使用Object/Array直接量 153
8.3 不要重复工作 154
8.3.1 延迟加载 154
8.3.2 条件预加载 156
8.4 使用速度快的部分 156
8.4.1 位操作 156
8.4.2 原生方法 159
8.5 小结 161
第9章:构建并部署高性能JavaScript应用 163
9.1 Apache Ant 163
9.2 合并多个JavaScript文件 165
9.3 预处理JavaScript文件 166
9.4 JavaScript压缩 168
9.5 构建时处理对比运行时处理 170
9.6 JavaScript的HTTP压缩 170
9.7 缓存JavaScript文件 171
9.8 处理缓存问题 172
9.9 使用内容分发网络(CDN) 173
9.10 部署JavaScript资源 173
9.11 敏捷JavaScript构建过程 174
9.12 小结 175
第10章:工具 177
10.1 JavaScript性能分析 178
10.2 YUI Profiler 179
10.3 匿名函数 182
10.4 Firebug 183
10.4.1 控制台面板分析工具 183
10.4.2 Console API 184
10.4.3 网络面板 185
10.5 IE开发人员工具 186
10.6 Safari Web检查器(Web Inspector) 188
10.6.1 分析面板 189
10.6.2 资源面板 191
10.7 Chrome开发人员工具 192
10.8 脚本阻塞 193
10.9 Page Speed 194
10.10 Fiddler 196
10.11 YSlow 198
10.12 dynaTrace Ajax Edition 199
10.13 小结 202
索引 203
前言/序言
译者序
这是一本关于JavaScript性能的书。
在Web应用日趋丰富的今天,越来越多的JavaScript被运用在我们的网页中。随着用户体验被日益重视,前端性能对用户体验的影响开始备受关注,而引起性能问题的因素相对复杂,因此它很难得到全面的解决。这本书是一个契机,它尝试着从多个方面综合分析导致性能问题的原因,并给出适合的解决方案,帮助我们改善Web应用的品质。
这本书页数不多,但它承载着JavaScript性能方面最为宝贵的经验。不仅从语言特性、数据结构、浏览器机理、网络传输等层面分析导致性能问题的原因,还介绍了多种工具来帮助我们提升开发过程和部署环节的工作效率。
本书作者Nicholas C. Zakas是一位经验丰富的前端专家,他的许多研究(www.nczonline. net)对前端业界的贡献让我们受益匪浅。本书的另外五位特约作者均为各自领域的专家,他们的专业技能和知识的融入使得本书内容更为充实,更具实用价值。
特别感谢赵泽欣(小马),他为审阅译文花了大量的时间和精力,他的耐心和细致让我十分敬佩。感谢朱宁(白鸦)和周筠老师的引荐让我得以参与本书的翻译。还要感谢博文视点的编辑们在本书翻译过程中给予的极大理解和帮助。
我们在本书翻译过程中力求保持行文流畅,但纰漏在所难免,恳请广大读者批评指正。关于本书的任何意见或想法,欢迎发送邮件至hpj.feedback@gmail.com。
最后,希望本书能帮助业界同仁打造出性能更为卓越的Web产品。
丁琛
《JavaScript 艺术:精通 Web 交互的秘密》 开启前沿 Web 互动体验的钥匙 在这个数字时代,Web 应用早已超越了简单的信息展示,它们是动态的、响应式的、高度交互的数字空间,用户体验至关重要。而 JavaScript,作为 Web 开发领域不可或缺的语言,是这一切的驱动力。本书《JavaScript 艺术:精通 Web 交互的秘密》并非一本枯燥的技术手册,而是一次深入探索 JavaScript 核心机制、揭示其精妙之处的旅程。它将带领你超越基础语法,触及那些能够将普通 Web 应用转化为令人惊叹的互动体验的深层原理与高级技巧。 本书旨在为那些已经掌握 JavaScript 基础,但渴望在 Web 互动方面达到更高境界的开发者提供一个清晰的路线图。我们不提供“开箱即用”的解决方案,而是聚焦于“为什么”和“如何”,让你理解代码背后的逻辑,从而能够自主解决复杂问题,创造出真正富有表现力的 Web 应用。 内容深度剖析: 第一部分:JavaScript 引擎的脉搏——深入理解运行时 要精通一门语言,首先要理解它的“心脏”是如何跳动的。本部分将带你走进 JavaScript 引擎的内部世界。 V8 引擎的秘密: 我们将深入剖析 V8 引擎(或其他主流 JavaScript 引擎,如 SpiderMonkey)的工作原理。你将了解其编译器(Ignition 和 TurboFan/Liftoff)如何将 JavaScript 代码转化为机器码,以及 JIT(Just-In-Time)编译如何实现代码的即时优化。理解内存管理(垃圾回收机制 Scavenger、Mark-Sweep 等)的工作方式,以及如何避免内存泄漏,是提升应用性能的关键。 事件循环(Event Loop)的舞蹈: 理解事件循环是掌握异步编程的基石。我们将详细解析宏任务(macrotasks)和微任务(microtasks)的区别,以及它们在事件循环中的执行顺序。通过对 `setTimeout`、`setInterval`、Promise、`process.nextTick`(Node.js 环境)等异步 API 的深入分析,你将能够编写出更高效、更可控的异步代码,避免回调地狱,并深入理解 `async/await` 的真正威力。 执行上下文与作用域链: 变量的查找、函数的调用,这一切都离不开执行上下文(Execution Context)和作用域(Scope)。我们将系统地讲解全局执行上下文、函数执行上下文以及词法作用域(Lexical Scope)的形成。理解作用域链的工作原理,将帮助你清晰地把握变量的可访问性,避免意外的全局变量污染和作用域冲突。 第二部分:函数的高级艺术——构建灵活且强大的抽象 函数是 JavaScript 的基石,但其潜力远不止于此。本部分将解锁函数的许多高级特性,让你能够构建出更灵活、可复用且易于维护的代码。 闭包(Closures):封装与状态管理: 闭包是 JavaScript 中最强大也最容易被误解的概念之一。我们将通过丰富的实例,展示闭包如何实现数据私有化,如何构建模块,以及在柯里化(Currying)和函数式编程中的应用。你将学会如何利用闭包来管理状态,而无需依赖全局变量。 原型链(Prototypal Inheritance)与继承: JavaScript 的继承模型与基于类的语言有所不同。本书将深入剖析原型链的工作原理,理解 `__proto__`、`prototype` 和 `Object.create()` 的作用。你将学会如何有效地实现类式继承的模拟,以及如何利用原型链来共享方法和属性,从而优化内存使用。 `this` 的指向:理解动态绑定: `this` 的指向问题是 JavaScript 中的一个常见陷阱。我们将系统地梳理 `this` 在不同场景下的指向规则:全局上下文、函数调用、方法调用、构造函数调用、`call`、`apply`、`bind` 的应用,以及箭头函数(Arrow Functions)如何改变 `this` 的绑定。掌握 `this` 的指向,是编写健壮的面向对象代码的关键。 高阶函数(Higher-Order Functions): 函数作为一等公民,可以被作为参数传递,也可以被作为返回值返回。我们将探索 map、filter、reduce 等函数式编程中的核心高阶函数,并展示如何利用它们来简化复杂的操作,提高代码的声明性和可读性。 第三部分:异步编程的精妙策略——应对并发与延迟 Web 应用的响应式体验高度依赖于高效的异步处理。本部分将为你提供应对各种异步挑战的强大武器。 Promise 的进阶应用: 除了基本的链式调用,我们将深入讲解 Promise 的各种高级用法,例如 `Promise.all()`、`Promise.race()`、`Promise.any()`、`Promise.allSettled()` 的适用场景。你将学会如何优雅地处理多个并行或串行的异步操作,以及如何处理 Promise 的拒绝(Rejection)。 async/await 的真正威力: `async/await` 语法糖是 Promise 之上的抽象,极大地提升了异步代码的可读性。我们将深入探讨 `async/await` 背后的机制,以及如何在错误处理、循环和条件语句中更有效地使用它。你将掌握如何编写接近同步风格的异步代码。 生成器(Generators)与迭代器(Iterators): 生成器是 JavaScript 中一种强大的控制流工具,它允许你暂停函数的执行并稍后恢复。我们将讲解生成器的语法,以及如何利用它们来处理大量数据、实现自定义迭代器,并与异步操作结合,构建更复杂的控制流。 Web Workers:释放浏览器多线程能力: 对于计算密集型任务,Web Workers 是提升 Web 应用响应能力的关键。我们将介绍 Web Workers 的概念,如何创建和通信,以及在何时使用它们来避免阻塞主线程。 第四部分:性能优化与内存管理——打造流畅的用户体验 再好的交互,如果卡顿缓慢,也将大打折扣。本部分将聚焦于如何让你的 JavaScript 代码运行得更快,占用更少的内存。 DOM 操作的效率法则: DOM 操作是 Web 开发中常见的性能瓶颈。我们将探讨如何最小化 DOM 操作的次数,批量更新 DOM(Document Fragment),以及使用虚拟 DOM(Virtual DOM)的思想来提高渲染效率。 事件委托(Event Delegation)与节流/防抖(Throttling/Debouncing): 理解事件委托的原理,能够显著减少事件监听器的数量。节流和防抖则是处理高频触发事件(如滚动、鼠标移动)的利器,我们将讲解它们的实现方式及应用场景。 代码打包与模块化: 了解 Webpack、Rollup 等现代打包工具的工作原理,如何实现代码分割(Code Splitting)、tree shaking,以及如何有效地组织和管理你的 JavaScript 模块,是构建大型、高性能应用的必备知识。 性能分析工具的应用: 本书将指导你如何使用浏览器开发者工具(Performance Tab)进行性能分析,识别代码中的瓶颈,并根据分析结果进行针对性的优化。 第五部分:高级模式与设计原则——构建可维护的复杂系统 随着项目规模的增长,代码的可维护性变得尤为重要。本部分将介绍一些高级的设计模式和原则,帮助你构建更健壮、更易于扩展的 Web 应用。 设计模式在 JavaScript 中的应用: 我们将深入探讨一些常用的 JavaScript 设计模式,如单例模式(Singleton)、工厂模式(Factory)、观察者模式(Observer)、模块模式(Module Pattern)、发布/订阅模式(Publish/Subscribe)等,并展示它们如何在实际项目中落地。 函数式编程思想(Functional Programming): 函数式编程强调纯函数、不可变性(Immutability)和声明式编程。我们将介绍函数式编程的核心概念,以及如何将其融入你的 JavaScript 代码中,从而编写出更易于测试、更少副作用的代码。 响应式编程(Reactive Programming)简介: 随着 RxJS 等库的流行,响应式编程在现代 Web 开发中越来越受到关注。我们将简要介绍响应式编程的思想,以及它如何帮助你以一种声明式的方式处理复杂的异步数据流。 代码的健壮性与错误处理: 学习如何编写能够优雅处理错误的 JavaScript 代码,包括使用 `try...catch` 块、Promise 的拒绝处理,以及如何进行有效的错误日志记录,是确保应用稳定运行的关键。 本书特色: 深入的原理讲解: 我们不满足于“怎么做”,更关注“为什么这么做”。通过对 JavaScript 引擎、运行时机制的深入剖析,让你知其然,更知其所以然。 丰富的实例分析: 每一个概念都配以精心设计的代码示例,帮助你直观理解,并鼓励你在实际项目中进行实践。 前沿技术的探索: 关注 Web 开发的最新趋势,将最新的技术和理念融入到讲解之中。 实用的优化技巧: 聚焦于 Web 应用性能的提升,提供行之有效的优化策略和调试方法。 强调可读性与可维护性: 帮助你写出清晰、易于理解、易于维护的代码,为构建大型复杂项目奠定基础。 《JavaScript 艺术:精通 Web 交互的秘密》将是你从一名 JavaScript 开发者蜕变为一名 Web 互动艺术家的重要伙伴。它将为你打开一扇通往更深层次理解和更高境界创作的大门,让你能够自信地驾驭 JavaScript 的强大力量,创造出令人惊叹的 Web 体验。准备好,与我们一同踏上这场深入JavaScript灵魂的探索之旅吧!