启动性能瓶颈分析与解决方案,网页性能提升指南

Web 的现状:网页性能提升指南

2017/09/21 · 基础技术 ·
性能

原文出处: Karolina
Szczur   译文出处:碧青_Kwok   

互联网发展非常迅速,所以我们创造了Web平台。通常我们会忽视连通性等问题,但用户们却不会视而不见。一瞥万维网的现状,可以发现我们并没有用同情心、变通意识去构建它,更不要说性能了。

所以,今天的Web是什么状态呢?

在这个星球上的74亿人中,只有46%可以上网。平均网络速度上限为7Mb/s。更重要的是,有93%的互联网用户正在通过移动设备进行访问——若不适配移动设备将引起用户反感。通常情况下,数据比我们假设的更昂贵——可能需要1到13小时才能购买500MB的数据包(德国
vs. 巴西;更有趣的统计数据参见 Ben
Schwarz 的 Beyond the Bubble: The Real
World
Performance)。

我们的网站也不是完美的——平均网站是原始Doom游戏的大小(约3
MB)(请注意,为了统计准确,应使用中位数,阅读 Ilya
Grigorik
的优秀“平均页面”是一个神话,中档网站大小目前为1.4MB)。图像可以轻松占用1.7
MB的带宽,而JavaScript平均值也有400KB的体积。这不仅是Web平台的问题,原生应用程序可能更糟,还记得为了获取错误修复版本,而下载200MB安装包的情景吗?

技术人员经常会发现自己处于特权状态。随着最新的高端笔记本电脑、手机和快速有线互联网连接,很容易让我们忘记,这些并不是每个人都有的条件(实际上,真的很少)。

如果我们从特权和缺乏同情的角度来构建网络平台,那么将导致排他性的糟糕体验。

考虑到设计和开发的性能,我们怎样才能做得更好?


10 个打造 React.js App 的最佳 UI 框架

2017/05/26 · 基础技术 ·
React,
UI

原文出处: Vladimir
Metnew   译文出处:IT程序狮   

图片 1

10 个打造 React.js App 的最佳 UI 框架

在本文中,我们将分享一些助你打造 React.js App 最佳的 UI
框架。它们具备你所需要的基本 React 组件,以及易用的
API,同时,在外观和体验上也非常棒。Have Fun !


JavaScript 启动性能瓶颈分析与解决方案

2017/02/17 · JavaScript
· 性能

原文出处: Addy
Osmani   译文出处:王下邀月熊_Chevalier   

图片 2

在 Web 开发中,随着需求的增加与代码库的扩张,我们最终发布的 Web
页面也逐渐膨胀。不过这种膨胀远不止意味着占据更多的传输带宽,其还意味着用户浏览网页时可能更差劲的性能体验。浏览器在下载完某个页面依赖的脚本之后,其还需要经过语法分析、解释与运行这些步骤。而本文则会深入分析浏览器对于
JavaScript
的这些处理流程,挖掘出那些影响你应用启动时间的罪魁祸首,并且根据我个人的经验提出相对应的解决方案。回顾过去,我们还没有专门地考虑过如何去优化
JavaScript
解析/编译这些步骤;我们预想中的是解析器在发现<script>标签后会瞬时完成解析操作,不过这很明显是痴人说梦。下图是对于
V8 引擎工作原理的概述:
图片 3下面我们深入其中的关键步骤进行分析。

优化所有资源

理解浏览器如何分析和处理资源,是显著提高性能的最强大但未充分利用的方式之一。事实证明,浏览器在嗅探资源方面非常出色,同时解析并确定其优先级。这里是关键请求的来源。

如果请求中包含用户视口中呈现内容所必需的资源,则该请求至关重要。

对于大多数网站,它将是HTML、必要的CSS、logo、网络字体,也可能是图片。在许多情况下,几十个其他不相关的资源(JavaScript、跟踪代码、广告等)影响了关键请求。幸运的是,我们能够通过仔细挑选重要资源并调整优先级来控制这种行为。

通过“我们可以手动强制调高资源的优先级,确保所需的内容按时呈现。这种技术可以显著改善“交互时间”指标,从而使最佳的用户体验成为可能。

图片 4

关键请求对许多人来说,似乎仍然是一个黑匣子,可共享资料的缺乏并不能改变现状。幸运的是,Ben
Schwarz
发表了关于这个问题的非常全面并平易近人的文章——关键请求。另外,请参阅Addy的文章,在Chrome中的预加载、预取和优先级(Preload,
Prefetch and Priorities in
Chrome)。

图片 5

[在Chrome开发人员工具中启用优先级]

要跟踪在请求优先级处理方面的情况,请使用Lighthouse性能工具和关键请求链审核工具,或查看Chrome开发人员工具中“网络”选项卡下的请求优先级。

1. Material-UI

图片 6

基于谷歌 Material Design 设计规范的 React 组件

此外,它还是 React 的第一个 UI
套件。Material-UI具备你所需要的所有组件(甚至更多),以及可配置性极高的预定义调色板和“,帮助你为应用程序定制相应的颜色主题。

由于 Material-UI
过去的版本中存在一些性能问题,就我个人而言,不是很满意。但自3.0
版本发布后的反馈来看,它在性能方面已有所改善。

项目地址:【传送门】

到底是什么拖慢了我们应用的启动时间?

在启动阶段,语法分析,编译与脚本执行占据了 JavaScript
引擎运行的绝大部分时间。换言之,这些过程造成的延迟会真实地反应到用户可交互时延上;譬如用户已经看到了某个按钮,但是要好几秒之后才能真正地去点击操作,这一点会大大影响用户体验。
图片 7上图是我们使用
Chrome Canary 内置的 V8 RunTime Call Stats
对于某个网站的分析结果;需要注意的是桌面浏览器中语法解析与编译占用的时间还是蛮长的,而在移动端中占用的时间则更长。实际上,对于
Facebook, Wikipedia, Reddit
这些大型网站中语法解析与编译所占的时间也不容忽视:
图片 8上图中的粉色区域表示花费在
V8 与 Blink’s C++
中的时间,而橙色和黄色分别表示语法解析与编译的时间占比。Facebook 的
Sebastian Markbage 与 Google 的 Rob Wormald 也都在 Twitter 发文表示过
JavaScript 的语法解析时间过长已经成为了不可忽视的问题,后者还表示这也是
Angular 启动时主要的消耗之一。
图片 9

随着移动端浪潮的涌来,我们不得不面对一个残酷的事实:移动端对于相同包体的解析与编译过程要花费相当于桌面浏览器2~5倍的时间。当然,对于高配的
iPhone 或者 Pixel 这样的手机相较于 Moto G4
这样的中配手机表现会好很多;这一点提醒我们在测试的时候不能仅用身边那些高配的手机,而应该中高低配兼顾:
图片 10

上图是部分桌面浏览器与移动端浏览器对于 1MB 的 JavaScript
包体进行解析的时间对比,显而易见的可以发现不同配置的移动端手机之间的巨大差异。当我们应用包体已经非常巨大的时候,使用一些现代的打包技巧,譬如代码分割,TreeShaking,Service
Workder
缓存等等会对启动时间有很大的影响。另一个角度来看,即使是小模块,你代码写的很糟或者使用了很糟的依赖库都会导致你的主线程花费大量的时间在编译或者冗余的函数调用中。我们必须要清醒地认识到全面评测以挖掘出真正性能瓶颈的重要性。

通用性能清单

  1. 积极地缓存
  2. 启用压缩
  3. 优化关键资源的优先级
  4. 使用CDN(Content Delivery Networks)

2. React Desktop

图片 11

专为 MacOS Sierra 和 Windows 10 提供的 React UI 组件

关于Electron
框架,我相信你已经有所了解。如果你对跨平台桌面应用程序
UI
组件也感兴趣的话,那么React-Desktop绝对是你的“菜”。你可以使用它轻松获取用于
Mac OS 和 Windows 10 系统上相应的 UI 组件。

项目地址:【传送门】

JavaScript 语法解析与编译是否成为了大部分网站的瓶颈?

我曾不止一次听到有人说,我又不是 Facebook,你说的 JavaScript
语法解析与编译到
底会对其他网站造成什么样的影响呢?对于这个问题我也很好奇,于是我花费了两个月的时间对于超过
6000 个网站进行分析;这些网站囊括了 React,Angular,Ember,Vue
这些流行的框架或者库。大部分的测试是基于 WebPageTest
进行的,因此你可以很方便地重现这些测试结果。光纤接入的桌面浏览器大概需要
8 秒的时间才能允许用户交互,而 3G 环境下的 Moto G4 大概需要 16 秒
才能允许用户交互。

图片 12大部分应用在桌面浏览器中会耗费约
4 秒的时间进行 JavaScript 启动阶段(语法解析、编译、执行)

图片 13

而在移动端浏览器中,大概要花费额外 36% 的时间来进行语法解析:
图片 14

另外,统计显示并不是所有的网站都甩给用户一个庞大的 JS
包体,用户下载的经过 Gzip 压缩的平均包体大小是 410KB,这一点与
HTTPArchive 之前发布的 420KB
的数据基本一致。不过最差劲的网站则是直接甩了 10MB
的脚本给用户,简直可怕。

图片 15

通过上面的统计我们可以发现,包体体积固然重要,但是其并非唯一因素,语法解析与编译的耗时也不一定随着包体体积的增长而线性增长。总体而言小的
JavaScript
包体是会加载地更快(忽略浏览器、设备与网络连接的差异),但是同样 200KB
的大小,不同开发者的包体在语法解析、编译上的时间却是天差地别,不可同日而语。

图片优化

图片通常占网页传输的大部分有效载荷,因此图片优化可以带来最大的性能提升。有许多现有的策略和工具可以帮助我们删除额外的字节,但是首先应考虑的问题是:“图片对于我想传达的信息和效果至关重要吗?”。如果可以消除它,不仅可以节省带宽,而且还节省了请求。

在某些情况下,可以通过不同的技术实现类似的结果。比如CSS就具有艺术方向的一系列属性,例如阴影、渐变、动画及形状,允许我们构造适当风格的DOM元素。

3. Semantic-UI-React

图片 16

由 Semantic-UI 官方出品的 React UI 组件

就个人而言,我认为它是最好用的 React UI
框架。它是由官方基于Semantic-UI打造的
React 组件,它几乎涵盖了 Semantic-UI 上的所有组件,而且它还有一个易用的
Declarative API,以及用于 React 组件的 shorthand props,同时它能够做到
jQuery-free。

另外,我做了一个使用 React-Semantic-UI,Webpack
构建项目的新手示例,你也可以来看看。

项目地址:【传送门】

现代 JavaScript 语法解析 & 编译性能评测

选择正确的格式

如果不能舍弃图片,确定哪种格式更合适就很重要了。首先要在矢量和光栅图形之间做出选择:

  • 矢量图形:分辨率独立,通常体积更小。非常适合logo、icon和简单的图形,包括基本形状(线,多边形,圆和点)。
  • 光栅图形:呈现更详细的信息,比较适合相片。

做出首个决定后,可以选择以下几种格式:JPEG、GIF、PNG–8、PNG–24,或最新的
WEBP 与 JPEG-XR
格式。有了这么多的选项,如何确保我们做出正确的选择?以下是找出最佳格式的基本方法:

  • JPEG:颜色非常丰富的图片(例如照片)
  • PNG–8:色彩相对单一的图片
  • PNG–24:局部透明的图片
  • GIF:动图

Photoshop可以通过各种设置,例如降低质量、降低噪音或色彩数量来优化以上每一种格式。确保设计师了解上述性能实践,并能够使用正确的方式优化相应格式的图片。如果您想了解更多如何处理图片,请阅读
Lara Hogan 的好文 Designing for
Performance。

4. Ant-design

图片 17

一套企业级 UI 设计语言和基于 React 实现的 Web 组件库的体验解决方案

引用官方文档介绍:

  • 用于 Web 应用程序的企业级 UI 设计语言。
  • 一套开箱即用的高品质 React 组件。
  • 由 TypeScript 构建,并具备完整定义类型。
  • 基于 npm + webpack + dva 前端开发工作流。

它支持浏览器、服务器端渲染和 Electron
环境,并具备丰富的组件,你还可以通过Create-react-app
来学习。来看看Ant-design
demo吧!

项目地址:【传送门】

Chrome DevTools

打开 Timeline( Performance panel ) > Bottom-Up/Call Tree/Event Log
就会显示出当前网站在语法解析/编译上的时间占比。如果你希望得到更完整的信息,那么可以打开
V8 的 Runtime Call Stats。在 Canary 中,其位于 Timeline 的 Experims >
V8 Runtime Call Stats 下。
图片 18

试用新格式

图像格式有几个较新的玩家,即WebP、JPEG 2000 和
JPEG-XR。它们都是由浏览器厂商开发的:Google 的 WebP,Apple 的 JPEG 2000
和 Microsoft 的 JPEG-XR。

WebP
是最受欢迎的竞争者,支持无损和有损压缩,这使得它非常灵活。无损的 WebP
比 PNG 小26%,比 JPG 小25-34%
。WebP
有着74%的浏览器支持,它可以安全地进行降级,最多可节省1/3的传输字节。JPG
和 PNG 可以在 Photoshop
和其他图像处理应用程序以及命令行界面(brew install webp)中转换为WebP。

如果你想探索其他格式之间的视觉差异,推荐 Github 上这个很赞的
Demo。

5. Blueprint

图片 19

引用自官方文档:

“它将为拥有复杂、数据密集的 Web
界面的桌面应用程序进行全面优化。如果你注重移动端的交互体验,并且正寻找移动优先的
UI 套件的话,它可能不适合你。”

Blueprint 是由 TypeScript
构建,并具备良好的使用文档。它包含了丰富(30+)的 React
基础组件,从按钮到表单控件、工具提示均有涉及。此外,它的每个组件都包含了
CSS 样式。并且,你还可以使用 Sass 和 Less 变量、优雅的调色板和两种尺寸的
300+ UI 图标等工具,来打造一款专属于你的组件和应用程序。

项目地址:【传送门】

Chrome Tracing

打开 about:tracing 页面,Chrome
提供的底层的追踪工具允许我们使用disabled-by-default-v8.runtime_stats来深度了解
V8 的时间消耗情况。V8
也提供了详细的指南来介绍如何使用这个功能。
图片 20

用工具和算法进行优化

即使使用了高效的图像格式,也不应跳过后处理优化。这一步很重要。

如果您选择了尺寸相对较小的
SVG,它们也是可以再次压缩的。SVGO
是一个命令行工具,可以通过剥离不必要的元数据来快速优化
SVG。另外,如果您喜欢Web界面或受操作系统的限制,请使用 Jake
Archibald 的
SVGOMG。因为 SVG 是基于 XML
的格式,它也可以在服务器端进行 GZIP 压缩。

ImageOptim
是大多其他图像类型的最好选择。包括 pngcrush、pngquant、MozJPEG、Google
Zopfli等,它在一个全面的开源包中捆绑了一大堆优秀的工具。ImageOptim
可以以 Mac OS 应用程序、命令行界面和 Sketch
插件形式,轻松地实现到现有的工作流程中。对于那些在 Linux 或 Windows
上的场景,大多数 ImageOptim 的 CLI 都可以在您的平台上使用。

如果您倾向于尝试新兴的编码器,Google 今年早些时候发布了
Guetzli——源自
WebP 和 Zopfli 的开源算法。Guetzli
可以比任何其他可用的压缩方法生成35%更小体积的
JPEG
。唯一的缺点是:处理时间慢(CPU 每处理百万像素需要1分钟)。

选择工具时,请确保它们生成所需的结果并适应团队的工作流程。理想情况是,将优化过程自动化,这样就不会产生漏掉的情况。

6. React-Bootstrap

图片 21

用 React 构建的 Bootstrap 3 组件

引用自官方文档:

React-Bootstrap是一个可重用的前端组件库。通过使用
Facebook 的 React.js 框架来获得 Twitter Bootstrap
的外观与体验,以及更清晰的代码。

简而言之,它是知名的 Bootstrap 组件的 React 实现。

项目地址:【传送门】

WebPageTest

图片 22WebPageTest
中 Processing Breakdown 页面在我们启用 Chrome > Capture Dev Tools
Timeline 时会自动记录 V8 编译、EvaluateScript 以及 FunctionCall
的时间。我们同样可以通过指明disabled-by-default-v8.runtime_stats的方式来启用
Runtime Call Stats。
图片 23

更多使用说明参考我的gist点击预览。

响应式图片

十年前,我们使用一种分辨率,就可以为所有人服务,但时代变化太快,现今的响应式
Web
已非往日可比。这也是为什么我们必须要特别留心,去精心优化视觉资源,确保它们适应各种视口设备。幸运的是,感谢
Responsive Images
社区小组,我们可以完美使用 picture
元素和 srcset 属性(二者都有85%+支持率)。

7. React-Toolbox

图片 24

一套基于谷歌 Material Design 规范和 CSS 模块的 React 组件

你听说过CSS Modules吗?
React-Toolbox便依赖于它。React-Toolbox
是一个具有 30+
开箱即用组件的高度可定制框架。从此,你可以不必使用类似Purify-CSS这样的工具,仅通过所需的
CSS 便可以进行项目的开发。

项目地址:【传送门】

User Timing

我们还可以使用 Nolan Lawson 推荐的User Timing
API来评估语法解析的时间。不过这种方式可能会受
V8 预解析过程的影响,我们可以借鉴 Nolan 在 optimize-js
评测中的方式,在脚本的尾部添加随机字符串来解决这个问题。我基于 Google
Analytics 使用相似的方式来评估真实用户与设备访问网站时候的解析时间:
图片 25

srcset 属性

srcset在分辨率切换方案中效果最佳——即当我们需要根据用户的屏幕密度和大小显示图像时。基于srcsetsize属性中的一组预定义规则,浏览器将选择最佳图片,相应地提供给视口。这项技术可以带来很大的带宽和请求节省,特别是对于移动用户。
图片 26
[srcset 使用示例]

8. Grommet

图片 27

用于企业应用的先进的 UX 框架

Grommet 不仅仅是 UX
框架,它还提供了从理论到应用程序开发所需的所有指导、组件以及设计资源。例如,它提供了
React 编写的丰富的 UX 组件、自带的 grommet-cli
、入门学习指南、预设模版、优秀的使用文档等资源。

项目地址:【传送门】

DeviceTiming

Etsy 的 DeviceTiming
工具能够模拟某些受限环境来评估页面的语法解析与执行时间。其将本地脚本包裹在了某个仪表工具代码内从而使我们的页面能够模拟从不同的设备中访问。可以阅读
Daniel Espeset 的Benchmarking JS Parsing and Execution on Mobile
Devices
一文来了解更详细的使用方式。
图片 28

picture 元素

picture元素和media属性旨在使艺术设计变得容易。通过为不同情形提供不同图片(通过媒体查询进行测试),无论什么分辨率,我们都能始终将图像中最重要的元素保持在焦点。
图片 29
[picture 元素使用示例]

请务必阅读 Jason Grigsby 的 Responsive
Images
101指南,以便对这两种方法进行彻底的阐述。

9. Fabric

图片 30

用于为 Office 和 Office 365 构建用户体验的 React 组件

在过去的几年里,微软公司支持并创建了许多开源项目,例如 Angular
2、TypeScript、VS Code(基于
Electron)以及Fabric。

Fabric是利用 TypeScript 编写的官方
Office
库,它具有“入门”指南、博客、官方调色板和字体以及项目所需的所有组件。

项目地址:【传送门】

我们可以做些什么以降低 JavaScript 的解析时间?

  • 减少 JavaScript
    包体体积。我们在上文中也提及,更小的包体往往意味着更少的解析工作量,也就能降低浏览器在解析与编译阶段的时间消耗。
  • 使用代码分割工具来按需传递代码与懒加载剩余模块。这可能是最佳的方式了,类似于PRPL这样的模式鼓励基于路由的分组,目前被
    Flipkart, Housing.com 与 Twitter 广泛使用。
  • Script streaming: 过去 V8 鼓励开发者使用async/defer来基于script
    streaming实现
    10-20% 的性能提升。这个技术会允许 HTML
    解析器将相应的脚本加载任务分配给专门的 script streaming
    线程,从而避免阻塞文档解析。V8
    推荐尽早加载较大的模块,毕竟我们只有一个 streamer 线程。
  • 评估我们依赖的解析消耗。我们应该尽可能地选择具有相同功能但是加载地更快的依赖,譬如使用
    Preact 或者 Inferno 来代替 React,二者相较于 React
    体积更小具有更少的语法解析与编译时间。Paul Lewis
    在最近的一篇文章中也讨论了框架启动的代价,与
    Sebastian Markbage
    的说法不谋而合:最好地评测某个框架启动消耗的方式就是先渲染一个界面,然后删除,最后进行重新渲染。第一次渲染的过程会包含了分析与编译,通过对比就能发现该框架的启动消耗。

如果你的 JavaScript 框架支持
AOT(ahead-of-time)编译模式,那么能够有效地减少解析与编译的时间。Angular
应用就受益于这种模式:
图片 31

发表评论

电子邮件地址不会被公开。 必填项已用*标注