meituan / WMRouter

WMRouter是一款Android路由框架,基于组件化的设计思路,有功能灵活、使用简单的特点。
https://tech.meituan.com/meituan_waimai_android_open_source_routing_framework.html
Apache License 2.0
2.31k stars 342 forks source link

feat:优化XXXAnnotationInit初始化逻辑 #71

Closed BiaoWu closed 3 years ago

BiaoWu commented 5 years ago

主要目的是为了减少加载耗时。

修改前: image

修改后 image

项目中的Demo测试耗时 修改前: 2019-09-19 18:19:04.359 29256-29276/com.sankuai.waimai.router.demo I/WMRouter: ServiceLoader init cost 4 ms 2019-09-19 18:19:04.364 29256-29276/com.sankuai.waimai.router.demo I/WMRouter: PageAnnotationHandler init cost 4 ms 2019-09-19 18:19:04.377 29256-29276/com.sankuai.waimai.router.demo I/WMRouter: UriAnnotationHandler init cost 12 ms 2019-09-19 18:19:04.382 29256-29276/com.sankuai.waimai.router.demo I/WMRouter: RegexAnnotationHandler init cost 4 ms

修改后: 2019-09-19 18:22:03.080 29707-29727/? I/WMRouter: ServiceLoader init cost 12 ms

24ms —> 12ms,大约提升50%

jzj1993 commented 4 years ago

感谢提交代码,我理解你的修改相当于把原先运行时用ServiceLoader加载AnnotationInit的过程直接用插件解决了,确实对运行时的性能有所提升。

但是貌似也有点问题:

1、Demo中的页面数量少,性能提升50%的说服力不够。实际项目中可能有上百个页面,因此AnnotationHandler自身的初始化耗时会长很多,而减少的主要是ServiceLoader加载AnnotationInit的过程,包括HashMap操作以及AnnotationInit对象实例化的耗时,优化效果可能没有这么明显。

2、【主要问题】原先各个AnnotationHandler各自负责自己的初始化,可以确保初始化被调用到。但是修改之后,如果用户有特殊需求,自己覆写了RootUriHandler,并且AnnotationHandler并不是直接嵌套在RootUriHandler中,而是中间又加了别的Handler,就会导致初始化失效(findChildHandlerByClass找不到对应的Handler)。

3、原先的lazyInit设计,ServiceLoader和每个AnnotationHandler的初始化都可以分开进行,对性能要求比较高的时候,用户可以控制调用lazyInit方法的时机。一种常见的场景是,App启动时(Application.onCreate)就需要ServiceLoader,但启动到首页之后才需要页面跳转,这时AnnotationHandler初始化可以从Application延后到Activity,有利于加速App冷启动(对于更复杂的项目,甚至还可以把初始化过程继续拆分,按需、分组注册页面)。

jzj1993 commented 3 years ago

这个PR先关闭了,如果后面有更好的优化方案,欢迎重新提PR。感谢~