Tian性能优化:2018年JavaScript开销及优化工具和方法

10年服务1亿Tian开发工程师

注:现代Tian开发中性能瓶颈依然在于JavaScript,而且Tian项目中JavaScript开销越来越大。本文详细介绍了 JavaScript 开销及原因,更是给出了相应的Tian性能优化工具和方法。文章有点长,但是相信你可以获得很多有用的信息。

相关文章:
[Tian性能优化]移动端页面的 JavaScript 开销
JavaScript性能优化技巧


构建交互式网站必定涉及向用户发送大量的JavaScript代码。 你在移动设备上打开页面,是否看起来像是一直加载,或尝试滚动时,页面没有任何反应?

因为一个字节一个字节的发送和解析,JavaScript仍然是我们向手机发送的最昂贵的资源,因为它可以在很大程度上延迟可交互性。

通过 () 测试 CNN.com 的 JavaScript 处理时间。高端手机(iPhone 8)可在~4秒内处理脚本。相比之下(Moto G4)需要 ?13s 而2018年的低端手机(阿尔卡特 1X)则需要 ~36秒。
今天我们将介绍一些策略,用于在保持良好用户体验的前提下更有效地发送 JavaScript 。

概括

  • 要页面的快速运行,只需加载当前页面所需的 JavaScript 。 优先考虑用户需要的内容,并通过来延迟加载其余部分。 这为您提供了加载和快速可交互的最佳机会。 一般情况下,基于路由堆栈的代码拆分是一个很好的选择。
  • 拥抱性能预算并融入日常开发。 对于移动设备,目标是 。 未压缩的这仍然是 ~0.7MB 的代码。 预算对于成功是至关重要的,然而,他们不能神奇地孤立地修复性能。。没有预算的构建会导致性能倒退和失败。
  • 了解如何 并修剪你的 JavaScript 包。 当你 ,而这个库的大多数代码用于浏览器的 polyfill 或 重复的代码。
  • 每次互动都是新的“Time-to-Interactive”的开始; 在这种情况下考虑优化。传输大小对于低端移动网络至关重要,而设备的CPU 对于 JavaScript 解析时间至关重要。
  • 如果客户端 JavaScript 没有提升用户体验,你需要问问自己是否真的有必要这么做。也许服务器端渲染的 HTML 会更快。考虑只在绝对需要客户端渲染的页面上才客户端框架。如果做得不好,服务器渲染和客户端渲染都会成为一场灾难。

“JavaScript的开销”的视频。

WEB 因用户“体验”而膨胀

当用户访问您的站点时,您可能会发送大量文件,其中许多是脚本。 从Web浏览器的角度来看,这看起来有点像这样:

一堆文件疯狂的扔给你
尽管我喜欢JavaScript,但它始终是您网站中开销最大的部分。我想解释一下这个主要问题。

目前的中间网页传输 。未压缩的情况下,浏览器需要处理的脚本超过1MB。

注意:如果你不确定你的 JavaScript 包是否会延迟用户与你网站的可交互速度?可以通过 。

来自 ,突出显示中间网页传输压缩后的 JavaScript 资源约为 350KB。这些页面最多需要15秒才具备可交互性
使用这么多 JavaScript 需要超过14秒才能加载并在移动设备上进行交互。

其中一个重要因素是在移动网络上下载的代码在移动设备的CPU上处理需要多长时间。

我们来看看移动网络。

全球移动网络状况

在特定指标中表现更好的国家的颜色更深。未包括的国家是灰色的。同样 的是,即使在美国,农村宽带速度也比城市地区慢20%。
显示了4G网络在全球范围内的可靠性以及每个国家/地区的平均连接速度用户体验。我们可以看到,许多国家的连接速度仍然比我们想象的要低。

对于中间网站来说,350 KB的脚本不仅需要一段时间才能下载,现实情况是,如果我们查看热门网站,它们实际上会发送比这更多的脚本:

未压缩的JS包大小数字来自“”。像Google表格这样的网站会突出显示为传输最多5.8MB的脚本(解压缩时)。
我们在桌面和移动网络上都达到了这个上限,在这些网站上,网站有时会发送价值数兆字节的代码,然后浏览器需要处理这些代码。 要问的问题是,

JavaScript 的成本所在

“拥有这么多脚本的网站对全世界广大用户来说都是无法访问的;在统计中,用户不会等待他们加载完成“ – Alex Russell
注意:如果您发送的脚本太多,请考虑使用 来分解包或 。

今天的网站通常会在他们的JS包中发送以下内容:

  • 客户端的框架或者 UI 库;
  • 状态管理解决方案(例如 Redux);
  • Polyfills(通常被用于不需要它们的现代浏览器);
  • 完整的库 VS. 仅需要的内容(例如,所有lodash,Moment +语言环境)
  • 一套 UI 组件(按钮,标题,侧边栏等)

这些代码加起来越多,页面加载所需的时间就越长。

加载网页主要取决于三个因素。

分别是:加载是否被触发?加载的内容是否是有用?以及加载的内容是否可用?

加载需要一个过程。 我们正在转向关注以用户为中心的幸福指数。我们现在会问“用户何时可以*使用*页面?”而不仅仅是查看onload或domContentLoaded。 如果他们点击一个用户界面,它会立即响应吗?
加载是否被触发? 是你能够将一些内容传输到屏幕的那一刻。 (页面是否开始跳转?服务端是否开始响应?)

加载的内容是否是有用? 是您绘制文本或内容的时刻,允许用户从中获取有价值的信息并与之交互。

然后,加载的内容是否可用? 是当用户可以开始与网页进行有意义地交互并发生某些事情。

我之前提到这个术语“交互”,意味着什么呢?

通过可视化的交互时间的方式来突出显示一个加载不佳的体验是如何使用户认为他们可以完成一个目标,而实际上,页面还没有完成加载实现这个目标所有必需的代码。感谢Kevin Schaaf的交互动画
要使页面成为可交互的页面,它必须能够快速响应用户输入。一个小的 JavaScript 负载可以确保快速响应用户交互。

无论用户点击链接还是滚动页面,他们都需要看到为了响应他们的行为而实际发生的事情。无法实现这一目标的体验会让您的用户感到沮丧。

Lighthouse在实验室环境中测量一系列以用户为中心的性能指标,如“交互时间”。
这种情况经常发生在服务器端端渲的页面,然后随后发送一堆 JavaScript 来“润滑”界面(附加事件处理程序和额外行为).

当浏览器运行您可能需要的许多事件时,它可能会在处理用户输入的同一线程上执行此操作。该线程称为主线程。

将过多的JavaScript加载到主线程(通过 <script> 等)是个问题。将JS拉入 或通过 进行缓存不会产生相同的负面等待交互(Time-to-Interactive)影响。

这是一个用户可以点击某些UI的示例。 通常,他们可能会选中一个复选框或点击一个链接,一切都会正常工作。 但是如果我们模拟阻塞主线程,那么任何事情都无法发生。 他们无法检查该复选框或单击链接,因为主线程被阻止。
避免尽可能地阻塞主线程。有关更多信息,请参阅“”

我们看到与我们合作的团队在许多类型的网站上遭受 JavaScript 影响交互性的情况。

JavaScript可以延迟可见元素的交互性。图例是 Google搜索中的一些UI元素
太多(主线程)JavaScript可以延迟可见元素的交互性。 这对许多公司来说都是一个挑战。

以上是Google搜索中的一些示例,您可以从一开始使就使用这些UI,但如果某个网站运行过多的JavaScript,则可能会在实际发生某些事情之前出现延迟。 这会让用户感到有点沮丧。 理想情况下,我们希望所有交互尽快响应。

通过WebPageTest和Lighthouse 衡量news.google.com的互动时间()
通过衡量Google新闻在移动设备上的交互时间,我们观察到高端设备大约7秒内实现交互,而低端设备需要55秒,差异巨大。那么,什么是交互性的良好目标呢?

谈到 Time to Interactive,我们认为您的基准应该是在速度比较慢的3G连接的中端移动设备上,以五秒钟的速度可进行交互。 “但是,我的用户都在使用快速网络和高端手机!”……是吗? 你可能会使用“快速”的咖啡店WiFi,但实际上只能获得2G或3G的速度。 变化很大。

谁减少了 JavaScript 并减少了他们的可交互时间?

  • . 收入增长44%,注册增长753%,。

让我们设计一个更具弹性的移动网络,不依赖于大型JavaScript负载。

交互性受到很多事情的影响。比如用户通过咖啡店WiFi或旅途中的间歇性网络连接来加载网页。

当发生这种情况时,您需要处理大量JavaScript,这个时候用户需要等待页面呈现内容。 或者,如果某些东西已经呈现,但他们仍然需要等待很长时间才能与这些元素进行交互。 理想情况下,减少传输JavaScript可以缓解这些问题。

为什么JavaScript 开销如此高昂?

为了解释 JavaScript 为何有如此大的开销,我想向您介绍将内容发送到浏览器时发生的事情。 用户在浏览器的地址栏中键入URL:

请求被发送到服务器,然后服务器返回一些标记。然后,浏览器会解析这些标记并发现必要的CSS,JavaScript和图像。然后,浏览器必须获取并处理所有这些资源。

上面的场景准确描述了Chrome在处理您发送的所有内容时所发生的情况(是的,它是一个巨大的表情符号工厂)。

这里面临的挑战之一是 JavaScript 最终成为瓶颈。理想情况下,我们希望能够快速绘制像素,然后让页面可交互。但如果 JavaScript 是一个瓶颈,你最终只能看到一些你无法与之交互的东西。

我们希望防止 JavaScript 成为现代体验的瓶颈。

作为一名开发者,要记住的一件事:如果我们想让 JavaScript “变快”,我们必须让下载、解析、编译和执行 JavaScript 的整个过程都变快。

这意味着我们不仅要保证快速的网络传输,还要保证快速的脚本处理能力。

如果您花费很长时间在JavaScript引擎中解析和编译脚本上,那么就会延迟用户与您网页交互的时间。

为了提供一些关于此的数据,这里是(Chrome 的 JavaScript 引擎)在处理包含脚本的页面时花费时间的细分统计图如下:

JavaScript解析/编译=在页面加载期间在V8(Chrome的JS引擎)中花费的时间的10-30%
橙色表示解析 JavaScript 所花费的所有时间。 黄色,是编译的时间。两者加起来,需要花费高达30%的时间来处理页面的JavaScript – 这些开销是真实存在的。

从Chrome 66开始,V8,将编译时间缩短了20%。 但是解析和编译仍然非常昂贵,并且很少看到大型脚本能在50ms内执行完成,即使是在线程外编译也是如此。

对于 JavaScript, 要记住的另一件事是所有字节并不是相等的。 200 KB的脚本和200 KB的图像具有不同的开销。

并非所有字节都相同。 对于 200KB的脚本与200KB JPG 两组字节,除了原始网络传输时间之外,其他开销并不相同。
它们可能需要相同的时间来下载,但是在处理时开销并不相同。

需要在屏幕上对JPEG图像进行解码,栅格化和绘制。 需要下载 JavaScript 包然后进行解析,编译和执行 – 并且引擎需要完成许多。 请注意,这些成本并不完全相同。

他们开始重视 JavaScript 开销问题的一个重要的原因是移动端。

移动设备频谱

廉价/低端、中端和高端设备组成了移动设备频谱。
如果我们足够幸运,可能会拥有一部高端或中端手机。 现实情况是并非所有用户都拥有这些设备。

他们可能使用低端或中端的手机,这些设备之间的差异也可能非常明显;散热、高速缓存大小、CPU、GPU – 根据您使用的设备,您最终可能会遇到JavaScript等资源的完全不同的处理时间。 。

对“ 23 亿 Android智能手机的分析”。 Android在全球市场占有75.9%的份额,预计2018年将有3亿部智能手机加入市场。其中许多将是预算Android设备。
以下是分析2018年可用硬件解析JavaScript所需时间的细分:

在真实设备上手动分析1MB未压缩JavaScript(< 200KB缩小和gzip)的处理(解析/编译)时间。( 这些设备通常 CPU 较差,使用更小的 L2 / L3 高速缓存。如果你希望他们都拥有高端硬件,那么普通用户该怎么办?

让我们通过来自现实网站的脚本来查看这个问题的更实用版本。 这 CNN.com 的JS处理时间:

<

figcaption>通过 WebPageTest 查看 CNN.com 的 JavaScript处理时间()

在iPhone 8(使用A11芯片)上处理CNN的JavaScript比在普通手机上花费少9秒。 这可以让可交互时间快9秒。

既然WebPageTest支持阿尔卡特1X(在美国销售约100美元的手机,在发布时售罄),我们还可以看看在中低端硬件上加载CNN的过程。 通过对比三类机型的 filmstrips 片段,能看出低端机型甚至都不能用简单的慢来形容了。

在中低端硬件(源)上使用3G网络加载重量级网站CNN.com的比较。阿尔卡特1X需要65秒才能完全加载。()
这提示我们,不要再理所当然的认为用户都是使用快速网络和快速设备。

有些用户不会使用快速网络或拥有最新最好的手机,因此我们开始在真实手机和真实网络上进行测试至关重要。 可变性(Variability)是一个真正的问题。

“可变性是杀死用户体验的原因” – Ilya Grigorik。 快速设备实际上有时可能很慢。 快速网络可能很慢,可变性最终会使一切变得缓慢。

当差异可能会破坏用户体验时,使用缓慢的基线进行开发可确保每个人(快速和慢速设置)都能获益。 如果您的团队可以查看他们的分析并准确了解您的用户实际访问您网站的设备,这些将会提示您应该在办公室中使用哪些设备来测试您的网站。

使用真实的手机和网络测试。
在“移动”配置文件下预先配置了许多 Moto G4。 如果您无法购买自己的中端级硬件进行测试,这将非常有用。

这里设置了许多配置文件,您可以使用这些配置文件已预先配置了常用设备。 例如,我们有一些中端移动设备准备测试,如 Moto G4 。

在代表性网络上进行测试也很重要。 虽然我已经谈到了低端手机和中端手机的重要性,但 Brian Holt 提出了这个观点:。

“了解网站的受众群体,然后适当地关注应用程序的性能至关重要” —?Brian Holt ()
并非每个站点都需要在低端手机上的2G网络上表现良好。也就是说,在整个频谱范围内实现高性能并不是一件坏事。

Google Analytics > 受众群体 > 移动设备 > 设备可视化设备和比赛 访问您网站的位置。
您可能在频谱较高端或频谱的不同部分拥有广泛的用户。 请注意您网站后台的数据,以便您可以合理地调用所有这些内容。

如果您希望JavaScript快速,请注意低端网络的下载时间。 您可以进行的改进包括:减少代码,缩小源代码,利用压缩(即 ,,和 )。

利用缓存重复访问。对于CPU速度慢的手机,解析时间至关重要。

如果您是后端或全栈开发人员,您应该知道您可以获得有关CPU,磁盘和网络的开销。

当我们构建的网站越来越依赖JavaScript时,我们有时会以一种我们不太容易看到的方式为我们发送的内容付出代价。

如何发送更少的JavaScript

最直接的方式是我们发送最少的脚本给用户,同时仍然给他们一个有用的网页。 是最有效的选择。

可以在页面、路由或组件的基础上拆分大型的 JavaScript 包文件。如果从一开始,你的工具链就默认设置了“拆分”,那么你将会获得更多的收益。
代码分割就是一种思想,他不是向用户发送一个整个单文件的 JavaScript 包 – 有点像一个大型的披萨 – 如果一次只发送一小个片段会怎样?只要让当前页面的功能可用就可以了。

代码拆分可以在页面级别、路由级别或组件级别完成。很多现代库和框架都通过 (中文)和 Parcel(中文)等打包工具来实现代码拆分。 (中文)、和 都提供了提供了这方面的指南。

// 拆分前
import OtherComponent from './OtherComponent';

const MyComponent = () => (
  <OtherComponent/>
);
// 拆分后
import Loadable from 'react-loadable';

const LoadableOtherComponent = Loadable({
  loader: () => import('./OtherComponent'),
  loading: () => <div>Loading...</div>,
});

const MyComponent = () => (
  <LoadableOtherComponent/>
);
使用 在React应用中添加代码拆分 – 一个高阶的组件,它在React友好的API中包装动态导入,以便在给定组件的应用程序中添加代码拆分。
许多大型团队最近开始着手代码拆分,并且取得了巨大成功。

为了尽可能快地重写他们的移动网络页面,以确保用户能够与他们的网站进行交互, 和 在采用激进的代码拆分,他们的可交互时间( Time to Interactive )提高了50%。。

像 (React), 和 这样的堆栈尝试强制执行良好的默认设置,以便在中端移动硬件上快速加载和获取交互。

许多这些网站所做的另一件事是:将审计分析 JavaScript 作为其工作流程的一部分。

定期审查您的JavaScript包。 像 webpack-bundle-analyzer 这样的工具非常适合分析你构建的JavaScript包,并且 [VS Code 的 import-cost 扩展](https://www.7psus5.com/archives/9507) 非常适合在本地迭代工作流程中查看开销大的依赖项(例如当你 `npm install` 并导入包时)
值得庆幸的是,JavaScript生态系统有许多很棒的工具可以帮助我们分析打包文件。

我们可以使用、 和 等工具来分析JavaScript包,寻找进行代码拆分的可能性。

这些工具可以对 JavaScript 包的内容进行可视化:它们突出显示大型的库、重复的代码和你可能不需要的依赖项。

来自 Benedikt R?tsch 的“”
包文件的审计分析通常会突出显示可重置的依赖项(如 Moment.js 及其语言环境),以便获得更轻的替代方案(例如 )。

如果您使用webpack,您可能会发现我们在 会很有用。

度量、优化、监控和重复

如果您不确定一般的JavaScript性能是否有任何问题,请查看 :

Lighthouse 最近添加了许多新的、您可能不了解的但是又有用的 。
Lighthouse 是内嵌在 Chrome 开发者工具中的一款工具。它也可以作为 使用。它为你提供了深入的性能分析,并给出了一些潜在可以提高性能的建议。

最近 LightHouse 添加了一个功能,即标记出高 “JavaScript boot-up time(JavaScript 启动时间)” 的支持。这个审计分析突出显示了可能需要花费很长时间进行解析/编译的脚本,这会延迟可交互性。您可以并据此拆分和优化你的代码。

您可以做的另一件事是确保您没有将未使用的代码发送给您的用户:

使用 查找未使用的CSS和JS代码。
是DevTools中的一项功能,它允许您在页面中发现未使用的JavaScript(和CSS)。 在DevTools中加载页面,coverage选项卡将显示被执行的代码数量与加载的数量。 您只需提供用户需要的代码即可提高页面性能。

提示:通过覆盖记录,您可以与您的应用进行交互,DevTools将更新您使用的包的数量。

这对于找出可以进行拆分的脚本以及延迟加载非关键脚本来说非常有用。

如果你正在寻找一种为用户提供高效的 JavaScript 分发模式,请查看 。

PRPL是高性能的加载模式。它代表:

  • 推送(P)ush – 为初始网址路由推送关键资源。
  • 渲染(R)ender – 渲染初始路由。
  • 预缓存(P)re-cache – 预缓存剩余路由。
  • 延迟加载(L)azy-load – 延迟加载并按需创建剩余路由。

PRPL(Push、Render、Precache和Lazy-Load)是一种模式,用于对每个路由进行代码拆分,然后利用 预先缓存未来路由需要用到的JavaScript和逻辑,并按需延迟加载。

这意味着当用户导航到应用中的其他视图时,它很可能已经存在于浏览器缓存中,因此他们在启动脚本和获取可交互性方面的成本降低了很多。

如果您关心性能,或者您曾经为您的网站做过性能补丁,那么你就会知道,有时候您可能最终要解决某个问题,但几周后又出现了,发现团队中有人正在开发某个功能,无意中破坏了应用。就像这样:

值得庆幸的是,我们可以尝试解决这个问题,一种方法是制定 。

性能预算是至关重要的,因为它们使每个人保持一致。它们创造了一种共享热情的文化,以不断改善用户体验和团队责任。

预算定义了可衡量的约束,让团队去实现性能目标。因为你不能突破预算的限制,所以每走一步都要考虑好性能,而不是事后再来解决。

根据 Tim Kadlec 的经验, 可包括:

  • 里程碑时间 – 基于加载页面的用户体验的时间(例如,可交互时间( Time to Interactive ))。 您常常希望对几个里程碑时间进行配对,以便在页面加载期间准确地表示完整的内容。
  • 基于质量的指标 – 基于原始值(例如JavaScript的权重,HTTP请求的数量)。 这些都专注于浏览器体验。
  • 基于规则的指标 – 由 Lighthouse 或 WebPageTest 等工具生成的分数。通常,一个数字或系列数字来对你的网站进行评分。

Alex Russell 发布了关于性能预算的,其中有几点值得注意:

  • “领导阶层的支持很重要。为了保持良好的整体用户体验,而暂停搁置功能性开发工作,通常这是对技术产品经过深思熟虑后的意愿。“
  • “性能是由工具支持的文化。浏览器会自动尽可能优化HTML+CSS。将更多的工作转移到会给团队和工具带来负担的JS中。“
  • “性能预算不会让你伤心。他们的存在是为了让组织自我纠正。团队需要性能预算来限制决策空间并帮助实现它们。“

每个参与人和其执行力都会关系到网站的用户体验。

使性能成为对话的一部分。
性能指标通常是文化挑战,而不是技术挑战。

建议Tian工程师在计划会议和其他会议中讨论性能。向业务利益相关者询问他们的业绩预期,他们是否了解Tian性能如何影响他们关心的业务指标?询问团队如何计划解决性能瓶颈问题。
虽然这里的答案可能不尽如人意,但至少对话开始了。

“通过展示性能如何影响他们关心的关键指标,使性能与利益相关者的目标相关。如果没有性能文化,那么性能是不可持续的“ –
这是一个性能执行计划:

  • 创建您的性能愿景。 这是一份关于业务利益相关者和开发人员认为“良好表现”的协议
  • 设定性能预算。 从愿景中提取关键绩效指标(KPI),并从中设定切合实际的可衡量目标。 例如 “在5s内加载并可进行交互”。 规模预算可能会失败。 例如“JS压缩后保持 < 170KB”
  • 创建关于KPI的定期报告。 这可以是发送给业务的定期报告,突出显示进度和成功部分。

Andy Still的 都是优秀的书籍,讨论如何考虑如何实现性能文化。

那么性能预算的工具有哪些呢? 您可以设置 Lighthouse 评分预算与 项目持续集成:

如果您的性能分数低于 的某个值,则防止 pull
请求被合并。是另一种基于配置的方法来设置预算。
许多性能监控服务支持设置性能预算和预算警报,包括 , , 和 :

我的网站 teejungle.net 的 JavaScript 性能预算使用 SpeedCurve ,它支持一系列 。
拥抱性能预算可以鼓励团队认真思考他们从设计阶段早期到里程碑结束所做出的任何决策将产生怎样的后果。

寻找进一步的参考? U.S Digital Service 通过设定时间到交互等指标的目标和预算,记录他们 。

接下来……

每个站点都应该可以访问 。

要跟踪 JavaScript 可能对 RUM(真实用户监控)设置中的用户体验产生的影响,网络上有两件事情,我建议大家去看看。

现场数据(或RUM – 真实用户监控)是从用户在自己真实环境中经历的实际页面加载中收集的性能数据。 拥有大量JavaScript有效负载的站点将受益于通过 长时间任务 和 首次输入延迟 来度量这项工作的主线。
第一个是 —— 一组API,帮助你收集真实世界中持续时间超过50毫秒并可能会阻塞主线程的任务。您可以记录这些任务并将它们记录到您的分析中。

第二个是 ,是用于度量从用户首次向网站发起交互(如当他们点击按钮时)到浏览器能够响应该交互的时间。FID是一个早期指标,不过现在已经有一个可用的 ,你可以尝试下。

在这两者之间,您应该能够从真实用户那里获得足够的遥测数据,以查看他们遇到的JavaScript性能问题。

Marcel Freinbichler 发布了一则关于 USA Today 向欧盟用户提供了一个精简版网站 的 [推文](https://twitter.com/fr3ino/status/1000166112615714816) ,它比正常页面加载快42秒。
众所周知,第三方 JavaScript 可能会对页面加载性能产生严重影响。重要的是要认识到自己写 JavaScript 对性能的影响。如果我们要加快加载速度,需要同时消除双方对用户体验产生的影响。

我们看到了几个常见的漏洞,包括在文档头部使用JavaScript来决定向用户显示那个版本的A/B测试。或者将A/B测试所有的JS都发送给用户,但实际上只用了其中一个 。

如果这是你目前遇到的主要瓶颈,我们还提供了一个有关。

总结

性能优化是一段长途旅行。许多小的变化可以带来巨大的收益。

使用户能够以最少的阻力与您的站点进行交互。 运行最少量的JavaScript以提供真正的价值。 这可能意味着你需要采取渐进的步骤来实现目标。

最后,您的用户会感谢您。

参考

原文链接:

赞(0) 打赏
未经允许不得转载:WEBTian开发 » Tian性能优化:2018年JavaScript开销及优化工具和方法

评论 1

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
  1. #-49

    如果能把页面美化一下,估计会比掘金的访问量差不多

    刘裕强4个月前 (08-29)回复

Tian开发相关广告投放 更专业 更精准

联系我们

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏