客户端性能

在之前的文章中,我介绍了理解、分析和改进您的 Web 应用程序性能的不同方法。我已经表明,在您的网络连接、服务器硬件、数据库设计和 HTTP 服务器配置之间,您可以更改和改进您的 Web 应用程序的性能——嗯,某种程度上是这样。Web 应用程序在刚开始时,仅在服务器端是动态的。当然,它们输出 HTML——以及后来的 CSS 和 JavaScript——但是绝大多数处理和计算都发生在服务器上。

当然,这种模式在过去十年中发生了巨大的变化,以至于您现在可以准确地声称自己是一名 Web 开发人员,并且几乎完全使用 HTML、CSS 和 JavaScript 工作,几乎没有或根本没有服务器端组件。诸如 Ember.js、Angular.js 和 React.js 等整个 MVC 框架都假设您将用 JavaScript 编写应用程序,并为您提供执行此操作所需的对象和基础设施。

如果您担心 Web 应用程序的性能,则不仅需要关注服务器上发生的事情,还需要关注浏览器中发生的事情。一些商业性能监控解决方案已经考虑到了这一点,使您能够查看元素在用户浏览器上渲染和执行所需的时间。但是,也有大量开源工具可供您检查和改进客户端程序的执行方式。

本月,我将总结对 Web 应用程序性能的探索,并对需要牢记的事项以及有助于确保您实际执行应执行操作的工具进行调查。

客户端注意事项

客户端代码是用 JavaScript 编写的。无论代码是内联在 <script> 标签中还是从远程服务器检索,都会在浏览器解析器到达页面该部分时执行。如果您在页面顶部有 JavaScript,则会在解析器到达该部分时执行它,这可能会延迟页面其余部分的渲染。相比之下,如果您的 JavaScript 位于底部,则解析器仅在解析和渲染页面的其余部分后才会执行它。这就是为什么这么多开发人员学会将他们的 JavaScript 命令放在“document-ready”回调函数中的原因;这样,代码仅在整个页面加载完毕后才执行。

由于许多现代 Web 应用程序都在 JavaScript 中进行,因此您经常从远程服务器加载 JavaScript 意味着渲染页面所需的时间不仅取决于服务器速度、网络带宽和页面的复杂性,还取决于提供此类 JavaScript 的服务器和网络,以及这些页面的复杂性。因此,通常认为最佳实践是在 HTML 页面的底部尽可能晚地加载尽可能多的库。也就是说,您应该将 <script> 标签(无论是本地的还是远程的)放在页面的底部,而不是放在顶部——除非必须这样做。

更好的是,您应该将 JavaScript 文件合并为一个文件。这有很多优点。这意味着用户的浏览器只需要下载一个文件,而不是很多文件。如果您将站点上需要的所有 JavaScript 都包含在一个文件中,那么也意味着该文件只需要加载一次。在随后的每个页面加载中,都会提到 JavaScript,但不会下载它,因为它已经缓存在浏览器的内存中。当然,您可以通过压缩单个 JavaScript 文件使事情变得更好。事实证明这非常有效,因为压缩算法对于文本,尤其是对于重复自身的文本(如程序代码)效果很好。

更好的是,您可以运行 JavaScript 代码通过一个最小化器(或“压缩器”),它会删除注释、多余的空格以及客户端程序运行不需要的任何其他内容。通过最小化 JavaScript 文件,组合文件,然后压缩生成的组合,您可以显着减小发送到用户浏览器的 JavaScript 的大小,并确保它在每次访问您的网站时仅加载一次。

例如,UglifyJS 可以通过 npm 安装


npm install uglify-js -g

您可以使用以下命令在文件上运行它


uglifyjs FILENAME

虽然这会将输出发送到 stdout,但您可能希望将其重定向到一个文件


uglifyjs FILENAME > ugFILENAME.js

我从我的博士论文软件中提取了 JavaScript,并通过 uglifyjs 和 gzip 运行它。原始的 36KB 文件在压缩后为 8.5KB,但在丑化和压缩后为 6.0KB。尽管您可能会嘲笑现代世界中 36KB 文件的小尺寸,但事实是每个文件都需要时间,对于浏览器和服务器都是如此。您越快将其从服务器上取出并放入浏览器,效果就越好。

下载时间

一旦 JavaScript 进入用户的浏览器,事情就变得既容易又难以分析。一方面,您(开发人员)可以下载程序,对其进行测试并检查性能——然后,您还可以使用浏览器内调试工具来测试和改进。

Chrome 和 Firefox 提供的最重要的工具之一是显示发送到浏览器的文件。即使您的站点看起来加载和渲染速度很快,快速查看下载时间线几乎肯定会让您感到惊讶甚至震惊。您会看到每个 JavaScript(以及 CSS 和图像)文件下载所需的时间,从而了解用户请求您的页面到内容实际出现在页面上之间需要多少时间。这是一种很好的方法,可以帮助您识别潜在的瓶颈,然后减少它们对站点速度(或表面速度)的影响。

即使通常被认为是(商业)服务器端性能监控器的 New Relic 现在也提供了一些客户端性能检查。您在您的网站上放置一小段 JavaScript; New Relic 收集此信息,然后告诉您内容到达用户浏览器所需的时间以及渲染所需的时间。这为您提供了出人意料的深刻见解,了解您是否需要努力提高文件传递速度或进一步优化代码,以便代码运行得更快。肯定还有其他选择,但我发现即使是免费的(非开源,但免费)New Relic 客户端基准测试也非常有用。

在您组合并压缩 JavaScript 文件后,您应该认真考虑将它们以及任何其他静态资源(例如 CSS 文件和图像)放在内容分发网络 (CDN) 上。CDN 仅处理静态内容,但考虑到有多少大型、下载速度慢的文件是静态的,这通常可以提供显着的改进。CDN 不仅具有很大的带宽,而且还将您的内容复制到多台服务器,使用地理位置最近的服务器为您的用户提供内容。因此,东京的用户将从本地 CDN 服务器接收数据,而芝加哥的用户将从不同的 CDN 服务器接收数据。因此,使用 CDN 可以减轻主 Web 服务器的负载,同时减少实际和感知到的下载时间。

JavaScript 基准测试

尽管 JavaScript 以(我认为当之无愧的)令人沮丧和古怪的语言而闻名,但事实是,现代 JavaScript 实现运行速度非常快——假设您以正确的方式使用该语言。但是,有时很难知道您的程序将大部分时间花在哪里。幸运的是,Chrome 开发人员工具(Chrome 浏览器的一部分)包含一个分析工具。转到开发人员工具中的“Profile”选项卡,并在访问您的站点之前选择 CPU 选项。您可以运行您的站点几秒钟或几分钟,然后再停止分析。完成此操作后,您将获得(非常长的)指示,指示哪些 JavaScript 程序正在运行,它们来自哪里以及 CPU 在每个程序中花费了多少时间。

您同样可以要求分析器检查内存使用情况。您编写的应用程序越复杂,这些工具就越必要。与此同时,您可能会发现,当您分析 JavaScript 代码时,最常用的代码可能不是您自己编写的代码,而是您正在使用的底层框架的一部分。

在基于 Firefox 的调试器 Firebug 中,您可以通过转到“控制台”选项卡并单击“Profile”来分析页面。您将看到一个表格,显示每个函数花费了多少时间,以及在那里花费的时间占总时间的百分比。如果您是 Chrome 用户,则可以打开开发人员工具并单击“Profiles”选项卡。然后,您需要选择是要检查 CPU 性能还是内存性能(以两种不同的风格)。启动和停止分析器后,您可以分析 JavaScript 使用的资源——然后,当然,适当地更改您的代码。

我开始更频繁地使用的一个工具是 Google 的 PageSpeed。这个工具集似乎是一个 SaaS,是 YSlow 的更新版本,YSlow 多年来一直是我的首选工具。例如,Google 的工具会告诉您您的网站对移动设备的友好程度。

此外,PageSpeed 结果始终指向文档,这些文档详细描述了问题为何存在问题以及您可以采取哪些步骤来解决这些问题。这些文档写得非常好,并且为如何提高 JavaScript 和 CSS 的性能提出了非常实用、清晰的建议。在针对我客户的网站之一运行 PageSpeed 后,我发现我们仍然有一些阻塞 JavaScript 的位置高于可能需要的水平。它还建议可以压缩哪些图像以及我们可以节省多少空间。

总结

尽管服务器端编程仍然是 Web 的重要组成部分,但客户端是大部分操作发生的地方,也是用户经常感知到延迟和缓慢的地方。因此,值得投入时间来检查您的客户端性能并在用户开始抱怨(或默默离开您)之前解决问题。使用各种工具来检查您的性能,以及减小 JavaScript 和 CSS 下载的大小和时间,将大大有助于提高用户对您网站的满意度。

Reuven Lerner 在世界各地的公司教授 Python、数据科学和 Git。您可以订阅他的免费每周“更好的开发人员”电子邮件列表,并通过他的书籍和课程在 http://lerner.co.il 学习。Reuven 与他的妻子和孩子住在以色列的莫迪因。

加载 Disqus 评论