百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程字典 > 正文

精读《高效 javascript》(js 高级技巧)

toyiye 2024-08-24 00:28 4 浏览 0 评论

前言

本期我来给大家推荐的书是《高性能JavaScript》,在这本书中我们能够了解 javascript 开发过程中的性能瓶颈,如何提升各方面的性能,包括代码的加载、运行、DOM交互、页面生存周期等。同样我们今天还是用思维导图的方式来精读一遍。(思维导图图片可能有点小,记得点开看,你会有所收获)

加载和执行

管理浏览器中的 JavaScript 代码是个棘手的问题,因为代码执行阻塞了其他浏览器处理过程,诸如用户 界面绘制。每次遇到<script>标签,页面必须停下来等待代码下载(如果是外部的)并执行,然后再继续处 理页面其他部分。但是,有几种方法可以减少 JavaScript 对性能的影响:

  1. 将所有<script>标签放置在页面的底部,紧靠 body 关闭标签</body>的上方。此法可以保证页面在脚本 运行之前完成解析。
  2. 将脚本成组打包。页面的<script>标签越少,页面的加载速度就越快,响应也更加迅速。不论外部脚本 文件还是内联代码都是如此。

有几种方法可以使用非阻塞方式下载 JavaScript:

  • <script>标签添加 defer 属性(只适用于 Internet Explorer 和 Firefox 3.5 以上版本)
  • 动态创建<script>元素,用它下载并执行代码
  • 用 XHR 对象下载代码,并注入到页面中

通过使用上述策略,你可以极大提高那些大量使用 JavaScript 代码的网页应用的实际性能。

数据存取

在 JavaScript 中,数据存储位置可以对代码整体性能产生重要影响。有四种数据访问类型:直接量,变 量,数组项,对象成员。它们有不同的性能考虑。

直接量和局部变量访问速度非常快,数组项和对象成员需要更长时间。局部变量比域外变量快,因为它位于作用域链的第一个对象中。变量在作用域链中的位置越深,访问所需 的时间就越长。全局变量总是最慢的,因为它们总是位于作用域链的最后一环。避免使用 with 表达式,因为它改变了运行期上下文的作用域链。而且应当小心对待 try-catch 表达式的 catch 子句,因为它具有同样效果。嵌套对象成员会造成重大性能影响,尽量少用。

一个属性或方法在原形链中的位置越深,访问它的速度就越慢。一般来说,你可以通过这种方法提高 JavaScript 代码的性能:将经常使用的对象成员,数组项,和域外变 量存入局部变量中。然后,访问局部变量的速度会快于那些原始变量。通过使用这些策略,你可以极大地提高那些需要大量 JavaScript 代码的网页应用的实际性能。

DOM 编程

DOM 访问和操作是现代网页应用中很重要的一部分。但每次你通过桥梁从 ECMAScript 岛到达 DOM 岛 时,都会被收取“过桥费”。为减少 DOM 编程中的性能损失,请牢记以下几点:

最小化 DOM 访问,在 JavaScript 端做尽可能多的事情。在反复访问的地方使用局部变量存放 DOM 引用.小心地处理 HTML 集合,因为他们表现出“存在性”,总是对底层文档重新查询。将集合的 length 属性缓 存到一个变量中,在迭代中使用这个变量。如果经常操作这个集合,可以将集合拷贝到数组中。

如果可能的话,使用速度更快的 API,诸如 querySelectorAll()和 firstElementChild。注意重绘和重排版;批量修改风格,离线操作 DOM 树,缓存并减少对布局信息的访问。动画中使用绝对坐标,使用拖放代理。使用事件托管技术最小化事件句柄数量。

算法和流程控制

正如其他编程语言,代码的写法和算法选用影响 JavaScript 的运行时间。与其他编程语言不同的是, JavaScript 可用资源有限,所以优化技术更为重要。

for,while,do-while 循环的性能特性相似,谁也不比谁更快或更慢。除非你要迭代遍历一个属性未知的对象,否则不要使用 for-in 循环。改善循环性能的最好办法是减少每次迭代中的运算量,并减少循环迭代次数。

一般来说,switch 总是比 if-else 更快,但并不总是最好的解决方法。当判断条件较多时,查表法比 if-else 或者 switch 更快。

浏览器的调用栈尺寸限制了递归算法在 JavaScript 中的应用;栈溢出错误导致其他代码也不能正常执行。如果你遇到一个栈溢出错误,将方法修改为一个迭代算法或者使用制表法可以避免重复工作。

运行的代码总量越大,使用这些策略所带来的性能提升就越明显。

字符串和正则表达式

密集的字符串操作和粗浅地编写正则表达式可能是主要性能障碍,但本章中的建议可帮助您避免常见缺陷。当连接数量巨大或尺寸巨大的字符串时,数组联合是 IE7 和它的早期版本上唯一具有合理性能的方法。如果你不关心 IE7 和它的早期版本,数组联合是连接字符串最慢的方法之一。使用简单的+和+=取而代之, 可避免(产生)不必要的中间字符串。

回溯既是正则表达式匹配功能基本的组成部分,又是正则表达式影响效率的常见原因。回溯失控发生在正则表达式本应很快发现匹配的地方,因为某些特殊的匹配字符串动作,导致运行缓慢 甚至浏览器崩溃。避免此问题的技术包括:使相邻字元互斥,避免嵌套量词对一个字符串的相同部分多次 匹配,通过重复利用前瞻操作的原子特性去除不必要的回溯。

提高正则表达式效率的各种技术手段,帮助正则表达式更快地找到匹配,以及在非匹配位置上花费更少 时间(见《更多提高正则表达式效率的方法》)。正则表达式并不总是完成工作的最佳工具,尤其当你只是搜索一个文本字符串时。

虽然有很多方法来修整一个字符串,使用两个简单的正则表达式(一个用于去除头部空格,另一个用于 去除尾部空格)提供了一个简洁、跨浏览器的方法,适用于不同内容和长度的字符串。从字符串末尾开始 循环查找第一个非空格字符,或者在一个混合应用中将此技术与正则表达式结合起来,提供了一个很好的 替代方案,它很少受到字符串整体长度的影响。

快速响应用户界面

JavaScript 和用户界面更新在同一个进程内运行,同一时刻只有其中一个可以运行。这意味着当 JavaScript 代码正在运行时,用户界面不能响应输入,反之亦然。有效地管理 UI 线程就是要确保 JavaScript 不能运行 太长时间,以免影响用户体验。最后,请牢记如下几点:

  1. JavaScript 运行时间不应该超过 100 毫秒。过长的运行时间导致 UI 更新出现可察觉的延迟,从而对整体 用户体验产生负面影响。
  2. JavaScript 运行期间,浏览器响应用户交互的行为存在差异。无论如何,JavaScript 长时间运行将导致用 户体验混乱和脱节。
  3. 定时器可用于安排代码推迟执行,它使得你可以将长运行脚本分解成一系列较小的任务。

网页工人线程是新式浏览器才支持的特性,它允许你在 UI 线程之外运行 JavaScript 代码而避免锁定 UI。网页应用程序越复杂,积极主动地管理 UI 线程就越显得重要。没有什么 JavaScript 代码可以重要到允 许影响用户体验的程度。

Ajax

高性能 Ajax 包括:知道你项目的具体需求,选择正确的数据格式和与之相配的传输技术。

作为数据格式,纯文本和 HTML 是高度限制的,但它们可节省客户端的 CPU 周期。XML 被广泛应用 普遍支持,但它非常冗长且解析缓慢。JSON 是轻量级的,解析迅速(作为本地代码而不是字符串),交 互性与 XML 相当。字符分隔的自定义格式非常轻量,在大量数据集解析时速度最快,但需要编写额外的 程序在服务器端构造格式,并在客户端解析。

当从页面域请求数据时,XHR 提供最完善的控制和灵活性,尽管它将所有传入数据视为一个字符串, 这有可能降低解析速度。另一方面,动态脚本标签插入技术允许跨域请求和本地运行 JavaScript 和 JSON, 虽然它的接口不够安全,而且不能读取信息头或响应报文代码。多部分 XHR 可减少请求的数量,可在一次响应中处理不同的文件类型,尽管它不能缓存收到的响应报文。当发送数据时,图像灯标是最简单和最 有效的方法。XHR 也可用 POST 方法发送大量数据。

除这些格式和传输技术之外,还有一些准则有助于进一步提高 Ajax 的速度:

  1. 减少请求数量,可通过 JavaScript 和 CSS 文件打包,或者使用 MXHR。
  2. 缩短页面的加载时间,在页面其它内容加载之后,使用 Ajax 获取少量重要文件。
  3. 确保代码错误不要直接显示给用户,并在服务器端处理错误。
  4. 学会何时使用一个健壮的 Ajax 库,何时编写自己的底层 Ajax 代码。

Ajax 是提升你网站潜在性能之最大的改进区域之一,因为很多网站大量使用异步请求,又因为它提供 了许多不相关问题的解决方案,这些问题诸如,需要加载太多资源。对 XHR 的创造性应用是如此的与众 不同,它不是呆滞不友好的界面,而是响应迅速且高效的代名词;它不会引起用户的憎恨,谁见了它都会 爱上它。

编程实践

JavaScript 提出了一些独特的性能挑战,关系到你组织代码的方法。网页应用变得越来越高级,包含的 JavaScript 代码越来越多,出现了一些模式和反模式。请牢记以下编程经验:

  1. 通过避免使用 eval_r()和 Function()构造器避免二次评估。此外,给 setTimeout()和 setInterval()传递函数参 数而不是字符串参数。
  2. 创建新对象和数组时使用对象直接量和数组直接量。它们比非直接量形式创建和初始化更快。
  3. 避免重复进行相同工作。当需要检测浏览器时,使用延迟加载或条件预加载。
  4. 当执行数学远算时,考虑使用位操作,它直接在数字底层进行操作。
  5. 原生方法总是比 JavaScript 写的东西要快。尽量使用原生方法。

构建并部署高性能 javascript 应用

开发和部署过程对基于 JavaScript 的应用程序可以产生巨大影响,最重要的几个步骤如下:

  1. 合并 JavaScript 文件,减少 HTTP 请求的数量
  2. 使用 YUI 压缩器紧凑处理 JavaScript 文件
  3. 以压缩形式提供 JavaScript 文件(gzip 编码)
  4. 通过设置 HTTP 响应报文头使 JavaScript 文件可缓存,通过向文件名附加时间戳解决缓存问题
  5. 使用内容传递网络(CDN)提供 JavaScript 文件,CDN 不仅可以提高性能,它还可以为你管理压缩和缓 存

所有这些步骤应当自动完成,不论是使用公开的开发工具诸如 Apache Ant,还是使用自定义的开发工具 以实现特定需求。如果你使这些开发工具为你服务,你可以极大改善那些大量使用 JavaScript 代码的网页 应用或网站的性能。

工具

当网页或应用程序变慢时,分析网上传来的资源,分析脚本的运行性能,使你能够集中精力在那些需要 努力优化的地方。使用网络分析器找出加载脚本和其它页面资源的瓶颈所在,这有助于决定哪些脚本需要延迟加载,或者 进行进一步分析。传统的智慧告诉我们应尽量减少 HTTP 请求的数量,尽量延迟加载脚本以使页面渲染速度更快,向用户 提供更好的整体体验。使用性能分析器找出脚本运行时速度慢的部分,检查每个函数所花费的时间,以及函数被调用的次数, 通过调用栈自身提供的一些线索来找出哪些地方应当努力优化。虽然花费时间和调用次数通常是数据中最有价值的点,还是应当仔细察看函数的调用过程,可能发现其 它优化方法。这些工具在那些现代代码所要运行的编程环境中不再神秘。在开始优化工作之前使用它们,确保开发时 间用在解决问题的刀刃上。

最后

如果你觉得此文对你有一丁点帮助,点个赞。或者可以加入我的开发交流群:1025263163相互学习,我们会有专业的技术答疑解惑

如果你觉得这篇文章对你有点用的话,麻烦请给我们的开源项目点点star: https://gitee.com/ZhongBangKeJi/CRMEB不胜感激 !

相关推荐

# Python 3 # Python 3字典Dictionary(1)

Python3字典字典是另一种可变容器模型,且可存储任意类型对象。字典的每个键值(key=>value)对用冒号(:)分割,每个对之间用逗号(,)分割,整个字典包括在花括号({})中,格式如...

Python第八课:数据类型中的字典及其函数与方法

Python3字典字典是另一种可变容器模型,且可存储任意类型对象。字典的每个键值...

Python中字典详解(python 中字典)

字典是Python中使用键进行索引的重要数据结构。它们是无序的项序列(键值对),这意味着顺序不被保留。键是不可变的。与列表一样,字典的值可以保存异构数据,即整数、浮点、字符串、NaN、布尔值、列表、数...

Python3.9又更新了:dict内置新功能,正式版十月见面

机器之心报道参与:一鸣、JaminPython3.8的热乎劲还没过去,Python就又双叒叕要更新了。近日,3.9版本的第四个alpha版已经开源。从文档中,我们可以看到官方透露的对dic...

Python3 基本数据类型详解(python三种基本数据类型)

文章来源:加米谷大数据Python中的变量不需要声明。每个变量在使用前都必须赋值,变量赋值以后该变量才会被创建。在Python中,变量就是变量,它没有类型,我们所说的"类型"是变...

一文掌握Python的字典(python字典用法大全)

字典是Python中最强大、最灵活的内置数据结构之一。它们允许存储键值对,从而实现高效的数据检索、操作和组织。本文深入探讨了字典,涵盖了它们的创建、操作和高级用法,以帮助中级Python开发...

超级完整|Python字典详解(python字典的方法或操作)

一、字典概述01字典的格式Python字典是一种可变容器模型,且可存储任意类型对象,如字符串、数字、元组等其他容器模型。字典的每个键值key=>value对用冒号:分割,每个对之间用逗号,...

Python3.9版本新特性:字典合并操作的详细解读

处于测试阶段的Python3.9版本中有一个新特性:我们在使用Python字典时,将能够编写出更可读、更紧凑的代码啦!Python版本你现在使用哪种版本的Python?3.7分?3.5分?还是2.7...

python 自学,字典3(一些例子)(python字典有哪些基本操作)

例子11;如何批量复制字典里的内容2;如何批量修改字典的内容3;如何批量修改字典里某些指定的内容...

Python3.9中的字典合并和更新,几乎影响了所有Python程序员

全文共2837字,预计学习时长9分钟Python3.9正在积极开发,并计划于今年10月发布。2月26日,开发团队发布了alpha4版本。该版本引入了新的合并(|)和更新(|=)运算符,这个新特性几乎...

Python3大字典:《Python3自学速查手册.pdf》限时下载中

最近有人会想了,2022了,想学Python晚不晚,学习python有前途吗?IT行业行业薪资高,发展前景好,是很多求职群里严重的香饽饽,而要进入这个高薪行业,也不是那么轻而易举的,拿信工专业的大学生...

python学习——字典(python字典基本操作)

字典Python的字典数据类型是基于hash散列算法实现的,采用键值对(key:value)的形式,根据key的值计算value的地址,具有非常快的查取和插入速度。但它是无序的,包含的元素个数不限,值...

324页清华教授撰写【Python 3 菜鸟查询手册】火了,小白入门字典

如何入门学习python...

Python3.9中的字典合并和更新,了解一下

全文共2837字,预计学习时长9分钟Python3.9正在积极开发,并计划于今年10月发布。2月26日,开发团队发布了alpha4版本。该版本引入了新的合并(|)和更新(|=)运算符,这个新特性几乎...

python3基础之字典(python中字典的基本操作)

字典和列表一样,也是python内置的一种数据结构。字典的结构如下图:列表用中括号[]把元素包起来,而字典是用大括号{}把元素包起来,只不过字典的每一个元素都包含键和值两部分。键和值是一一对应的...

取消回复欢迎 发表评论:

请填写验证码