二、使用 JSLint 提高代码性能

在本章中,我们将学习如何在 JavaScript 中确认性能修复,我们还将学习 JSLint。 有两个非常好的 JavaScript 验证和优化工具,我们将学习如何使用这两个工具,以及如何设置选项以获得最佳的代码性能优化结果。

因此,我们将在本章中涵盖以下主题:

  • 检查 JavaScript 代码性能
  • 什么是 JavaScript 检测?
  • 使用 JSLint

检查 JavaScript 代码性能

在我们开始谈论如何提高 JavaScript 的性能之前,我们必须问自己一个棘手的问题:哪些代码改进实际上提高了 JavaScript 应用的速度。 在 JavaScript 开发的早期,许多性能改进主要是基于已知的 JavaScript 编码标准实现的,在没有声明变量的情况下监视全局变量,保持变量范围一致,等等,除了网站内任何可视的东西之外,没有太多的验证。

今天,我们有了新的 api 来利用这个问题,并为代码的一小部分提供范围解决方案。

关于控制台时间 API

为了解决这个问题,现代的浏览器实现了新的控制台功能,称为console.timeconsole.timeEnd。 这两个函数所做的就是允许开发人员指定的标签console.timeconsole.timeEnd功能,测量的时间之间的一个代码块timetimeEnd实例需要的功能,最后,导致一个控制台。

让我们看看如何在一个工作示例中使用console.time()console.timeEnd()。 这里,在我们的02_01.js示例文件中,我们有一个简单的代码块,在for循环中使用new关键字创建 100 个简单的 JavaScript 对象,如下面的截图所示:

About the console time API

提示

下载示例代码

您可以从您的账户http://www.packtpub.com下载您购买的所有 pack 书籍的示例代码文件。 如果您在其他地方购买了这本书,您可以访问http://www.packtpub.com/support并注册,直接将文件通过电子邮件发送给您。

正如我们在第 5 行所看到的,我们调用了console.time函数,在函数内部,我们用100 objects in For Loop字符串标签作为代码块的参数。 然后在第 7 行添加一个NewObj对象构造器。 接下来,我们在第 11 行有一个简单的 JavaScriptfor循环,它创建了NewObj构造器的100实例,在第 13 行传递了for循环中每个实例的值。 最后,在第 16 行,我们用console.timeEnd函数结束时间块,使用与time实例开头声明的相同的标签。

让我们在浏览器中尝试这段代码; 我将使用谷歌 Chrome 浏览器,但任何现代浏览器,如最新版本的 Firefox、Internet Explorer 或 Safari,都应该可以。 我们将在浏览器的 URL 中打开about:blank,这样我们就可以在一个简单的测试环境中工作,然后我们将打开 Web 检查器或浏览器调试器,将代码片段粘贴到控制台,并按输入。 以下是在我的浏览器中显示的结果:

About the console time API

如果我们看一下输出中的undefined行之前,我们可以看到在console.time函数输出中定义的标签:100 objects in For loop: 0.274ms。 因此,通过一些硬数据,我们可以直观地看到,我们编写的代码块使用了0.274msJavaScript 解释器来处理这段代码。 很好,但是如果我们调整我们的代码,使它更有效,比如,改变我们的for循环,停止在10而不是100,会发生什么呢? 好了,这里是我们示例文件中的02_02.js文件的更新代码示例:

About the console time API

在这里,我们改变了for循环在第 5、11、12 和 16 行迭代的次数; 让我们运行这段代码,看看会发生什么,如下面的截图所示:

About the console time API

我们现在可以看到,将for循环降至10迭代,而100迭代将处理时间从0.274ms降至0.099ms。 我们可以将其扩展到更大的应用,因为我们知道这个性能测试 API 对评估 JavaScript 代码的性能非常有帮助。

何时使用控制台

console.time()方法允许开发人员了解哪些代码会影响性能,哪些不会。 console.time()方法提供的结果不仅基于您使用的浏览器,而且还基于您使用的操作系统和系统硬件。 如果您运行前面的代码片段,它们应该接近本书中给出的值,但更有可能不是相同的小变化。

所以,当使用console.time()的时候,把它们当作一个指导,而不是一个艰难的结果。 当我们使用console.time()方法阅读这本书时,根据你的工作环境,这里列出的结果和你所经历的可能会有一些差异。 应该一致的是,当使用console.time()方法时,您将看到总体上的性能改进。

现在我们已经掌握了性能测试的知识,我们将开始学习 JavaScript 中常见的性能瓶颈,但在我们深入研究这些概念之前,我们将看看帮助评估过程的工具。

什么是 JavaScript 检测?

在讨论 JSLint 之前,我们需要一般地讨论一下检查器,它们是什么,以及它们是如何影响 JavaScript 性能的。 简单地说,lint 是一个代码验证检查器。 它允许开发人员指向代码文件并检查错误或潜在问题,范围从空格问题到纯代码错误。

检查器通常接收文件的内容并构建源树。 在 JavaScript 中,可以是全局变量、函数、原型、数组等对象。 在创建树之后,分析程序将获取源代码树的一部分,并报告分析程序将标记的任何内容。 最后,在运行 linter 之前标记的任何规则读取器或参数都将查找要忽略的选项并生成最终报告。

JavaScript 选项的常见规则读取器是设置,例如检查 EcmaScript 3、允许空格、允许continue关键字、允许if语句使用非严格条件,等等。

关于 JSLint

JSLint 是一个 JavaScript 代码分析工具,由 Douglas Crockford 用 JavaScript 编写,他也帮助推广了 JSON 在软件开发中的应用。 JSLint 的使用有多种方式,如在第 1 章The Need for Speed中所述。 许多 ide 的功能不仅仅是编辑代码; 其中一些特性包括错误检查,在某些情况下,ide 使用 JSLint 的一个版本。

在本章中,我们将讨论如何使用 JSLint 的官方在线网站http://www.jslint.com/,如下面的截图所示:

About JSLint

使用 JSLint

JSLint 非常容易使用一个站点; 您所需要的只是一些 JavaScript,并将代码文件粘贴到 JSLint 中。 让我们尝试一个小的代码示例,如下面的截图所示,你可以在示例文件中引用02_03.js文件:

Using JSLint

现在,让我们将我们的代码粘贴到输入框中http://www.JSLint.com,并点击JSLint按钮。 马上,我们就会看到JSLint按钮下面的错误列表,如下图所示:

Using JSLint

参见以下遗留错误:

Using JSLint

复习错误

在查看这些错误之前,让我们先看看错误列表的底部; 我们将看到一个错误:Stopping. (52% scanned)。 这是一个警告,JSLint 发现了太多的错误,以至于 JSLint 中的分析器工具干脆放弃了检查错误。 在检查 JSLint 消息时,记住这个错误很重要; 由于只有 52%的代码被审查,一旦我们修复它们,额外的错误可能会出现。

好的,现在我们已经理解了 JSLint 的限制,让我们修复这些错误。 当使用 JSlint 时,从上到下遍历错误列表,因此错误 1 是Unexpected character '(space)'.。 那是什么意思? 为了解释,JSLint 是非常挑剔的方式,应该在 JavaScript 文件的间距。 JavaScript 解释器假定在特定的 JavaScript 对象和变量中有特定的空格。

这个空白会在代码中出现任何其他错误之前显示,因此我们可以假设这个错误出现在任何代码出现之前,事实上,情况就是这样。 如果我们查看02_03.js文件,实际上第 4 行是导致问题的原因,即注释头和my_count全局变量之间的空格。

配置凌乱的空白

我们可以用两种方法来解决的空格错误:我们可以检查每个空格并逐行更正它,或者,如果我们在使用缩小器,我们可以告诉 JSLint 忽略空的和不必要的行。 为了做到这一点,我们将导航到页面底部的选项,并将杂乱的空白选项设置为true 这将告诉 JSLint 忽略任何与代码解释没有直接关联的空格问题,如下面的截图所示:

Configuring messy white space

一旦这个设置为true,我们将看到一个新的面板出现在选项下,称为JSLint DirectivesJSLint Directives面板提供了一个快速的参数列表,JSLint 将在执行验证器之前检查代码时传入。 如果我们试图在 JSLint 的另一个实例(比如构建系统)中复制并粘贴这个配置,在这里看到指令是非常有用的。

忽略混乱的空白,我们可以在代码上重新运行 JSLint,并看到更新后的错误列表,如下所示:

Configuring messy white space

现在,我们检查 JSLint 检测到多少代码。 这一次,如果我们查看最后一个错误,我们可以看到 JSLint 停止在84%,这比以前好多了,但是我们可以在这里做得更好。 让我们看看第一个新错误。 在错误列表的顶部,我们可以看到错误陈述为'my_count' was used before it was defined.,这是第 5 行,在Errors面板中的字符 1。

这表明我们忘了在my_count变量之前声明var,所以让我们按照如下截图更新它,在第 5 行将var添加到my_count中,然后让我们重新运行 JSLint。 您可以将练习文件中的更新引用为02_03_01``.js:

Configuring messy white space

接下来,用更新后的代码运行 JSLint 之后,让我们看看下面两行。 第一行是Unexpected TODO comment。 这很简单; 在 JSLint 中,我们可以在 JavaScript 代码中指定允许TODO 注释,这非常方便! 让我们允许这样做,因为我们只是在 JSLint 中改进我们的代码,目前还没有完成文件。 看看我突出显示的选项,你可以设置 TODO 是否允许:

Configuring messy white space

我们现在将Options面板中的TODO comments设置为true; 接下来,让我们看看其余的错误。

理解使用严格语句

下面是我们的 JSLint 错误列表中剩下的内容,如下面的截图所示。 我们看到的下一个错误是Missing 'use strict' statement.。 现在,如果你之前没有见过 JavaScript 中的use strict语句,我将解释:

Understanding the use strict statement

use strict语句提示浏览器在运行时读取 JavaScript 时启用严格模式。 这使得通常以警告形式显示的错误可以在浏览器中以错误的形式返回。 在我们的代码中使用use strict语句的另一个好处是,它允许 JavaScript 解释器运行得更快,因为它假设代码已经经过了优化和错误测试。 这告诉 JavaScript 解释器这里的代码已经被正确地编写,解释器不需要在运行时对代码进行那么多的检查。

使用use strict语句并不难实现,我们可以像这样在每个函数的代码之前添加它:

Understanding the use strict statement

我们也可以将它添加到整个 JavaScript 文件的第一行代码之上,如下面的截图所示:

Understanding the use strict statement

关于 JSLint 的use strict语句需要知道的一件事是,JSLint更喜欢在函数级别设置use strict语句(在前面的第一个use strict示例中显示)。 它的想法是根据函数适当地设置use strict语句的范围,以更好地进行代码测试和分析,但这两者在 JavaScript 中都是正确的。

让我们在TODO评论下结束这些剩余的问题; 在第 9 行,将添加"use strict",然后在console.log语句之后的第 10 行添加分号。 完成后,它应该类似如下截图:

Understanding the use strict statement

在 JSLint 中使用控制台

我们已经差不多完成了这个代码。 然而,在执行它时,我们得到一个错误列表,其中第一行(看起来有点奇怪)表示:'console' was used before it was defined.in theerrors面板。 JSLint 可以验证不是为浏览器设计的 JavaScript; 例如,这可以是一个 Node.js 脚本。 为了启用浏览器对象,我们需要在 JSLintoptions面板中启用控制台、浏览器选项; 我们可以将这些设置为true,如下截图所示:

Using console in JSLint

启用这些选项后,让重新运行脚本; 剩下的错误应该是直接的。 第一个错误抱怨我们应该Combine this with the previous 'var' statement.。 我们可以删除number1number2变量,简单地赋值my_count = 42;

最后,我们的if声明需要做一些工作。 首先,JSLint 抱怨我们在if语句中使用了一个松散条件(用于比较的双等号)。 如果使用三重 equals 进行比较,则也要比较类型。 通过这样做,我们的代码将比以前更快地运行比较。 此外,if语句没有在条件代码周围包含括号,这可能会降低解释器的速度,所以让我们添加它们。 我们的最终代码应该类似如下截图:

Using console in JSLint

现在让我们通过 JSLint 重新运行最终确定的代码,我们应该会看到这样的屏幕:

Using console in JSLint

我们可以看到,我们现在在 JSLint 没有错误,我们还可以看到一个函数报告面板中,表示一个变量范围的变量是全局什么文件,变量和函数内部存在一个函数,包括我们的匿名函数的例子。

在结束本章之前,让我们用console.time函数在2_03_01.js02_03_03.js代码文件中尝试一下console.time方法。 我得到我的时间为前者是0.441ms,而优化代码与 JSLint 是0.211ms! 不坏; 的表现!

小结

在本章中,我们学习了console.timeconsole.timeEnd方法的基础知识,我们还学习了 JSLint 以及它如何提高我们的 JavaScript 性能。 在下一章中,我们将快速浏览一下 JSLint,并将其集成到构建系统中。