You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@weex.apache.org by ky...@apache.org on 2019/07/31 13:08:21 UTC

[incubator-weex] branch master updated: [Android] record performance detail cost (#2769)

This is an automated email from the ASF dual-hosted git repository.

kyork pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-weex.git


The following commit(s) were added to refs/heads/master by this push:
     new 76bfd6b   [Android] record performance detail cost (#2769)
76bfd6b is described below

commit 76bfd6b5b25d9e2bf009dbbd254873a6f5fe369a
Author: chen <lu...@users.noreply.github.com>
AuthorDate: Wed Jul 31 21:08:16 2019 +0800

     [Android] record performance detail cost (#2769)
---
 .../main/java/com/taobao/weex/WXSDKInstance.java   |  3 +-
 .../main/java/com/taobao/weex/bridge/WXBridge.java | 13 ++++
 .../com/taobao/weex/bridge/WXBridgeManager.java    | 13 ++++
 .../com/taobao/weex/performance/WXInstanceApm.java | 72 ++++++++++++++++++++++
 .../weex/ui/action/GraphicActionAddElement.java    | 11 ++++
 weex_core/Source/android/wrap/wx_bridge.cpp        | 35 +++++++++++
 .../android/jniprebuild/jniheader/WXBridge_jni.h   | 33 ++++++++++
 .../Source/core/moniter/render_performance.cpp     | 13 ++++
 weex_core/Source/core/moniter/render_performance.h |  9 ++-
 .../Source/core/render/page/render_page_base.cpp   |  6 +-
 .../Source/core/render/page/render_page_base.h     |  2 +
 11 files changed, 207 insertions(+), 3 deletions(-)

diff --git a/android/sdk/src/main/java/com/taobao/weex/WXSDKInstance.java b/android/sdk/src/main/java/com/taobao/weex/WXSDKInstance.java
index 17cd7c8..c982e80 100644
--- a/android/sdk/src/main/java/com/taobao/weex/WXSDKInstance.java
+++ b/android/sdk/src/main/java/com/taobao/weex/WXSDKInstance.java
@@ -816,6 +816,7 @@ public class WXSDKInstance implements IWXActivityStateListener,View.OnLayoutChan
     }
     mApmForInstance.setPageName(pageName);
     mApmForInstance.onStage(WXInstanceApm.KEY_PAGE_STAGES_RENDER_ORGIGIN);
+    mApmForInstance.doDelayCollectData();
 
     mWXPerformance.pageName = (TextUtils.isEmpty(pageName) ? "defaultBundleUrl":pageName);
     if (TextUtils.isEmpty(mBundleUrl)) {
@@ -1641,7 +1642,7 @@ public class WXSDKInstance implements IWXActivityStateListener,View.OnLayoutChan
     if (mHasCreateFinish){
       lazyLoadTime = lastElementChangeTime - mWXPerformance.renderTimeOrigin;
       if (lazyLoadTime > 8000) {
-        //bad case
+        //force record detail performance data
         return;
       }
     }
diff --git a/android/sdk/src/main/java/com/taobao/weex/bridge/WXBridge.java b/android/sdk/src/main/java/com/taobao/weex/bridge/WXBridge.java
index 512ab32..669032f 100755
--- a/android/sdk/src/main/java/com/taobao/weex/bridge/WXBridge.java
+++ b/android/sdk/src/main/java/com/taobao/weex/bridge/WXBridge.java
@@ -122,6 +122,7 @@ public class WXBridge implements IWXBridge {
 
   private native void nativeSetPageArgument(String instanceId, String key, String value);
 
+  public native void nativeOnInteractionTimeUpdate(String instanceId);
 
   /**
    * Update Init Framework Params
@@ -183,6 +184,18 @@ public class WXBridge implements IWXBridge {
             ResultCallbackManager.generateCallbackId(callback));
   }
 
+  @CalledByNative
+  public void onNativePerformanceDataUpdate(String instanceId,Map<String,String> map){
+    if (TextUtils.isEmpty(instanceId) || null == map || map.size() < 1){
+      return;
+    }
+    WXSDKInstance instance = WXSDKManager.getInstance().getAllInstanceMap().get(instanceId);
+    if (null == instance || null == instance.getApmForInstance()){
+      return;
+    }
+    instance.getApmForInstance().updateNativePerformanceData(map);
+  }
+
   // Result from js engine
   @CalledByNative
   public void onReceivedResult(long callbackId, byte[] result) {
diff --git a/android/sdk/src/main/java/com/taobao/weex/bridge/WXBridgeManager.java b/android/sdk/src/main/java/com/taobao/weex/bridge/WXBridgeManager.java
index 27136f6..987d83d 100755
--- a/android/sdk/src/main/java/com/taobao/weex/bridge/WXBridgeManager.java
+++ b/android/sdk/src/main/java/com/taobao/weex/bridge/WXBridgeManager.java
@@ -283,6 +283,18 @@ public class WXBridgeManager implements Callback, BactchExecutor {
 //      }
     }
   }
+
+  public void onInteractionTimeUpdate(final String instanceId){
+    post(new Runnable() {
+      @Override
+      public void run() {
+        if (mWXBridge instanceof WXBridge ){
+          ((WXBridge)mWXBridge).nativeOnInteractionTimeUpdate(instanceId);
+        }
+      }
+    });
+  }
+
   public boolean jsEngineMultiThreadEnable() {
     return isJsEngineMultiThreadEnable;
   }
@@ -1021,6 +1033,7 @@ public class WXBridgeManager implements Callback, BactchExecutor {
         WXSDKInstance instance = WXSDKManager.getInstance().getAllInstanceMap().get(instanceId);
         if (null != instance && instance.isPreInitMode()){
           instance.getApmForInstance().onStage(WXInstanceApm.KEY_PAGE_STAGES_LOAD_BUNDLE_END);
+          instance.getApmForInstance().onStageWithTime(WXInstanceApm.KEY_PAGE_STAGES_END_EXCUTE_BUNDLE,WXUtils.getFixUnixTime()+600);
         }
       }
     });
diff --git a/android/sdk/src/main/java/com/taobao/weex/performance/WXInstanceApm.java b/android/sdk/src/main/java/com/taobao/weex/performance/WXInstanceApm.java
index 28f5765..d75e271 100644
--- a/android/sdk/src/main/java/com/taobao/weex/performance/WXInstanceApm.java
+++ b/android/sdk/src/main/java/com/taobao/weex/performance/WXInstanceApm.java
@@ -74,8 +74,10 @@ public class WXInstanceApm {
     public static final String KEY_PAGE_STAGES_CREATE_FINISH= "wxJSBundleCreateFinish";
     public static final String KEY_PAGE_STAGES_FSRENDER = "wxFsRender";
     public static final String KEY_PAGE_STAGES_NEW_FSRENDER = "wxNewFsRender";
+    public static final String KEY_PAGE_STAGES_END_EXCUTE_BUNDLE = "wxEndExecuteBundle";
     public static final String KEY_PAGE_STAGES_INTERACTION = "wxInteraction";
     public static final String KEY_PAGE_STAGES_DESTROY = "wxDestroy";
+
     //Custom preprocessing start, called when activity created or other time. Called by other activity
     public static final String KEY_PAGE_STAGES_CUSTOM_PREPROCESS_START = "wxCustomPreprocessStart";
     //Custom preprocessing end, called when you'are able to start weex render. Called by other activity
@@ -117,6 +119,11 @@ public class WXInstanceApm {
     public static final String KEY_PAGE_STATS_NET_SUCCESS_NUM = "wxNetworkRequestSuccessCount";
     public static final String KEY_PAGE_STATS_NET_FAIL_NUM = "wxNetworkRequestFailCount";
     public static final String KEY_PAGE_STATS_JSLIB_INIT_TIME = "wxJSLibInitTime";
+    public static final String KEY_PAGE_STATS_VIEW_CREATE_COST = "wxViewCost";
+    public static final String KEY_PAGE_STATS_COMPONENT_CREATE_COST = "wxComponentCost";
+    public static final String KEY_PAGE_STATS_EXECUTE_JS_CALLBACK_COST = "wxExecJsCallBack";
+    public static final String KEY_PAGE_STATS_LAYOUT_TIME = "wxLayoutTime";
+
 
     /************** value *****************/
     public static final String VALUE_ERROR_CODE_DEFAULT = "0";
@@ -141,6 +148,18 @@ public class WXInstanceApm {
 
     public Set<String> exceptionRecord = new CopyOnWriteArraySet<String>();
 
+    private double interactionLayoutTime;
+    public long componentCreateTime;
+    private long interactionComponentCreateTime;
+    public long viewCreateTime;
+    private long interactionViewCreateTime;
+    //next version
+    private long wxExecJsCallBackTime;
+    private long interactionJsCallBackTime;
+
+
+    private boolean mHasRecordDetailData = false;
+
     /**
      * send performance value to js
      **/
@@ -367,6 +386,8 @@ public class WXInstanceApm {
         if (null == apmInstance || mEnd) {
             return;
         }
+        new Handler(Looper.getMainLooper()).removeCallbacks(delayCollectDataTask);
+        recordPerformanceDetailData();
         exceptionRecord.clear();
         mUIHandler.removeCallbacks(jsPerformanceCallBack);
         onStage(KEY_PAGE_STAGES_DESTROY);
@@ -379,6 +400,17 @@ public class WXInstanceApm {
         }
     }
 
+    public void doDelayCollectData(){
+        new Handler(Looper.getMainLooper()).postDelayed(delayCollectDataTask,8000);
+    }
+
+    private Runnable delayCollectDataTask = new Runnable() {
+        @Override
+        public void run() {
+            recordPerformanceDetailData();
+        }
+    };
+
 
     private void printLog(){
         Long startDownLoad = stageMap.get(KEY_PAGE_STAGES_DOWN_BUNDLE_START);
@@ -450,6 +482,17 @@ public class WXInstanceApm {
         if (forceStopRecordInteraction){
             return;
         }
+        long now = WXUtils.getFixUnixTime();
+        if (now - preUpdateTime > 50){
+            //for performance, reduce jni calls
+            WXBridgeManager.getInstance().onInteractionTimeUpdate(mInstanceId);
+            preUpdateTime = now;
+        }
+
+        interactionComponentCreateTime = componentCreateTime;
+        interactionViewCreateTime = viewCreateTime;
+        Double layoutTime = recordStatsMap.get("wxLayoutTime");
+        interactionLayoutTime = layoutTime ==null? 0:layoutTime;
 
         performanceRecord.interactionTime = curTime - performanceRecord.renderUnixTimeOrigin;
         performanceRecord.interactionRealUnixTime = System.currentTimeMillis();
@@ -463,6 +506,8 @@ public class WXInstanceApm {
         }
     }
 
+    private long preUpdateTime = 0;
+
     public void updateFSDiffStats(String name, double diffValue) {
         if (null == apmInstance || isFSEnd) {
             return;
@@ -470,6 +515,17 @@ public class WXInstanceApm {
         updateDiffStats(name, diffValue);
     }
 
+    public void recordPerformanceDetailData(){
+        if (mHasRecordDetailData){
+            return;
+        }
+        mHasRecordDetailData = true;
+        addStats(KEY_PAGE_STATS_VIEW_CREATE_COST,interactionViewCreateTime);
+        addStats(KEY_PAGE_STATS_COMPONENT_CREATE_COST,interactionComponentCreateTime);
+        addStats(KEY_PAGE_STATS_EXECUTE_JS_CALLBACK_COST,interactionJsCallBackTime);
+        addStats(KEY_PAGE_STATS_LAYOUT_TIME,interactionLayoutTime);
+    }
+
     public void updateDiffStats(String name, double diffValue) {
         if (null == apmInstance) {
             return;
@@ -608,4 +664,20 @@ public class WXInstanceApm {
         return builder.toString();
    }
 
+   public void updateNativePerformanceData(Map<String,String> nativePerformanceData){
+        if (null == nativePerformanceData){
+            return;
+        }
+        for (Map.Entry<String,String> entry : nativePerformanceData.entrySet()){
+            double value = -1;
+            try {
+                value = Double.valueOf(entry.getValue());
+            }catch (Exception e){
+                e.printStackTrace();
+            }
+            if (value != -1){
+                recordStatsMap.put(entry.getKey(),value);
+            }
+        }
+   }
  }
diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/action/GraphicActionAddElement.java b/android/sdk/src/main/java/com/taobao/weex/ui/action/GraphicActionAddElement.java
index 85dd99e..a0b2005 100644
--- a/android/sdk/src/main/java/com/taobao/weex/ui/action/GraphicActionAddElement.java
+++ b/android/sdk/src/main/java/com/taobao/weex/ui/action/GraphicActionAddElement.java
@@ -36,6 +36,8 @@ import com.taobao.weex.ui.component.WXComponent;
 import com.taobao.weex.ui.component.WXVContainer;
 import com.taobao.weex.utils.WXExceptionUtils;
 import com.taobao.weex.utils.WXLogUtils;
+import com.taobao.weex.utils.WXUtils;
+
 import java.util.Arrays;
 import java.util.Locale;
 import java.util.Map;
@@ -78,10 +80,13 @@ public class GraphicActionAddElement extends GraphicActionAbstractAddElement {
     try {
       parent = (WXVContainer) WXSDKManager.getInstance().getWXRenderManager()
           .getWXComponent(getPageId(), mParentRef);
+      long start = WXUtils.getFixUnixTime();
       BasicComponentData basicComponentData = new BasicComponentData(ref, mComponentType,
           mParentRef);
       child = createComponent(instance, parent, basicComponentData);
       child.setTransition(WXTransition.fromMap(child.getStyles(), child));
+      long diff = WXUtils.getFixUnixTime()-start;
+      instance.getApmForInstance().componentCreateTime += diff;
       if (null != parent && parent.isIgnoreInteraction){
         child.isIgnoreInteraction = true;
       }
@@ -187,6 +192,7 @@ public class GraphicActionAddElement extends GraphicActionAbstractAddElement {
       if (!TextUtils.equals(mComponentType, "video") && !TextUtils.equals(mComponentType, "videoplus"))
         child.mIsAddElementToTree = true;
 
+      long start = WXUtils.getFixUnixTime();
       parent.addChild(child, mIndex);
       parent.createChildViewAt(mIndex);
 
@@ -196,6 +202,11 @@ public class GraphicActionAddElement extends GraphicActionAbstractAddElement {
       }
       child.applyLayoutAndEvent(child);
       child.bindData(child);
+      long diff = WXUtils.getFixUnixTime() - start;
+      if (null != getWXSDKIntance()){
+        getWXSDKIntance().getApmForInstance().viewCreateTime +=diff;
+      }
+
     } catch (Exception e) {
       WXLogUtils.e("add component failed.", e);
     }
diff --git a/weex_core/Source/android/wrap/wx_bridge.cpp b/weex_core/Source/android/wrap/wx_bridge.cpp
index 01fd2b0..9cf5ee3 100755
--- a/weex_core/Source/android/wrap/wx_bridge.cpp
+++ b/weex_core/Source/android/wrap/wx_bridge.cpp
@@ -19,6 +19,7 @@
 
 #include "android/wrap/wx_bridge.h"
 #include <fstream>
+#include <core/render/manager/render_manager.h>
 
 #include "android/wrap/log_utils.h"
 #include "android/base/string/string_utils.h"
@@ -44,6 +45,8 @@
 #include "core/bridge/eagle_bridge.h"
 #include "core/common/view_utils.h"
 #include "third_party/json11/json11.hpp"
+#include "core/moniter/render_performance.h"
+#include "core/render/page/render_page_base.h"
 
 using namespace WeexCore;
 jlongArray jFirstScreenRenderTime = nullptr;
@@ -662,6 +665,38 @@ static jstring ExecJSOnInstance(JNIEnv* env, jobject jcaller,
   return env->NewStringUTF(result->data.get());
 }
 
+static void onInteractionTimeUpdate(JNIEnv* env, jobject jcaller, jstring instanceId) {
+  ScopedJStringUTF8 idChar(env, instanceId);
+
+  RenderPageBase* page = RenderManager::GetInstance()->GetPage(idChar.getChars());
+  if (nullptr == page){
+    return;
+  }
+  auto performance = page->getPerformance();
+  if (nullptr == performance){
+    return;
+  }
+  bool change = performance->onInteractionTimeUpdate();
+
+  if (!change){
+      return;
+  }
+
+  std::map<std::string,std::string> c_performance_data;
+  performance->getPerformanceStringData(c_performance_data);
+
+
+  auto performance_map = std::unique_ptr<WXMap>(new WXMap);
+  if (performance_map == nullptr) {
+      return;
+  }
+  performance_map->Put(env,c_performance_data);
+
+  jobject jni_map_performance =
+          performance_map.get() != nullptr ? performance_map->jni_object() : nullptr;
+  Java_WXBridge_onNativePerformanceDataUpdate(env,jcaller,instanceId,jni_map_performance);
+}
+
 static void FireEventOnDataRenderNode(JNIEnv* env, jobject jcaller,
                                       jstring instanceId, jstring ref,
                                       jstring type, jstring data,
diff --git a/weex_core/Source/base/android/jniprebuild/jniheader/WXBridge_jni.h b/weex_core/Source/base/android/jniprebuild/jniheader/WXBridge_jni.h
index e53e07e..f8e04ce 100755
--- a/weex_core/Source/base/android/jniprebuild/jniheader/WXBridge_jni.h
+++ b/weex_core/Source/base/android/jniprebuild/jniheader/WXBridge_jni.h
@@ -88,6 +88,8 @@ static jstring ExecJSOnInstance(JNIEnv* env, jobject jcaller,
     jstring script,
     jint type);
 
+static void onInteractionTimeUpdate(JNIEnv* env, jobject jcaller, jstring instanceId);
+
 static void FireEventOnDataRenderNode(JNIEnv* env, jobject jcaller,
     jstring instanceId,
     jstring ref,
@@ -1092,6 +1094,31 @@ static void Java_WXBridge_reportNativeInitStatus(JNIEnv* env, jobject obj,
 
 }
 
+static intptr_t g_WXBridge_onNativePerformanceDataUpdate = 0;
+static void Java_WXBridge_onNativePerformanceDataUpdate(JNIEnv* env, jobject obj,
+                                                        jstring id,
+                                                        jobject data) {
+    /* Must call RegisterNativesImpl()  */
+    //CHECK_CLAZZ(env, obj,
+    //    WXBridge_clazz(env));
+    jmethodID method_id =
+            base::android::GetMethod(
+                    env, WXBridge_clazz(env),
+                    base::android::INSTANCE_METHOD,
+                    "onNativePerformanceDataUpdate",
+                    "("
+                    "Ljava/lang/String;"
+                    "Ljava/util/Map;"
+                    ")"
+                    "V",
+                    &g_WXBridge_onNativePerformanceDataUpdate);
+
+    env->CallVoidMethod(obj,
+                        method_id, id, data);
+    base::android::CheckException(env);
+
+}
+
 // Step 3: RegisterNatives.
 
 static const JNINativeMethod kMethodsWXBridge[] = {
@@ -1162,6 +1189,11 @@ static const JNINativeMethod kMethodsWXBridge[] = {
 "I"
 ")"
 "Ljava/lang/String;", reinterpret_cast<void*>(ExecJSOnInstance) },
+    { "nativeOnInteractionTimeUpdate",
+"("
+"Ljava/lang/String;"
+")"
+"V", reinterpret_cast<void*>(onInteractionTimeUpdate) },
 { "nativeFireEventOnDataRenderNode",
     "("
     "Ljava/lang/String;"
@@ -1389,6 +1421,7 @@ static void Java_WXBridge_reset_clazz(JNIEnv* env, const char* className) {
     g_WXBridge_callHasTransitionPros = 0;
     g_WXBridge_getMeasurementFunc = 0;
     g_WXBridge_reportNativeInitStatus = 0;
+    g_WXBridge_onNativePerformanceDataUpdate = 0;
 }
 
 #endif  // com_taobao_weex_bridge_WXBridge_JNI
diff --git a/weex_core/Source/core/moniter/render_performance.cpp b/weex_core/Source/core/moniter/render_performance.cpp
index a35eeb4..0730f37 100644
--- a/weex_core/Source/core/moniter/render_performance.cpp
+++ b/weex_core/Source/core/moniter/render_performance.cpp
@@ -17,6 +17,7 @@
  * under the License.
  */
 #include <cstdint>
+#include <string>
 #include "render_performance.h"
 
 namespace WeexCore {
@@ -43,4 +44,16 @@ namespace WeexCore {
 
     return ret;
   }
+
+    bool RenderPerformance::onInteractionTimeUpdate() {
+      if (cssLayoutTimeForInteraction == cssLayoutTime){
+          return false;
+      }
+      cssLayoutTimeForInteraction = cssLayoutTime;
+        return true;
+    }
+
+    void RenderPerformance::getPerformanceStringData(std::map<std::string, std::string> &map) {
+        map["wxLayoutTime"] = std::to_string(this->cssLayoutTimeForInteraction);
+    }
 }
diff --git a/weex_core/Source/core/moniter/render_performance.h b/weex_core/Source/core/moniter/render_performance.h
index 1eff88f..140b7b2 100644
--- a/weex_core/Source/core/moniter/render_performance.h
+++ b/weex_core/Source/core/moniter/render_performance.h
@@ -20,6 +20,7 @@
 #define WEEX_PROJECT_WXPERFORMANCE_H
 
 #include <vector>
+#include <map>
 
 namespace WeexCore {
 
@@ -49,10 +50,16 @@ namespace WeexCore {
 
     int64_t onRenderSuccessParseJsonTime;
 
+    int64_t cssLayoutTimeForInteraction;
+
     RenderPerformance() : callBridgeTime(0), cssLayoutTime(0), parseJsonTime(0),
                           firstScreenCallBridgeTime(0), firstScreenCssLayoutTime(0),
                           firstScreenParseJsonTime(0), onRenderSuccessCallBridgeTime(0),
-                          onRenderSuccessCssLayoutTime(0), onRenderSuccessParseJsonTime(0) {}
+                          onRenderSuccessCssLayoutTime(0), onRenderSuccessParseJsonTime(0),
+                          cssLayoutTimeForInteraction(0) {}
+    bool onInteractionTimeUpdate();
+
+    void getPerformanceStringData(std::map<std::string,std::string> &map);
 
     std::vector<int64_t> PrintPerformanceLog(PerformanceStage performanceStage);
   };
diff --git a/weex_core/Source/core/render/page/render_page_base.cpp b/weex_core/Source/core/render/page/render_page_base.cpp
index 8a3e914..e95f552 100644
--- a/weex_core/Source/core/render/page/render_page_base.cpp
+++ b/weex_core/Source/core/render/page/render_page_base.cpp
@@ -102,5 +102,9 @@ namespace WeexCore {
             action = nullptr;
         }
     }
-    
+
+    RenderPerformance* RenderPageBase::getPerformance() {
+        return this->render_performance_;
+    }
+
 }
diff --git a/weex_core/Source/core/render/page/render_page_base.h b/weex_core/Source/core/render/page/render_page_base.h
index 76e8658..2a546f2 100644
--- a/weex_core/Source/core/render/page/render_page_base.h
+++ b/weex_core/Source/core/render/page/render_page_base.h
@@ -84,6 +84,8 @@ public:
     virtual RenderObject *GetRenderObject(const std::string &ref) { return nullptr; };
     virtual void SetDefaultHeightAndWidthIntoRootRender(const float default_width, const float default_height,
                                                         const bool is_width_wrap_content, const bool is_height_wrap_content) {};
+
+    virtual RenderPerformance* getPerformance();
     
     virtual void OnRenderPageClose() = 0;