当前位置:首页 > 生态圈 > 正文内容

一行代码有多少(一行代码是什么意思)

abcsky889个月前 (10-26)生态圈143

今天给各位分享

原标题:如何不改一行代码,让Hippy启动速度提升50%?如何不改一行代码,让Hippy启动速度提升50%? 作者:pennyli,腾讯PCG客户端开发工程师背景 目前QQ浏览器(下简称QB)使用Hippy的业务超过100个,基本上95%的核心业务都是使用Hippy作为首要技术栈来开发。

一行代码有多少(一行代码是什么意思)

但是跟Native相比较而言,Hippy是使用JS引擎进行异步渲染,在用户从点击到打开首屏可交互过程中会有一定的耗时,影响用户体验如何优化这段耗时,尽量对齐Native体验,想必是每个团队需要思考优化的事情。

本文主要介绍QQ浏览器通过切换JS引擎来优化耗时的探索过程和效果收益,主要包含:通过分析H网站建设及推广优化ippy执行流程及耗时瓶颈,对比业界JS引擎方案,选择使用Hermes引擎,将JS离线生成Bytecode,使用引擎直接加载Bytecode的能力,在业务无需修改一行代码的前提下,让Hippy的包加载速度提高80%,首帧耗时优化50%起。

Hippy业务耗时瓶颈分析 Hippy整个启动流程,依赖JS线程的执行,我们其实可以将整个过程抽象看成一个串行的操作,以QB冷启动首页Feed流,结合线上数据性能监控可以看到如下阶段耗时:

注:TTI = Time To Interact,意思是从业务创建到业务可交互所花费的时间,因为衡量业务可交互比较复杂,各个业务对可交互的定义不一样,所以这里以首帧上屏为准来网站建设及推广优化衡量;通过打点分析得到,用户从打开业务创建RootView开始,到最终首帧上屏总共耗时1488毫秒,其中主要在Module初始化、创建HippyCore(bootstrap.js以及common包执行耗时)、业务包执行耗时上;

其中加载执行业务包耗时1303毫秒,占整体TTI的87%如果我们能够优化加载执行业务包的耗时,那么我们就可以极大的降低TTI在iOS上Hippy使用的是系统提供的JavaCore引擎来运行JS代码,所以我们要分析一下JSC的执行过程。

JavaCore执行流程分析 具体流程:1. 词法分析,输出tokens;2. 语法分析,生产AST(抽象语法树);3. 从AST生成字节码网站建设及推广优化;4. 通过Low Level解释器执行字节码;5. 使用JIT加速解释执行机器码;(带JIT的版本)

注:本文JSC是指苹果官方提供的JavaCore.framework,JSC分带JIT与不带JIT的版本,带JIT的版本目前只有苹果自家的Safari能够使用,公开的JavaCore因为安全原因(JIT可以动态执行机器码),实际是不带JIT的版本。

下面讨论的也是指不带JIT的JSC版本整个流程,在JS代码被解释执行前,绝大部分时间消耗是在字节码生成上,如果能将Bytecode生成前置,缓存起来,每次执行JS的时候,直接取缓存的Bytecode,那将会极大降低耗时,但是很可惜的是,JavaCor网站建设及推广优化e是属于系统库,并没有提供这个能力。

我们可以考虑选择其他支持Bytecode的引擎替换掉JSC可选引擎对比 除了JSC,常见的开源引擎包括V8、QuickJS、HermesJS引擎是否支持BytecodeSDK大小是否开源作者JavaCore。

0AppleV8(仅仅是支持CodeCache,不支持直出Bytecode)8-10MGoogleQuickJS1MBellardHermes3MFacebook注:直出是指支持编译输出Bytecode文件,并且直接运行Bytecode。

Hermes和QuickJS支持直出Bytecode,并且在包大小上对比V8和JSC占优性能指标对比 以下各项对比取至网站建设及推广优化Linux上各引擎测试数据包加载耗时速度对比(越低越好) 使用引擎执行业务JS代码,其中JSC和V8均是直接执行JS代码,QuickJS和Hermes是执行Bytecode。

QuickJS一骑绝尘,Hermes紧跟其后,JSC次之,V8最差;执行效率对比(越高越好) 使用引擎跑一些开源的算法或者知名JS功能库。

V8和JSC性能最好,Hermes次之,QuickJS最差;内存增量(越低越好)

表现最好的是JSC,其次是Hermes和V8;带JIT的JSC和V8,内存消耗最高;编译文件大小 衡量编译文件压缩比是为了衡量包下发更新效率,以QB首页Feed流(3.8M左右)举例,JSC和V8均输入原始j网站建设及推广优化s文件,QuickJS和Hermes输入JS编译后的Bytecode文件。

JSC和V8压缩比较高,Hermes和QuickJS压缩比不高,在下发效率上,差于JSC和V8;结论 从执行耗时、执行性能、内存增量、编译文件大小以及整体framework大小5个纬度来分析看:1. 带JIT的JSC和V8性能最好,但是加载时间是最长的,内存消耗也是最多的,包也较大;

2. 支持提前预编译的Hermes和QuickJS,加载速度以及内存表现是最好的;对于提高TTI,加载速度指标最为重要虽然性能低于JSC和V8,但是对于JS耗时高的操作,可以充分利用modules放在Native去操作;所以基于以上,会优先考网站建设及推广优化虑Hermes和QuickJS;。

Hermes在性能、内存以及编译包大小上是优于QuickJS的,另外Hermes有Facebook的React Native社区生态支持,相较于QuickJs更新演进更快,所以更倾向使用Hermes来替换JSC。

Hermes引擎调研 编译 Hermes虽然是深度集成在React Native里的,但是facebook也将单独的引擎独立出来了,官网地址 仓库地址 编译指南按照编译指南编译之后,实际编译的产物只是用于在PC/Mac/Linux运行的Hermes二进制文件。

通过这些二进制文件,我们可以在Terminal里执行JS,以及将JS编译成Bytecode# 网站建设及推广优化执行原始JS hermes test.js# 编译并输出以及执行Bytecode hermes -emit-binary -out test.hbc test.js hermes test.hbc 。

在移动端上,Hermes也是使用CMake进行编译,并且提供了脚本可以方便输出Android和iOS动态库具体可以在官网上查看编译指南运行 Hermes包含几个非常重要的结构对象,下面主要讲其中的几个Runtime

Hermes使用非常简单,提供了一个Runtime的抽象类,所有的js对象都执行在Runtime对象上,类似JSC的JSContext;派生了HermesRuntime子类来实现所有JS网站建设及推广优化操作通过静态方法创建一个HermesRuntime对象;。

HERMES_EXPORT std::unique_ptr makeHermesRuntime( const ::hermes::vm::RuntimeConfig &runtimeConfig = ::hermes::vm::RuntimeConfig);

同时也提供了一些执行JS的方法// 执行JS(JS or Bytecode) virtual Value evaluateJava( const std::shared_ptr & buffer, const std::string& sourceURL) = 0; // 预编译JS网站建设及推广优化 virtual std::shared_ptr prepareJava( const std::shared_ptr & buffer, std::string sourceURL) = 0; // 执行预编译的JS virtual Value evaluatePreparedJava( const std::shared_ptr & js) = 0; Value

JSC在处理基础数据的时候,所有的类型都是JSValue类型;处理Object是JSObjectRef对象,在Hermes上也有对应的实现;

提供方法判断是什么类型,以及快捷获取类型值,比如:Bool isStr = value.is网站建设及推广优化Stringfacebook::jsi::String str = value.asString Object

Object对应就是JS的对象,基于Object派生Function以及Array和JSArrayBuffer,同样Object也提供很多方法获取和设置属性;Runtime提供一个默认的全局对象global, 所有的JS逻辑均运行在默认的global之上。

Object也提供很对方法获取属性,比如:// 判断是否有该属性boolhasProperty(Runtime&runtime,constchar*name)const;// 获取属性值ValuegetProperty(Runtime网站建设及推广优化&runtime,constchar*name)const;// 获取属性值并转化成objectObjectgetPropertyAsObject(Runtime&runtime,constchar*name)const; Function

对应JS的Function,提供静态方法创建Function:static Function createFromHostFunction( Runtime& runtime, const jsi::PropNameID& name, unsigned int paramCount, jsi::HostFunctionType func);

提供实例方法调用:网站建设及推广优化auto func = Function::createFromHostFunction(...)func.call(...) 同样还有Array,ArrayBuffer,HostObject等等。

通过Runtime,我们可以获取JS Object、Function,同时我们也可以创建JS Object、Function,注入给JS,这样就可以实现双向通信。Hippy2.0架构分析 架构

包含三层:1. 和平台相关的能力扩展比如Module能力和UI组件,以及调用底层HippyCore的接口封装的Bridge和JS Executor层,该层在iOS和Android上分别使用OC和JAVA实现;

2网站建设及推广优化. HippyCore层,通过napi对不同JS引擎的接口进行接口封装,抹平不同引擎的接口差异,让上层调用通过调用简单的接口实现复杂的能力,该层使用C++实现,跨平台3. 前端JS SDK层,主要是定义了双向通信的方法函数跟上层进行通信以及功能处理。

另外还包括一些能力,基本是在hippycore层实现比如C++ Modules, TurboModules等我们需要切换引擎,上下两层其实都不需要特别(大量)修改,核心就是在hippycore层,需要使用hermes将napi定义的接口全部实现一遍,以及同时实现现在已经有的Abilites。

napi 主要有几种概念Engine:负责创建VM以及Sc网站建设及推广优化ope;VM:负责创建管理Ctx,一个VM可以创建一个或者多个Ctx;Ctx:负责创建引擎实例,并封装操作引擎的接口供外部调用;CtxValue:负责封装不同引擎的JS Value;

Scope:使用Ctx,执行Hippy基础初始化流程;Scope 主要负责Hippy基础初始化流程,核心步骤如下:注入Natives方法 通过给JS注入Native Function方法的方式,让JS可以直接调用终端方法;主要是常见的JS侧CallNative方法均通过此进行分发。

执行JS Native Source Code Hippy将一部分基础JS SDK代码,通过脚本将JS代码转换成二进制集网站建设及推广优化成在hippycore的C++代码里,在通过Ctx执行这些JS代码好处是:1. 解决C++ Module跟JS侧代码一致性问题(均使用C++形式加载调用)。

2. 对于常用的基础JS的SDK代码,不用打包到基础包里,可以减少Common包大小,另外职责也分离其中包括C++ Module跟JS对象绑定,以及TurboModule和DynamicImport均在此步骤进行定义实现;。

Abilities C++ Module 不同于Native Module字符串消息映射和TurboModule HostObject的实现,C++ Module是将HippyCore里标记为导出的C++Module和其网站建设及推广优化函数对应在前端生成一个名字一样的JS对象和方法。

Hippy里常见的TimeModule,ContextifyModule均是如此实现TurboModule 前有NativeModule,后有C++Module,为什么还有TurboModle?NativeModule好处是对于一些能力要分端去实现的,两端实现起来比较方便,但是其是通过字符串映射到终端方法的方式进行调用以及存在JS线程到NativeModule线程切换效率问题;

C++Module的好处就是在JS线程直接调用绑定JS对象和方法执行,效率高,但是暴露的Module是用C++实现,如果分发调用到Native侧,一个是要区分平台,第二个是网站建设及推广优化分发到上层Java或者OC需要对应的类型转换。

为了解决上述问题,TuroboModule应运而生,兼具JS线程直接调用,并且不同平台可以分别实现自己的Turbo能力,关键是直接使用的引擎提供的HostObject方式实现,相较于C++Module 效率都更高。

Dynamic Import 动态导入能力,容许在JS侧动态加载远程或者本地JS代码,主要使用场景是对于分包加载,减少主包大小,提高业务加载包速度;最终实现也是通过C++Module ContextifyModule的LoadUntrustedContent方法来执行远端或者本地JS代码并返回给JS侧。

HippyCore异常处理 分两种异网站建设及推广优化常JS引擎接口异常,不同引擎异常不同(JSI Exception);Native异常,主要是Native侧的代码调用以及JS方法注入实现异常JS引擎接口报的异常 JSC引擎和V8处理逻辑不太一样,JSC的JSI接口会将Exception通过参数传递出来,V8是通过在调用上下文初始化TryCatch对象,对异常进行捕获;

所以对于JSC的JS异常,只需要处理接口的Exception就行;V8处理TryCatch对象捕获的异常就可以;JSValueRef js_error = nullptr; JSValueRef value_ref = JSObjectGetProperty(co网站建设及推广优化ntext_, global_obj, name_ref, &js_error); bool is_str = JSValueIsString(context_, value_ref); JSStringRelease(name_ref); Native异常

一般就是平台相关的异常,比如OC就是NSException,在双向通信以及各种JS接口注入实现处加Try-Catch进行捕获总结 通过以上架构分析,Hippy整个实现流程都已经变得非常清晰,我们可以使用Hermes的能力将上述能力均实现一下。

Hermes接入 本来是可以很详细介绍的,但是受限于篇幅不宜过长,后面在开一篇来讲Hermes接入对网站建设及推广优化比 性能 基于已经上线的业务性能统计数据(数据取至12月12日),对比如下:可以看到包加载执行耗时已经被彻底打下来了(70-80%幅度),进而极大降低了首帧耗时。

另外通过线上业务大盘整体耗时曲线图可以更直观看到效果(大部分业务没有全量,所以还会有持续下降的趋势):内存 在滑动相同的的List Item的情况下,Hippy Hermes和JSC的内存增量差别不大根据官方文档介绍Hermes应该是略优于JSC的,所以这里不排除Hippy或者前端SDK还有优化空间。

Crash Hippy的JSC相关的Crash率较高,比较难修改 Hermes也有一定的crash,但是从目前的对比来看,数量级较JSC网站建设及推广优化少很多以12月12日,iOS 13.4.0.5401版本的数据对比来看,Hermes的Crash率为JSC的50%,也就是说如果切换到Hermes上的话,相关引擎的Crash会下降一半。

JSC Crash关键词:jscctx/HippyJSCExecutor Hermes Crash关键词:hermes/HippyHermesExecutor计划的事情 目前Hermes已经在QB iOS版本上上线,业务接入成本非常低,无需修改一行代码,只需要打包的时候使用插件,输出Bytecode文件即可。

接入上线的业务已经遍布信息流、阅读、商业、搜索等各个业务场景剩余重要的事情主要有:1. Android接网站建设及推广优化入,对比V8性能,已经接近完成(对比V8,在低中端手机上有近50%的性能提升)2. Hermes调试能力,可以使用Hermes在Chrome上调试JS代码,Coming Soon!。

3. 基于Hermes的内存调试诊断工具;最后 通过接入Hermes,可以让业务更多的关注在JS业务逻辑里,让前置SDK流程的耗时不再是性能瓶颈。返回搜狐,查看更多责任编辑:

扫描二维码推送至手机访问。

版权声明:本文由海南拓宏网络科技工作室发布,如需转载请注明出处。

本文链接:http://4blc.com/post/323.html

分享给朋友:

“一行代码有多少(一行代码是什么意思)” 的相关文章

java面向对象基础知识(java语言面向对象是什么意思呀怎么写)

今天给各位分享 Java是面向对象的语言,而面向对象编程主要体现了继承、封装、多态三个特性,那么什么是对象?“一切皆对象”那么有没有更加通俗的解释是怎样的呢? 比如有个女朋友,那么她肯定是对象她的身高三围等等是参数属性,那些可以告诉别人的就叫公有属性,私密的就是私有属性;她...

java中变量的含义(java中的变量的定义是什么)

本文分享给大家的是: IT服务圈儿有温度、有态度的IT自媒体平台 变量是我们经常用到的一种,我在刚学 Java 的时候,也经常被各种变量的概念折磨,当时并没有细抠,但是我在写一篇类似的文章中,想把变量作为一种小标题来简述一下,但是发现,变量这个概念还是比较繁琐的,...

女人心歌曲在线试听(女人心歌曲原唱陈瑞dj)

本文分享给大家的是: 原标题:女人心是什么意思啊?男人懂点女人心,生活才会有趣味那么,什么是女人心,我们一起来了解下:1、女人都爱美,要懂她的口是心非(懂她)其实,不单女人,每个人都或多或少的爱美,但是女人尤为明显,她可以为了窈窕身材而饿肚子,饿到眼冒金星,浑身乏力也绝不吃东西,男...

java是什么原因(java为什么这么流行)

本文分享给大家的是: 初学者觉得复杂是很正常的,归根结底是因为没有理解JavaIO框架的设计思想:可以沿着这条路想一想:1,学IO流之前,我们写的程序,都是在内存里自己跟自己玩比如,你声明个变量,创建个数组,创建个集合,写一个排序算法,模拟一个链表,使用一些常用API,现在回想一下...

大连java培训机构有哪些(大连java招聘信息)

本文分享给大家的是: 如今,中国已经进入互联网高速发展期,各大公司在招聘时都会需要编程人员,而Java作为程序语言中较为便捷和高效的代表,已经成为许多企业招人时的首选于是,很多人为了程序员的高薪资想要通过培训转行,那么大连正规Java培训收费多少呢?今天“好程序员”就来带大家分析一...

java的数据类型有哪几种(java基础的数据类型)

今天给各位分享 什么是Java 基本数据类型前面讲过变量,程序中的变量是一个存储单元,用于存储程序中的数据而今天讲的数据类型是用来约定变量存储空间的大小约定变量存储空间大小的目的是根据数据大小选择合适的存储空间,将合适的数据存储到相应大小的存储空间可以避免计算机资源浪费,提高软件运...