编者按:HTML5应用被视为让本地软件云端化的利器,HTML5游戏也被视为一片新的蓝海,然而,HTML5远逊于原生的性能让众多开发者望而却步。本次InfoQ中文站便就此问题采访了英特尔(中国)开源技术中心负责crosswalk runtime和H5优化、硬件加速的两位工程师。
余枝强:我是英特尔中国开源技术中心的软件技术经理余枝强,主要负责HTML5引擎 -Crosswalk在安卓平台的开发, 以及一些新兴Web技术的研发
顾扬:我是英特尔中国开源技术中心web研发经理顾扬,负责web图形相关功能(CSS, Canvas2D和WebGL等)的实现和优化
余枝强:其实现在轻度、中度游戏/应用如果能够通过一些全栈式的优化(包括应用层,软件库,Web引擎层),某些场景下可能还需要一些Hybrid实现, 这样,HTML5应用接近或达到类似原生应用的性能应该问题不大。但重度、计算量大的应用(比如复杂的3D游戏,包括物理引擎等)目前确实还是有不少差距的。
我这里可以分享几个例子,它们都是一开始性能有较大的差距,但通过相应的优化性能达到了质的提升。
其中一个例子是和腾讯Alloy团队合作的,针对HTML5图像处理库的优化。原先这个图像处理库在移动端性能不理想,比如说对一副图像实现一个木雕效果需要十几秒甚至几十秒的时间(其中涉及到较为复杂的计算),后来我们在应用里引入并行 (WebCL, 它可以利用CPU 以及GPU中的多核的能力),通过对图像处理库相应的部分用WebCL重新实现,另外在Crosswalk引擎里加入WebCL的支持以及相应优化,最后这个图像处理时间在安卓平台上从几十秒降低到2秒以内。
另外一个例子是和触控科技合作了, 针对一个游戏-“进击的小怪物”的 HTML5版本做优化,其中涉及到比较酷炫的消除/爆炸效果,而这些效果在最新的Chrome里跑只有十几的fps 。通过引入Crosswalk 的游戏模式,把上层相对耗时的API通过原生的实现再桥接到HTML5引擎中,使得酷炫效果的性能比Chrome好5倍左右。
另外最近我们在调研一种典型的用户场景:大规模的图片的加载和滑动的性能问题, 以及和原生应用的性能区别。经过初步的调研,我们发现性能的差距有几个方面的原因:没有做更好的缓存,没有利用系统服务,不必要的事件处理,不必要数据转换,以及大量的数据缺少高效的数据传输机制,这中间有很多开销,会影响到用户体验。我们打算做一个参考实现来解决这种类型应用的性能问题。
总结来说, HTML5的性能问题,可能是多重原因组成,比如应用本身设计不合理,加了不必要的事件,没有用更好的缓存等等,另一方面引擎也可能有问题,比如数据传递,比如没有利用上更好的硬件特性。再加上Javascript语言的动态性,相对不容易写出优化的代码。这些问题,如果能够有全局的角度出发做相应优化,性能会有机会提升非常明显。另外对应用开发者来说,尽量用一些成熟的框架,最好也要对对底层引擎有一定的了解从而避开javacript 里的坑。成熟的框架相对来说已做了一些Javascript层面的优化,再通过引擎本身针对应用的场景做相应优化,同时让Web引擎更好的利用到底层的硬件能力,这些层面做好了,就容易有好的体验。
顾扬:从我的理解来说,native应用直接跟硬件打交道,web应用则是通过web引擎跟硬件打交道,多了web引擎这个中间层。正因为这个中间层,带来了一些性能差异:
1, web引擎相对native发展来说还很年轻,对CPU,GPU这样的计算资源还不能充分应用。
2,web引擎是一种通用平台,日益增强的能力也带来了日益复杂的架构和更多的overhead。当然除却web引擎带来的性能损失,JS语言本身也有一些局限性,比如数据类型不明确,不支持多进程等。我们的优化主要针对web引擎的上述两个短板:
1, 充分发挥硬件,主要是CPU和GPU的能力。比如充分利用Intel CPU的特殊指令集,GPU的特殊extension。
2, 因为我们熟悉web引擎的各个阶段,通过对典型应用场景的性能评估,了解瓶颈所在,从而优化引擎逻辑。
顾扬:目前的很多web引擎都是基于Chromium项目。我们的优化工作基本都是直接提交到Chromium,而且跟图形相关。具体涉及的软件仓库,主要是Skia和Chromium(Blink已经跟它融合)。
Skia方面优化 :
1,很多操作还是通过CPU进行的,Intel CPU有特殊指令集,用好这些指令集会有很多性能提升。
2,我们会做图形也是因为web的趋势是越来越多地用GPU而不是CPU来渲染。移动平台的GPU能力,近年来增长非常快,很多以前只有CPU能完成的任务,现在都能用GPU完成,而且性能更好。Skia代码中有些GPU的逻辑,要么有bug,要么还不够优化,我们消除了很多这样的正确性和性能问题,从而可以顺利的从CPU切换到GPU。
3,对路径渲染的一些优化。
4, CSS的很多优化,比如transform,box-shadow。
Chromium方面优化:
1,针对特殊场景的优化。比如Canvas2D被用在轻量级应用时,一些overhead可以忽略。但当用于一些heavy的游戏,比如一帧要画成百上千的东西时,引擎的一些overhead就突然成了瓶颈。
2,针对WebGL的各种优化,比如上传canvas/video到WebGL,GPU到GPU的纹理拷贝等。
3,一些场景下DOM操作的优化。
4,针对反锯齿效果性能的优化。
余枝强:的确有这个现象,有很多HTML5游戏引擎厂商都是自定义的一套 API,实现上其实是完全绕过了HTML5引擎,直接调到了底层的库。开发者就围绕这些API来开发,这在某些情况下的确有更好的性能,但也丧失了HTML5的一些优势,包括通用性,以及与HTML5 API的交互能力 (比如DOM)。不过这也是一种做法,但我觉得另一种可能更好的路是把HTML5 和 原生实现更高效的融合起来, 在把HTML5 本身的优势发挥出来,把标准的API以及丰富的HTML5 库利用起来,同时也能有和原生实现类似的性能。
余枝强:这个是有的。但首先我们要理解一下浏览器和独立的Web 引擎之间的区别。比如对于浏览器,你不知会访问哪个页面,所以为了防止潜在的恶意代码,在安全方面需要做很多检查,增加额外的开销,不同的页面也需要做相应的隔离。同时,浏览器需要更通用一点,来满足不同应用的需求,而通用也就意味着不容易做一些特定的优化。而作为一个独立应用,代码是可控的,场景是特定的,相对容易做一些针对性的优化。另外,在交互方面,比如浏览器里网页前进后退、手势,这些对于独立应用是不需要甚至有冲突的,这方面也是不小的区别。
但对于基础渲染,GPU加速等,浏览器和web引擎的基本是一致的. 还有,比如说把指令级的并行如SIMD带入到Web平台,这个也是通用的。SIMD.JS最先是在Crosswalk中有完整的实现,然后变成一个web标准,目前主流的浏览器厂商比如Google/Microsoft等都在加入相应支持。
余枝强:对于runtime会提供打包工具,可以将H5应用可选地打包成Android或IOS应用,所以不会减少用户。 只是在IOS上实际使用的是它自身的WKview引擎,而不是我们的加速引擎。但是考虑到IOS硬件不错,自带引擎加速也还可以,所以其实IOS上的H5性能问题没那么严重。
顾扬:我们在这两块做的优化不算多,主要针对一些特殊场景。比如上面提到CSS有个效果是box-shadow,计算非常耗资源。我们通过cache机制,把中间相对通用的计算结果保存下来,这样很多后续运算就不需要从头来过,很好的提升了性能。当然,做好这样的优化,需要做大量实验,对数据的典型性有很好的把握,也要对Skia的cache机制有很好的了解,并做很多增强。DOM的一些优化也是针对某些场景。比如在packaged app里,可以节省一些cache获得很大的性能提升。
顾扬:优化是很难做的,我们从12年开始做优化,碰到的最大问题不是怎么修复瓶颈,而是压根不知道哪是瓶颈。你想,H5有很多关于功能的标准,但却没有关于性能的。H5涉及的面很广,包括JS,CSS,Canvas2D,WebGL,Web Audio, Web Video等。这些领域在不同的硬件配置,比如CPU,GPU,内存,屏幕尺寸和分辨率上,表现都会有很大不同。怎么设计benchmark,既cover典型的应用场景,又能充分测出每个领域的瓶颈所在,是最难的事。我们从一开始就做好了长期作战的准备,比较系统的为优化做准备。我们收集,开发和评估各种benchmark,不断积累测试方法,自主开发一系列工具帮助我们自动化测试和明确问题。在这些benchmark帮我们明确了问题之后,就需要依赖我们对web引擎的了解,分析问题所在。有些问题是比较好解决的,比如有些局部代码写的不好,或者说有些regression,也就是说以前是好的,现在不好。另一些问题是比较系统性的,解决它们需要大量的改动,甚至改动底层架构。我们通常会积极跟upstream讨论,寻求最佳的解决方案。
这是我们整体做优化的一个思路,一个过程。优化不是一蹴而就的,需要长期的积累和很多很琐碎的工作。
顾扬:耗电和性能,很多时候是一对矛盾,需要很好的权衡。
有的时候很少的性能损失或者不损失,就能省很多电。比如通常的web应用,每帧的显示通常要经过CPU处理,然后交由GPU渲染。如果GPU是瓶颈,那么CPU再快也没有用。这个时候可以通过一些聪明的调度算法,减少CPU端的操作。再比如有些video的解码工作,交给GPU处理不仅快,还能大大节省整体耗电。
但决定并不是每次都这么容易。当省电的代价是比较大的性能损失时,就需要很好衡量了。有时可以在web引擎里面设置一些启发式规则,根据系统当时的情况,作出合适的选择。
顾扬:web发展很快,越来越多的人贡献idea和code。这些贡献主要在两方面,能力和性能。
能力方面,很多native的能力正在很快的加到web中,像蓝牙,NFC,AR,VR等。我们想要打通native和web的界线,native能做的,web都要做到。之前web是在追赶native的能力,今后要慢慢lead这些能力。世界不断发展,不断有新技术出现,这些新技术以后先在web还是先在native落地,则看谁基础更好,实现更经济了。哪边发展快,哪边就能引领行业发展。
第二类是性能。上面已经谈的比较多,主要是JS语言本身的性能,以及web引擎本身的性能。至于能不能达到native性能,坦白说很难,但可能有了足够好的性能之后,这个问题就不那么重要了。比如说web有个常用的指标FPS(一秒几帧),对人眼来说60FPS就已足够好,再高人也不易察觉了。所以如果web可以达到60帧一秒,native可以到80帧,虽然web还是不如native,但已经足够好。这个时候,web在其他方面的优势,比如统一的标准,高效的开发,方便的更新等,将秒杀这些很小的劣势。web就会变成一个很适宜开发的成熟平台。所以性能发展的目标,不一定是要达到native,而是足够好。
顾扬:我做web这么多年,非常热爱web,也对它很有信心。但是我认为世界上的统一是不可能的,也是不适合发展的。总有需要native存在的领域,比如有些对性能要求非常高的地方。做个类比,我们看一下计算机语言的发展历史,高级语言在慢慢侵蚀低级语言的地盘,从汇编到C/C++,Java,以及很多的脚本语言,但低级语言并没有消失。在很多底层库中,还用了大量的汇编,C/C++有更多的领域在使用,更不用说Java之类了。
web的使命,不是彻底取代native,而是补充了多样性,把应用这个蛋糕做大了。以前的人,哪有这么多应用可以用。可预测的是,在经历了高速发展期后,它跟native的在应用中的比例会趋于一个稳定的状态,native仍会有相当可观的比例。
余枝强,目前是英特尔开源技术中心的软件技术经理。 主要负责HTML5 引擎 – Crosswalk 在安卓平台的开发,以及一些其他和Web有关的新兴技术的研发工作(如HTML5 并行技术, HTML5 游戏优化,3D Camera等)。他坚信Web是未来, 也非常希望和大家一起努力,让这个未来能够更快更好的到来。
顾扬,英特尔中国开源技术中心web研发经理,负责web图形相关功能(CSS, Canvas2D和WebGL等)的实现和优化。2013年硕士毕业于浙江大学,后加入Intel从事编译器开发5年,转而主攻web。在web领域,带领团队完成Android Chrome 32位到64位的移植,负责英特尔移动平台web支持,更是贡献400多个patch到Chromium Upstream (包括Chromium, Blink, Skia等)和Khronos Github,实现和优化图形相关功能。业余爱好羽毛球,曾任上海英特尔羽毛球俱乐部主席7年,获奖颇丰。