前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >深入Weex系列(十)Weex SDK可优化细节思考

深入Weex系列(十)Weex SDK可优化细节思考

作者头像
用户2898788
发布2018-08-21 10:02:41
6700
发布2018-08-21 10:02:41
举报
文章被收录于专栏:双十二技术哥

1、前言

在上一篇文章中我们介绍了Weex SDK源码中可借鉴的细节,那么现在的Weex SDK已经是最优的吗?作为技术RD,我们心中一定要有敬畏:艺无止境,学习的过程中逐渐反思,寻找最优解。那么我们今天就来说说Weex SDK中有哪些可以优化的细节。

2、反射获取方法

大家知道对于Weex来说,JS引擎与Native的交互本质上就是方法的调用,最终调用的时候必然是反射无疑,但是方法的获取也是反射这一点存在很大优化空间。

先回忆下我们使用Module组件的方法:

  • 继承WXModule;
  • 编写函数体;
  • 给函数体打上注解@JSMethod;

而这些被打上注解的函数则可以拿来与Js进行交互,我们回忆下Module注册的代码,分别有Native的注册和Js的注册,注册有一步是获取Module组件中打上注解的方法:

代码语言:javascript
复制
  @Override
  public String[] getMethods() {
    if (mMethodMap == null) {
      generateMethodMap();
    }
    Set<String> keys = mMethodMap.keySet();
    return keys.toArray(new String[keys.size()]);
  }

  private void generateMethodMap() {
    if(WXEnvironment.isApkDebugable()) {
      WXLogUtils.d(TAG, "extractMethodNames:" + mClazz.getSimpleName());
    }
    HashMap<String, Invoker> methodMap = new HashMap<>();
    try {
      for (Method method : mClazz.getMethods()) {// 拿到方法
        // iterates all the annotations available in the method
        for (Annotation anno : method.getDeclaredAnnotations()) {// 方法是否被打上注解
          if (anno != null) {
            if(anno instanceof JSMethod) {
              JSMethod methodAnnotation = (JSMethod) anno;
              String name = JSMethod.NOT_SET.equals(methodAnnotation.alias())? method.getName():methodAnnotation.alias();
              methodMap.put(name, new MethodInvoker(method, methodAnnotation.uiThread()));// 封装成MethodInvoker对象
              break;
            }else if(anno instanceof WXModuleAnno) {
              WXModuleAnno methodAnnotation = (WXModuleAnno)anno;
              methodMap.put(method.getName(), new MethodInvoker(method,methodAnnotation.runOnUIThread()));
              break;
            }
          }
        }
      }
    } catch (Throwable e) {
      WXLogUtils.e("[WXModuleManager] extractMethodNames:", e);
    }
    mMethodMap = methodMap;
  }

可以看到,Module注册的过程必定是相对耗时的,而Module越多时间也越长,应用启动阶段注册的话尤为明显。而对于另一个组件Component基本也是一样的,只不过多了个注解@Component:

代码语言:javascript
复制
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Component {
  boolean lazyload() default true;
}

区别在于:对于Native注册,会有懒加载的判断,不过效果一般,因为Js端注册前已经生成一次了:

代码语言:javascript
复制
  @Override
  public void loadIfNonLazy() {
    Annotation[] annotations = mClz.getDeclaredAnnotations();
    for (Annotation annotation :
      annotations) {
      if (annotation instanceof Component){
        // 懒加载则暂时跨过这步
        if(!((Component) annotation).lazyload() && mMethodInvokers == null){
          generate();
        }
        return;
      }
    }
  }

那么反射消耗性能加上耗时的缺点应该如何解决呢?这里提供两条解决途径供参考:

  • 对Weex进行异步初始化,绝大多数应用使用Weex不会是整个App都由Weex完成,那么只要能保证Weex的初始化在使用之前完成即可;这点很容易做到毕竟App都有闪屏的时间可以利用;
  • 参考EventBus不同版本的改进,我们也可以将Weex的运行时注解改为编译时注解,这样就将在运行时的反射工作挪换到编译时,这种方式显然更好,也不需要再进行异步初始化;

3、适配的问题

对于Weex,它默认的将显示的宽度设置为750px作为适配的标准。

代码语言:javascript
复制
  @Deprecated
  public static float getRealPxByWidth(float pxValue) {
     return getRealPxByWidth(pxValue,750);
  }

  public static float getRealPxByWidth(float pxValue,int customViewport) {
    if (Float.isNaN(pxValue)) {
      return pxValue;
    }
    if (mUseWebPx) {
      return (float) Math.rint(pxValue);
    } else {
      float realPx = (pxValue * getScreenWidth() / customViewport);
      return realPx > 0.005 && realPx < 1 ? 1 : (float) Math.rint(realPx);
    }
  }

那提一个开发中的细节问题:我怎么知道需要在Vue的布局代码中写多少px呢?如果UI同学给出的不是750标准就需要自己使用公尺去计算。

解决思路:

  • 规范使用统一的页面适配保证比如出图按照750或者720(修改Weex适配的代码);
  • 修改Weex的webpack-loader,还是使用类如Android原生dp一样的布局单位(需要前端同学配合写个工具);

4、基础能力不够好

这个之前在Module的源码解析中其实提到过,比如网络请求的能力,不管是线程池的使用还是对缓存、协议等的支持都很一般。类如别的一些基础能力比如Stroage等模块也是一样。

不过这条属于苛责,之前也总结过对于Weex来说我们实际上只需要保存其Js引擎与Native的交互能力即可,别的都属于Weex为了吸引开发者而做的简略能力。现实的要求是把这些代码去掉,自己桥接原生原有的能力,缩减Apk的方法数。

5、其它

  • CSS的支持度不够完善,一些效果在Web上的显示和Native上不一样,这要求调试尽量在Native;
  • 关于文档,不可否认Weex的思路和SDK代码都非常优秀,但是文档就相对一般了,有些属于错误的;有些属于过于简单,比如对网络请求,没有Post请求的示例,对Component的自定义,没有ViewGroup的示例,有点避重就轻的嫌疑;

欢迎持续关注Weex源码分析项目:Weex-Analysis-Project

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2017-12-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 双十二技术哥 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、前言
  • 2、反射获取方法
  • 3、适配的问题
  • 4、基础能力不够好
  • 5、其它
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档