You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@weex.apache.org by mi...@apache.org on 2017/08/15 09:51:31 UTC
[06/16] incubator-weex git commit: + [android] batch modification for
tracing @notdanger
+ [android] batch modification for tracing @notdanger
Project: http://git-wip-us.apache.org/repos/asf/incubator-weex/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-weex/commit/102f2ed0
Tree: http://git-wip-us.apache.org/repos/asf/incubator-weex/tree/102f2ed0
Diff: http://git-wip-us.apache.org/repos/asf/incubator-weex/diff/102f2ed0
Branch: refs/heads/0.16-dev
Commit: 102f2ed0db66226aff309215acbd94472b77390b
Parents: e2d8a7b
Author: misakuo <mi...@apache.org>
Authored: Thu Aug 10 14:35:54 2017 +0800
Committer: misakuo <mi...@apache.org>
Committed: Thu Aug 10 14:35:54 2017 +0800
----------------------------------------------------------------------
.../com/alibaba/weex/PerformanceActivity.java | 121 --------------
.../java/com/taobao/weex/WXSDKInstance.java | 37 ++++-
.../main/java/com/taobao/weex/WXSDKManager.java | 9 ++
.../taobao/weex/adapter/ITracingAdapter.java | 31 ++++
.../com/taobao/weex/bridge/WXBridgeManager.java | 66 +++++++-
.../java/com/taobao/weex/common/WXTracing.java | 76 ---------
.../taobao/weex/dom/DOMActionContextImpl.java | 23 +--
.../com/taobao/weex/dom/RenderActionTask.java | 26 +++-
.../java/com/taobao/weex/dom/WXDomHandler.java | 15 +-
.../java/com/taobao/weex/dom/WXDomManager.java | 16 +-
.../java/com/taobao/weex/dom/WXDomModule.java | 37 ++++-
.../java/com/taobao/weex/dom/WXDomObject.java | 9 ++
.../dom/action/AbstractAddElementAction.java | 28 +++-
.../dom/action/AbstractLayoutFinishAction.java | 3 +-
.../weex/dom/action/AddElementAction.java | 30 +++-
.../taobao/weex/dom/action/AddEventAction.java | 27 +++-
.../weex/dom/action/CreateBodyAction.java | 19 +++
.../weex/dom/action/CreateFinishAction.java | 6 +
.../weex/dom/action/RefreshFinishAction.java | 4 +
.../taobao/weex/dom/action/TraceableAction.java | 82 ++++++++++
.../weex/dom/action/UpdateAttributeAction.java | 2 +-
.../weex/dom/action/UpdateStyleAction.java | 2 +-
.../java/com/taobao/weex/tracing/Stopwatch.java | 132 ++++++++++++++++
.../java/com/taobao/weex/tracing/WXTracing.java | 156 +++++++++++++++++++
.../com/taobao/weex/ui/WXRenderManager.java | 32 +++-
.../taobao/weex/ui/component/WXComponent.java | 58 +++++--
.../taobao/weex/ui/component/WXVContainer.java | 18 +++
.../ui/component/list/BasicListComponent.java | 2 +-
.../java/com/taobao/weex/utils/WXLogUtils.java | 45 +++---
.../com/taobao/weex/utils/WXLogUtilsTest.java | 1 -
30 files changed, 826 insertions(+), 287 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/102f2ed0/android/playground/app/src/main/java/com/alibaba/weex/PerformanceActivity.java
----------------------------------------------------------------------
diff --git a/android/playground/app/src/main/java/com/alibaba/weex/PerformanceActivity.java b/android/playground/app/src/main/java/com/alibaba/weex/PerformanceActivity.java
deleted file mode 100644
index ad88546..0000000
--- a/android/playground/app/src/main/java/com/alibaba/weex/PerformanceActivity.java
+++ /dev/null
@@ -1,121 +0,0 @@
-package com.alibaba.weex;
-
-
-import android.content.Context;
-import android.content.Intent;
-import android.graphics.Color;
-import android.os.Bundle;
-import android.support.v4.app.Fragment;
-import android.support.v4.app.FragmentManager;
-import android.view.Gravity;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-
-import com.alibaba.weex.performance.EnvironmentFragment;
-import com.alibaba.weex.performance.EventOverviewFragment;
-
-public class PerformanceActivity extends WXBaseActivity {
-
- private LinearLayout segmentHost;
-
- public static void start(Context context, int instanceId) {
- Intent intent = new Intent(context, PerformanceActivity.class);
- intent.putExtra("instanceId", instanceId);
- context.startActivity(intent);
- }
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_performance);
- segmentHost = (LinearLayout) findViewById(R.id.segment_control);
- addTab("页面性能", true, new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- switchFragment(EventOverviewFragment.getInstance(getIntent().getIntExtra("instanceId", -1)));
- }
- });
-
- addTab("DOM树", false, new View.OnClickListener() {
- @Override
- public void onClick(View v) {
-
- }
- });
-
- addTab("JS LOG", false, new View.OnClickListener() {
- @Override
- public void onClick(View v) {
-
- }
- });
-
- addTab("环境变量", false, new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- switchFragment(new EnvironmentFragment());
- }
- });
- }
-
- private void switchFragment(Fragment fragment) {
- getSupportFragmentManager()
- .beginTransaction()
- .replace(R.id.fragment_container, fragment)
- .commitAllowingStateLoss();
- }
-
- @Override
- protected void onResumeFragments() {
- super.onResumeFragments();
- FragmentManager fragmentManager = getSupportFragmentManager();
-
- Fragment fragment = fragmentManager.findFragmentById(R.id.fragment_container);
- if (fragment == null) {
- fragmentManager
- .beginTransaction()
- .add(R.id.fragment_container, EventOverviewFragment.getInstance(getIntent().getIntExtra("instanceId", -1)))
- .commitAllowingStateLoss();
- }
- }
-
- private void addTab(String title, final boolean selected, final View.OnClickListener listener) {
- final TextView textView = new TextView(this);
- textView.setText(title);
- LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
- lp.weight = 1;
- lp.setMargins(1, 1, 1, 1);
- if (selected) {
- textView.setBackgroundColor(Color.TRANSPARENT);
- } else {
- textView.setBackgroundColor(Color.WHITE);
- }
- textView.setGravity(Gravity.CENTER);
- textView.setLayoutParams(lp);
- textView.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- if (!v.isSelected() && v instanceof TextView) {
- listener.onClick(v);
- for (int i = 0; i < segmentHost.getChildCount(); i++) {
- segmentHost.getChildAt(i).setSelected(false);
- segmentHost.getChildAt(i).setBackgroundColor(Color.WHITE);
- ((TextView) segmentHost.getChildAt(i)).setTextColor(Color.parseColor("#1E90FF"));
- }
- v.setSelected(true);
- v.setBackgroundColor(Color.TRANSPARENT);
- ((TextView) v).setTextColor(Color.WHITE);
- }
- }
- });
- textView.setSelected(selected);
- if (selected) {
- textView.setTextColor(Color.WHITE);
- } else {
- textView.setTextColor(Color.parseColor("#1E90FF"));
- }
- segmentHost.addView(textView);
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/102f2ed0/android/sdk/src/main/java/com/taobao/weex/WXSDKInstance.java
----------------------------------------------------------------------
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 a8d8a60..d806148 100644
--- a/android/sdk/src/main/java/com/taobao/weex/WXSDKInstance.java
+++ b/android/sdk/src/main/java/com/taobao/weex/WXSDKInstance.java
@@ -61,6 +61,7 @@ import com.taobao.weex.dom.WXDomObject;
import com.taobao.weex.dom.WXDomTask;
import com.taobao.weex.dom.WXEvent;
import com.taobao.weex.http.WXHttpUtil;
+import com.taobao.weex.tracing.WXTracing;
import com.taobao.weex.ui.component.NestedContainer;
import com.taobao.weex.ui.component.WXBasicComponentType;
import com.taobao.weex.ui.component.WXComponent;
@@ -116,6 +117,9 @@ public class WXSDKInstance implements IWXActivityStateListener,DomContext, View.
private static volatile int mViewPortWidth = 750;
private int mInstanceViewPortWidth = 750;
+ public long mRenderStartNanos;
+ public int mExecJSTraceId = WXTracing.nextId();
+
/**
* Render strategy.
*/
@@ -415,6 +419,16 @@ public class WXSDKInstance implements IWXActivityStateListener,DomContext, View.
return;
}
+ if (WXTracing.isAvailable()) {
+ WXTracing.TraceEvent traceEvent = WXTracing.newEvent("executeBundleJS", mInstanceId, -1);
+ traceEvent.traceId = mExecJSTraceId;
+ traceEvent.iid = mInstanceId;
+ traceEvent.tname = "JSThread";
+ traceEvent.ph = "B";
+ traceEvent.submit();
+ mRenderStartNanos = System.nanoTime();
+ }
+
ensureRenderArchor();
Map<String, Object> renderOptions = options;
@@ -429,7 +443,7 @@ public class WXSDKInstance implements IWXActivityStateListener,DomContext, View.
}
mWXPerformance.pageName = pageName;
- mWXPerformance.JSTemplateSize = template.length() / 1024;
+ mWXPerformance.JSTemplateSize = template.length() / 1024f;
mRenderStartTime = System.currentTimeMillis();
mRenderStrategy = flag;
@@ -1480,6 +1494,7 @@ public class WXSDKInstance implements IWXActivityStateListener,DomContext, View.
private WXRenderStrategy flag;
private WXSDKInstance instance;
private long startRequestTime;
+ private int traceId;
private WXHttpListener(String pageName, Map<String, Object> options, String jsonInitData, WXRenderStrategy flag, long startRequestTime) {
this.pageName = pageName;
@@ -1487,6 +1502,16 @@ public class WXSDKInstance implements IWXActivityStateListener,DomContext, View.
this.jsonInitData = jsonInitData;
this.flag = flag;
this.startRequestTime = startRequestTime;
+ this.traceId = WXTracing.nextId();
+
+ if (WXTracing.isAvailable()) {
+ WXTracing.TraceEvent event = WXTracing.newEvent("downloadBundleJS", mInstanceId, -1);
+ event.iid = mInstanceId;
+ event.tname = "Network";
+ event.ph = "B";
+ event.traceId = traceId;
+ event.submit();
+ }
}
public void setSDKInstance(WXSDKInstance instance) {
@@ -1526,6 +1551,16 @@ public class WXSDKInstance implements IWXActivityStateListener,DomContext, View.
this.instance.getWXStatisticsListener().onHttpFinish();
}
+ if (WXTracing.isAvailable()) {
+ WXTracing.TraceEvent event = WXTracing.newEvent("downloadBundleJS", mInstanceId, -1);
+ event.traceId = traceId;
+ event.tname = "Network";
+ event.ph = "E";
+ event.extParams = new HashMap<>();
+ event.extParams.put("BundleSize", response.originalData.length);
+ event.submit();
+ }
+
mWXPerformance.networkTime = System.currentTimeMillis() - startRequestTime;
if(response.extendParams!=null){
Object actualNetworkTime=response.extendParams.get("actualNetworkTime");
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/102f2ed0/android/sdk/src/main/java/com/taobao/weex/WXSDKManager.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/WXSDKManager.java b/android/sdk/src/main/java/com/taobao/weex/WXSDKManager.java
index 0b43fa6..84e5fa8 100644
--- a/android/sdk/src/main/java/com/taobao/weex/WXSDKManager.java
+++ b/android/sdk/src/main/java/com/taobao/weex/WXSDKManager.java
@@ -27,6 +27,7 @@ import com.taobao.weex.adapter.DefaultUriAdapter;
import com.taobao.weex.adapter.DefaultWXHttpAdapter;
import com.taobao.weex.adapter.ICrashInfoReporter;
import com.taobao.weex.adapter.IDrawableLoader;
+import com.taobao.weex.adapter.ITracingAdapter;
import com.taobao.weex.adapter.IWXDebugAdapter;
import com.taobao.weex.adapter.IWXHttpAdapter;
import com.taobao.weex.adapter.IWXImgLoaderAdapter;
@@ -83,6 +84,7 @@ public class WXSDKManager {
private IWXStatisticsListener mStatisticsListener;
private URIAdapter mURIAdapter;
private IWebSocketAdapterFactory mIWebSocketAdapterFactory;
+ private ITracingAdapter mTracingAdapter;
private WXValidateProcessor mWXValidateProcessor;
// Tell weexv8 to initialize v8, default is true.
private boolean mNeedInitV8 = true;
@@ -410,4 +412,11 @@ public class WXSDKManager {
}
}
+ public void setTracingAdapter(ITracingAdapter adapter) {
+ this.mTracingAdapter = adapter;
+ }
+
+ public ITracingAdapter getTracingAdapter() {
+ return mTracingAdapter;
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/102f2ed0/android/sdk/src/main/java/com/taobao/weex/adapter/ITracingAdapter.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/adapter/ITracingAdapter.java b/android/sdk/src/main/java/com/taobao/weex/adapter/ITracingAdapter.java
new file mode 100644
index 0000000..4acb23d
--- /dev/null
+++ b/android/sdk/src/main/java/com/taobao/weex/adapter/ITracingAdapter.java
@@ -0,0 +1,31 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package com.taobao.weex.adapter;
+
+import com.taobao.weex.tracing.WXTracing;
+
+/**
+ * Created by moxun on 2017/7/6.
+ */
+
+public interface ITracingAdapter {
+ void enable();
+ void disable();
+ void submitTracingEvent(WXTracing.TraceEvent event);
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/102f2ed0/android/sdk/src/main/java/com/taobao/weex/bridge/WXBridgeManager.java
----------------------------------------------------------------------
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 2e8e928..2d533ea 100644
--- a/android/sdk/src/main/java/com/taobao/weex/bridge/WXBridgeManager.java
+++ b/android/sdk/src/main/java/com/taobao/weex/bridge/WXBridgeManager.java
@@ -51,6 +51,8 @@ import com.taobao.weex.dom.DOMAction;
import com.taobao.weex.dom.WXDomModule;
import com.taobao.weex.dom.action.Action;
import com.taobao.weex.dom.action.Actions;
+import com.taobao.weex.dom.action.TraceableAction;
+import com.taobao.weex.tracing.WXTracing;
import com.taobao.weex.utils.WXFileUtils;
import com.taobao.weex.utils.WXJsonUtils;
import com.taobao.weex.utils.WXLogUtils;
@@ -157,6 +159,8 @@ public class WXBridgeManager implements Callback,BactchExecutor {
private Interceptor mInterceptor;
+ private WXParams mInitParams;
+
private WXBridgeManager() {
initWXBridge(WXEnvironment.sRemoteDebugMode);
mJSThread = new WXThread("WeexJSBridgeThread", this);
@@ -394,7 +398,9 @@ public class WXBridgeManager implements Callback,BactchExecutor {
long start = System.currentTimeMillis();
+ long parseNanos = System.nanoTime();
JSONArray array = JSON.parseArray(tasks);
+ parseNanos = System.nanoTime() - parseNanos;
if(WXSDKManager.getInstance().getSDKInstance(instanceId)!=null) {
WXSDKManager.getInstance().getSDKInstance(instanceId).jsonParseTime(System.currentTimeMillis() - start);
@@ -411,7 +417,7 @@ public class WXBridgeManager implements Callback,BactchExecutor {
if(target != null){
if(WXDomModule.WXDOM.equals(target)){
WXDomModule dom = getDomModule(instanceId);
- dom.callDomMethod(task);
+ dom.callDomMethod(task,parseNanos);
}else {
callModuleMethod(instanceId, (String) target,
(String) task.get(METHOD), (JSONArray) task.get(ARGS));
@@ -463,10 +469,20 @@ public class WXBridgeManager implements Callback,BactchExecutor {
try {
if (WXSDKManager.getInstance().getSDKInstance(instanceId) != null) {
+ long start = System.currentTimeMillis();
+ long nanosTemp = System.nanoTime();
JSONObject domObject = JSON.parseObject(tasks);
+ nanosTemp = System.nanoTime() - nanosTemp;
+
WXDomModule domModule = getDomModule(instanceId);
Action action = Actions.getCreateBody(domObject);
domModule.postAction((DOMAction)action, true);
+
+ if (WXTracing.isAvailable() && action instanceof TraceableAction) {
+ ((TraceableAction) action).mParseJsonNanos = nanosTemp;
+ ((TraceableAction) action).mStartMillis = start;
+ ((TraceableAction) action).onStartDomExecute(instanceId, "createBody", "_root", domObject.getString("type"), tasks);
+ }
}
} catch (Exception e) {
WXLogUtils.e("[WXBridgeManager] callCreateBody exception: ", e);
@@ -605,9 +621,19 @@ public class WXBridgeManager implements Callback,BactchExecutor {
try {
if (WXSDKManager.getInstance().getSDKInstance(instanceId) != null) {
WXDomModule domModule = getDomModule(instanceId);
+ long start = System.currentTimeMillis();
+ long parseNanos = System.nanoTime();
JSONObject domObject = JSON.parseObject(task);
+ parseNanos = System.nanoTime() - parseNanos;
+
Action action = Actions.getUpdateAttrs(ref, domObject);
domModule.postAction((DOMAction)action, false);
+
+ if (WXTracing.isAvailable() && action instanceof TraceableAction) {
+ ((TraceableAction) action).mStartMillis = start;
+ ((TraceableAction) action).mParseJsonNanos = parseNanos;
+ ((TraceableAction) action).onStartDomExecute(instanceId, "updateAttrs", domObject.getString("ref"), domObject.getString("type"), task);
+ }
}
} catch (Exception e) {
WXLogUtils.e("[WXBridgeManager] callUpdateAttrs exception: ", e);
@@ -648,9 +674,19 @@ public class WXBridgeManager implements Callback,BactchExecutor {
try {
if (WXSDKManager.getInstance().getSDKInstance(instanceId) != null) {
WXDomModule domModule = getDomModule(instanceId);
+ long start = System.currentTimeMillis();
+ long nanosTemp = System.nanoTime();
JSONObject domObject = JSON.parseObject(task);
+ nanosTemp = System.nanoTime() - nanosTemp;
+
Action action = Actions.getUpdateStyle(ref, domObject, false);
domModule.postAction((DOMAction)action, false);
+
+ if (WXTracing.isAvailable() && action instanceof TraceableAction) {
+ ((TraceableAction) action).mParseJsonNanos = nanosTemp;
+ ((TraceableAction) action).mStartMillis = start;
+ ((TraceableAction) action).onStartDomExecute(instanceId, "updateStyle", ref, domObject.getString("type"), domObject.toJSONString());
+ }
}
} catch (Exception e) {
WXLogUtils.e("[WXBridgeManager] callUpdateStyle exception: ", e);
@@ -684,6 +720,10 @@ public class WXBridgeManager implements Callback,BactchExecutor {
WXDomModule domModule = getDomModule(instanceId);
Action action = Actions.getRemoveElement(ref);
domModule.postAction((DOMAction)action, false);
+
+ if (WXTracing.isAvailable() && action instanceof TraceableAction) {
+ ((TraceableAction) action).onStartDomExecute(instanceId, "removeElement", ref, null, ref);
+ }
}
} catch (Exception e) {
WXLogUtils.e("[WXBridgeManager] callRemoveElement exception: ", e);
@@ -752,6 +792,10 @@ public class WXBridgeManager implements Callback,BactchExecutor {
WXDomModule domModule = getDomModule(instanceId);
Action action = Actions.getAddEvent(ref, event);
domModule.postAction((DOMAction)action, false);
+
+ if (WXTracing.isAvailable() && action instanceof TraceableAction) {
+ ((TraceableAction) action).onStartDomExecute(instanceId, "addEvent", ref, null, event);
+ }
}
} catch (Exception e) {
WXLogUtils.e("[WXBridgeManager] callAddEvent exception: ", e);
@@ -785,6 +829,10 @@ public class WXBridgeManager implements Callback,BactchExecutor {
WXDomModule domModule = getDomModule(instanceId);
Action action = Actions.getRemoveEvent(ref, event);
domModule.postAction((DOMAction)action, false);
+
+ if (WXTracing.isAvailable() && action instanceof TraceableAction) {
+ ((TraceableAction) action).onStartDomExecute(instanceId, "removeEvent", ref, null, event);
+ }
}
} catch (Exception e) {
WXLogUtils.e("[WXBridgeManager] callRemoveEvent exception: ", e);
@@ -815,13 +863,22 @@ public class WXBridgeManager implements Callback,BactchExecutor {
if (WXSDKManager.getInstance().getSDKInstance(instanceId) != null) {
long start = System.currentTimeMillis();
+ long nanosTemp = System.nanoTime();
JSONObject domObject = JSON.parseObject(dom);
+ nanosTemp = System.nanoTime() - nanosTemp;
if (WXSDKManager.getInstance().getSDKInstance(instanceId) != null) {
WXSDKManager.getInstance().getSDKInstance(instanceId).jsonParseTime(System.currentTimeMillis() - start);
}
WXDomModule domModule = getDomModule(instanceId);
- domModule.postAction(Actions.getAddElement(domObject, ref,Integer.parseInt(index)),false);
+ DOMAction addElementAction = Actions.getAddElement(domObject, ref,Integer.parseInt(index));
+ domModule.postAction(addElementAction, false);
+
+ if (WXTracing.isAvailable() && addElementAction instanceof TraceableAction) {
+ ((TraceableAction) addElementAction).mParseJsonNanos = nanosTemp;
+ ((TraceableAction) addElementAction).mStartMillis = start;
+ ((TraceableAction) addElementAction).onStartDomExecute(instanceId, "addElement", domObject.getString("ref"), domObject.getString("type"), dom);
+ }
}
if (UNDEFINED.equals(callback) || NON_CALLBACK.equals(callback)) {
@@ -1368,9 +1425,14 @@ public class WXBridgeManager implements Callback,BactchExecutor {
wxParams.setDeviceHeight(TextUtils.isEmpty(config.get("deviceHeight")) ? String.valueOf(WXViewUtils.getScreenHeight(WXEnvironment.sApplication)) : config.get("deviceHeight"));
wxParams.setOptions(WXEnvironment.getCustomOptions());
wxParams.setNeedInitV8(WXSDKManager.getInstance().needInitV8());
+ mInitParams = wxParams;
return wxParams;
}
+ public WXParams getInitParams() {
+ return mInitParams;
+ }
+
private void execRegisterFailTask() {
if (mRegisterModuleFailList.size() > 0) {
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/102f2ed0/android/sdk/src/main/java/com/taobao/weex/common/WXTracing.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/common/WXTracing.java b/android/sdk/src/main/java/com/taobao/weex/common/WXTracing.java
deleted file mode 100644
index bc37386..0000000
--- a/android/sdk/src/main/java/com/taobao/weex/common/WXTracing.java
+++ /dev/null
@@ -1,76 +0,0 @@
-package com.taobao.weex.common;
-
-import android.os.Message;
-
-import com.taobao.weex.dom.WXDomHandler;
-import com.taobao.weex.dom.WXDomTask;
-import com.taobao.weex.dom.action.Action;
-import com.taobao.weex.utils.WXLogUtils;
-
-import java.util.concurrent.atomic.AtomicInteger;
-
-/**
- * Created by moxun on 2017/6/6.
- */
-
-public class WXTracing {
- private static final AtomicInteger sIdGenerator = new AtomicInteger(0);
-
- public static int nextId() {
- return sIdGenerator.getAndIncrement();
- }
-
- public static void submit(TraceEvent event) {
- WXLogUtils.d("WXTracing", event.toString());
- }
-
- public static class TraceEvent {
- public String name;
- public String phase;
- public String threadName;
- public long timestamp;
- public long nanoTime;
- public long duration;
-
- @Override
- public String toString() {
- final StringBuffer sb = new StringBuffer("TraceEvent{");
- sb.append("name='").append(name).append('\'');
- sb.append(", threadName='").append(threadName).append('\'');
- sb.append(", phase='").append(phase).append('\'');
- sb.append(", timestamp=").append(timestamp);
- sb.append(", nanoTime=").append(nanoTime);
- sb.append(", duration=").append(duration);
- sb.append('}');
- return sb.toString();
- }
- }
-
- public static String getFunctionName(Message msg) {
- Object obj = msg.obj;
- if (obj != null && obj instanceof WXDomTask) {
- Object action = ((WXDomTask) obj).args.get(0);
- if (action instanceof Action) {
- return getFunctionName(action.getClass());
- }
- }
-
- String actionName = "unknown";
- int what = msg.what;
- if (what == WXDomHandler.MsgType.WX_DOM_BATCH) {
- actionName = "domBatch";
- } else if (what == WXDomHandler.MsgType.WX_DOM_UPDATE_STYLE) {
- actionName = "updateStyle";
- } else if (what == WXDomHandler.MsgType.WX_CONSUME_RENDER_TASKS) {
- actionName = "consumeRenderTasks";
- }
- return actionName;
- }
-
- public static String getFunctionName(Class clazz) {
- String simpleName = clazz.getSimpleName();
- char[] chars = simpleName.replace("Action", "").toCharArray();
- chars[0] = Character.toLowerCase(chars[0]);
- return new String(chars);
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/102f2ed0/android/sdk/src/main/java/com/taobao/weex/dom/DOMActionContextImpl.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/dom/DOMActionContextImpl.java b/android/sdk/src/main/java/com/taobao/weex/dom/DOMActionContextImpl.java
index 6e1e385..d18cea8 100644
--- a/android/sdk/src/main/java/com/taobao/weex/dom/DOMActionContextImpl.java
+++ b/android/sdk/src/main/java/com/taobao/weex/dom/DOMActionContextImpl.java
@@ -26,12 +26,13 @@ import com.taobao.weex.WXSDKInstance;
import com.taobao.weex.WXSDKManager;
import com.taobao.weex.dom.action.Actions;
import com.taobao.weex.dom.flex.CSSLayoutContext;
+import com.taobao.weex.tracing.Stopwatch;
+import com.taobao.weex.tracing.WXTracing;
import com.taobao.weex.ui.IWXRenderTask;
import com.taobao.weex.ui.WXRenderManager;
import com.taobao.weex.ui.animation.WXAnimationBean;
import com.taobao.weex.ui.component.WXComponent;
import com.taobao.weex.ui.component.WXVContainer;
-import com.taobao.weex.utils.Stopwatch;
import com.taobao.weex.utils.WXLogUtils;
import java.util.ArrayList;
@@ -172,9 +173,18 @@ class DOMActionContextImpl implements DOMActionContext {
if (!mDirty || mDestroy) {
return;
}
-
+ long start = System.currentTimeMillis();
+ long startNanos = System.nanoTime();
WXDomObject rootDom = mRegistry.get(WXDomObject.ROOT);
layout(rootDom);
+
+ if (WXTracing.isAvailable()) {
+ WXTracing.TraceEvent batchEvent = WXTracing.newEvent("domBatch", mInstanceId, -1);
+ batchEvent.duration = Stopwatch.nanosToMillis(System.nanoTime() - startNanos);
+ batchEvent.ts = start;
+ batchEvent.ph = "X";
+ WXTracing.submit(batchEvent);
+ }
}
void layout(WXDomObject rootDom) {
@@ -182,9 +192,7 @@ class DOMActionContextImpl implements DOMActionContext {
return;
}
long start0 = System.currentTimeMillis();
- Stopwatch.tick();
rebuildingFixedDomTree(rootDom);
- WXLogUtils.e("Tracing", "rebuildingFixedDomTree " + Stopwatch.tackAndTick() + " ms");
rootDom.traverseTree( new WXDomObject.Consumer() {
@Override
@@ -195,13 +203,9 @@ class DOMActionContextImpl implements DOMActionContext {
dom.layoutBefore();
}
});
- WXLogUtils.e("Tracing", "layoutBefore " + Stopwatch.tackAndTick() + " ms");
long start = System.currentTimeMillis();
-
- long s = System.nanoTime();
rootDom.calculateLayout(mLayoutContext);
- WXLogUtils.e("Tracing", "layout " + Stopwatch.tackAndTick() + " ms");
WXSDKInstance instance = WXSDKManager.getInstance().getSDKInstance(mInstanceId);
if (instance != null) {
@@ -217,11 +221,9 @@ class DOMActionContextImpl implements DOMActionContext {
dom.layoutAfter();
}
});
- WXLogUtils.e("Tracing", "layoutAfter " + Stopwatch.tackAndTick() + " ms");
start = System.currentTimeMillis();
rootDom.traverseTree(new ApplyUpdateConsumer());
- WXLogUtils.e("Tracing", "applyUpdateConsumer " + Stopwatch.tackAndTick() + " ms");
if (instance != null) {
instance.applyUpdateTime(System.currentTimeMillis() - start);
@@ -232,7 +234,6 @@ class DOMActionContextImpl implements DOMActionContext {
if (instance != null) {
instance.updateDomObjTime(System.currentTimeMillis() - start);
}
- WXLogUtils.e("Tracing", "updateDomObj " + Stopwatch.tack() + " ms");
parseAnimation();
boolean isPreRenderMode = instance != null && instance.isPreRenderMode();
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/102f2ed0/android/sdk/src/main/java/com/taobao/weex/dom/RenderActionTask.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/dom/RenderActionTask.java b/android/sdk/src/main/java/com/taobao/weex/dom/RenderActionTask.java
index 28b487f..bac1574 100644
--- a/android/sdk/src/main/java/com/taobao/weex/dom/RenderActionTask.java
+++ b/android/sdk/src/main/java/com/taobao/weex/dom/RenderActionTask.java
@@ -18,6 +18,12 @@
*/
package com.taobao.weex.dom;
+import android.os.SystemClock;
+
+import com.taobao.weex.dom.action.AbstractAddElementAction;
+import com.taobao.weex.dom.action.TraceableAction;
+import com.taobao.weex.tracing.Stopwatch;
+import com.taobao.weex.tracing.WXTracing;
import com.taobao.weex.ui.IWXRenderTask;
/**
@@ -27,15 +33,33 @@ import com.taobao.weex.ui.IWXRenderTask;
class RenderActionTask implements IWXRenderTask {
private final RenderAction mRenderTask;
private final RenderActionContext mContext;
+ private final long mStartMillis = SystemClock.uptimeMillis();
public RenderActionTask(RenderAction action, RenderActionContext context){
mRenderTask = action;
mContext = context;
}
-
@Override
public void execute() {
+ if (WXTracing.isAvailable() && mRenderTask instanceof TraceableAction) {
+ ((TraceableAction) mRenderTask).mUIQueueTime = SystemClock.uptimeMillis() - mStartMillis;
+ }
+ long start = System.currentTimeMillis();
+ long uiNanos = System.nanoTime();
mRenderTask.executeRender(mContext);
+
+ if (WXTracing.isAvailable()) {
+ uiNanos = System.nanoTime() - uiNanos;
+ if (mRenderTask instanceof TraceableAction) {
+ if (!(mRenderTask instanceof AbstractAddElementAction)) {
+ WXTracing.TraceEvent uiExecuteEvent = WXTracing.newEvent("UIExecute", mContext.getInstance().getInstanceId(), ((TraceableAction) mRenderTask).mTracingEventId);
+ uiExecuteEvent.duration = Stopwatch.nanosToMillis(uiNanos);
+ uiExecuteEvent.ts = start;
+ uiExecuteEvent.submit();
+ }
+ ((TraceableAction) mRenderTask).onFinishUIExecute();
+ }
+ }
}
}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/102f2ed0/android/sdk/src/main/java/com/taobao/weex/dom/WXDomHandler.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/dom/WXDomHandler.java b/android/sdk/src/main/java/com/taobao/weex/dom/WXDomHandler.java
index 03f6940..ca79066 100644
--- a/android/sdk/src/main/java/com/taobao/weex/dom/WXDomHandler.java
+++ b/android/sdk/src/main/java/com/taobao/weex/dom/WXDomHandler.java
@@ -23,9 +23,8 @@ import android.os.Message;
import android.os.SystemClock;
import com.alibaba.fastjson.JSONObject;
-import com.taobao.weex.common.WXTracing;
import com.taobao.weex.dom.action.Actions;
-import com.taobao.weex.utils.WXLogUtils;
+import com.taobao.weex.dom.action.TraceableAction;
/**
* Handler for dom operations.
@@ -45,8 +44,6 @@ public class WXDomHandler implements Handler.Callback {
@Override
public boolean handleMessage(Message msg) {
- long s = System.nanoTime();
- String actionName = WXTracing.getFunctionName(msg);
if (msg == null) {
return false;
}
@@ -54,11 +51,12 @@ public class WXDomHandler implements Handler.Callback {
Object obj = msg.obj;
WXDomTask task = null;
- if (obj instanceof WXDomTask) {
+ if (obj != null && obj instanceof WXDomTask) {
task = (WXDomTask) obj;
- WXLogUtils.e("Tracing", "Method " + actionName + ", Queue time " + ((s - task.startTime) / 1000000.0) + " ms");
- } else {
- WXLogUtils.e("Tracing", "Method " + actionName + ", Queue time " + (SystemClock.uptimeMillis() - msg.getWhen()) + " ms");
+ Object action = ((WXDomTask) obj).args.get(0);
+ if (action != null && action instanceof TraceableAction) {
+ ((TraceableAction) action).mDomQueueTime = SystemClock.uptimeMillis() - msg.getWhen();
+ }
}
if (!mHasBatch) {
@@ -86,7 +84,6 @@ public class WXDomHandler implements Handler.Callback {
default:
break;
}
- WXLogUtils.e("Tracing", "Method " + actionName + ", Dom execute time " + ((System.nanoTime() - s) / 1000000.0) + " ms");
return true;
}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/102f2ed0/android/sdk/src/main/java/com/taobao/weex/dom/WXDomManager.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/dom/WXDomManager.java b/android/sdk/src/main/java/com/taobao/weex/dom/WXDomManager.java
index fe8866b..66fd56e 100644
--- a/android/sdk/src/main/java/com/taobao/weex/dom/WXDomManager.java
+++ b/android/sdk/src/main/java/com/taobao/weex/dom/WXDomManager.java
@@ -26,6 +26,10 @@ import com.taobao.weex.WXEnvironment;
import com.taobao.weex.WXSDKManager;
import com.taobao.weex.common.WXRuntimeException;
import com.taobao.weex.common.WXThread;
+import com.taobao.weex.dom.action.AbstractAddElementAction;
+import com.taobao.weex.dom.action.TraceableAction;
+import com.taobao.weex.tracing.Stopwatch;
+import com.taobao.weex.tracing.WXTracing;
import com.taobao.weex.ui.WXRenderManager;
import com.taobao.weex.utils.WXUtils;
@@ -160,8 +164,18 @@ public final class WXDomManager {
return;
}
}
+ long domStart = System.currentTimeMillis();
+ long domNanos = System.nanoTime();
action.executeDom(context);
-
+ if (WXTracing.isAvailable()) {
+ domNanos = System.nanoTime() - domNanos;
+ if (!(action instanceof AbstractAddElementAction) && action instanceof TraceableAction) {
+ WXTracing.TraceEvent domExecuteEvent = WXTracing.newEvent("DomExecute", context.getInstanceId(), ((TraceableAction) action).mTracingEventId);
+ domExecuteEvent.duration = Stopwatch.nanosToMillis(domNanos);
+ domExecuteEvent.ts = domStart;
+ domExecuteEvent.submit();
+ }
+ }
}
/**
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/102f2ed0/android/sdk/src/main/java/com/taobao/weex/dom/WXDomModule.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/dom/WXDomModule.java b/android/sdk/src/main/java/com/taobao/weex/dom/WXDomModule.java
index 2d44561..399ab3a 100644
--- a/android/sdk/src/main/java/com/taobao/weex/dom/WXDomModule.java
+++ b/android/sdk/src/main/java/com/taobao/weex/dom/WXDomModule.java
@@ -26,6 +26,9 @@ import com.taobao.weex.bridge.WXBridgeManager;
import com.taobao.weex.common.WXModule;
import com.taobao.weex.dom.action.Action;
import com.taobao.weex.dom.action.Actions;
+import com.taobao.weex.dom.action.TraceableAction;
+import com.taobao.weex.tracing.Stopwatch;
+import com.taobao.weex.tracing.WXTracing;
import com.taobao.weex.utils.WXLogUtils;
@@ -76,16 +79,16 @@ public final class WXDomModule extends WXModule {
mWXSDKInstance = instance;
}
- public void callDomMethod(JSONObject task) {
+ public void callDomMethod(JSONObject task, long... parseNanos) {
if (task == null) {
return;
}
String method = (String) task.get(WXBridgeManager.METHOD);
JSONArray args = (JSONArray) task.get(WXBridgeManager.ARGS);
- callDomMethod(method,args);
+ callDomMethod(method,args,parseNanos);
}
- public Object callDomMethod(String method, JSONArray args) {
+ public Object callDomMethod(String method, JSONArray args, long... parseNanos) {
if (method == null) {
return null;
@@ -102,6 +105,34 @@ public final class WXDomModule extends WXModule {
}else {
postAction((RenderAction)action);
}
+
+ if (WXTracing.isAvailable() && action instanceof TraceableAction) {
+ //TODO: CHECK AGAIN
+ String ref = null;
+ String type = null;
+ if (args.size() > 0) {
+ if (args.size() >= 1) {
+ if (args.get(0) instanceof String) {
+ ref = args.getString(0);
+ } else if (args.get(0) instanceof JSONObject) {
+ ref = ((JSONObject) args.get(0)).getString("ref");
+ type = ((JSONObject) args.get(0)).getString("type");
+ }
+ }
+
+ if (args.size() >= 2) {
+ if (args.get(1) instanceof JSONObject) {
+ ref = ((JSONObject) args.get(1)).getString("ref");
+ type = ((JSONObject) args.get(1)).getString("type");
+ }
+ }
+ }
+ if (parseNanos != null && parseNanos.length == 1) {
+ ((TraceableAction) action).mParseJsonNanos = parseNanos[0];
+ ((TraceableAction) action).mStartMillis -= Stopwatch.nanosToMillis(parseNanos[0]);
+ }
+ ((TraceableAction) action).onStartDomExecute(mWXSDKInstance.getInstanceId(), method, ref, type, args.toJSONString());
+ }
} catch (IndexOutOfBoundsException e) {
// no enougn args
e.printStackTrace();
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/102f2ed0/android/sdk/src/main/java/com/taobao/weex/dom/WXDomObject.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/dom/WXDomObject.java b/android/sdk/src/main/java/com/taobao/weex/dom/WXDomObject.java
index 641c95a..258df2b 100644
--- a/android/sdk/src/main/java/com/taobao/weex/dom/WXDomObject.java
+++ b/android/sdk/src/main/java/com/taobao/weex/dom/WXDomObject.java
@@ -86,7 +86,11 @@ public class WXDomObject extends CSSNode implements Cloneable,ImmutableDomObject
private boolean mYoung = false;
+ public long mDomThreadNanos;
+ public long mDomThreadTimestamp;
+
public void traverseTree(Consumer...consumers){
+ long startNanos = System.nanoTime();
if (consumers == null) {
return;
}
@@ -101,6 +105,7 @@ public class WXDomObject extends CSSNode implements Cloneable,ImmutableDomObject
child = getChild(i);
child.traverseTree(consumers);
}
+ mDomThreadNanos += (System.nanoTime() - startNanos);
}
@@ -628,6 +633,8 @@ public class WXDomObject extends CSSNode implements Cloneable,ImmutableDomObject
* @return Dom Object corresponding to the JSONObject.
*/
public static @Nullable WXDomObject parse(JSONObject json, WXSDKInstance wxsdkInstance){
+ long startNanos = System.nanoTime();
+ long timestamp = System.currentTimeMillis();
if (json == null || json.size() <= 0) {
return null;
}
@@ -671,6 +678,8 @@ public class WXDomObject extends CSSNode implements Cloneable,ImmutableDomObject
}
}
+ domObject.mDomThreadNanos = System.nanoTime() - startNanos;
+ domObject.mDomThreadTimestamp = timestamp;
return domObject;
}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/102f2ed0/android/sdk/src/main/java/com/taobao/weex/dom/action/AbstractAddElementAction.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/dom/action/AbstractAddElementAction.java b/android/sdk/src/main/java/com/taobao/weex/dom/action/AbstractAddElementAction.java
index b3b27a6..3b2d964 100644
--- a/android/sdk/src/main/java/com/taobao/weex/dom/action/AbstractAddElementAction.java
+++ b/android/sdk/src/main/java/com/taobao/weex/dom/action/AbstractAddElementAction.java
@@ -28,24 +28,30 @@ import com.taobao.weex.dom.DOMAction;
import com.taobao.weex.dom.DOMActionContext;
import com.taobao.weex.dom.RenderAction;
import com.taobao.weex.dom.WXDomObject;
+import com.taobao.weex.tracing.Stopwatch;
+import com.taobao.weex.tracing.WXTracing;
import com.taobao.weex.ui.component.WXComponent;
import com.taobao.weex.ui.component.WXComponentFactory;
import com.taobao.weex.ui.component.WXVContainer;
-import com.taobao.weex.utils.Stopwatch;
import com.taobao.weex.utils.WXLogUtils;
+import java.util.List;
+
/**
* Created by sospartan on 22/02/2017.
*/
-abstract class AbstractAddElementAction implements DOMAction, RenderAction {
-
+public abstract class AbstractAddElementAction extends TraceableAction implements DOMAction, RenderAction {
protected WXComponent generateComponentTree(DOMActionContext context, WXDomObject dom, WXVContainer parent) {
if (dom == null) {
return null;
}
+ long startNanos = System.nanoTime();
WXComponent component = WXComponentFactory.newInstance(context.getInstance(), dom, parent);
+ component.mTraceInfo.domThreadStart = dom.mDomThreadTimestamp;
+ component.mTraceInfo.rootEventId = mTracingEventId;
+ component.mTraceInfo.domQueueTime = mDomQueueTime;
context.registerComponent(dom.getRef(), component);
if (component instanceof WXVContainer) {
@@ -59,7 +65,7 @@ abstract class AbstractAddElementAction implements DOMAction, RenderAction {
}
}
}
-
+ component.mTraceInfo.domThreadNanos = System.nanoTime() - startNanos;
return component;
}
@@ -83,7 +89,7 @@ abstract class AbstractAddElementAction implements DOMAction, RenderAction {
//only non-root has parent.
Stopwatch.tick();
WXDomObject domObject = WXDomObject.parse(dom, instance);
- WXLogUtils.e("Tracing", "Component " + domObject.getRef() + " parseDomObject " + Stopwatch.tackAndTick() + " ms");
+ Stopwatch.split("parseDomObject");
if (domObject == null || context.getDomByRef(domObject.getRef()) != null) {
if (WXEnvironment.isApkDebugable()) {
@@ -93,13 +99,13 @@ abstract class AbstractAddElementAction implements DOMAction, RenderAction {
return;
}
appendDomToTree(context, domObject);
- WXLogUtils.e("Tracing", "Component " + domObject.getRef() + " appendDomToTree " + Stopwatch.tackAndTick() + " ms");
+ Stopwatch.split("appendDomToTree");
domObject.traverseTree(
context.getAddDOMConsumer(),
context.getApplyStyleConsumer()
);
- WXLogUtils.e("Tracing", "Component " + domObject.getRef() + " traverseTree " + Stopwatch.tackAndTick() + " ms");
+ Stopwatch.split("traverseTree");
//Create component in dom thread
@@ -109,13 +115,19 @@ abstract class AbstractAddElementAction implements DOMAction, RenderAction {
//stop redner, some fatal happened.
return;
}
- WXLogUtils.e("Tracing", "Component " + domObject.getRef() + " createComponent " + Stopwatch.tackAndTick() + " ms");
+ Stopwatch.split("createComponent");
context.addDomInfo(domObject.getRef(), component);
context.postRenderTask(this);
addAnimationForDomTree(context, domObject);
instance.commitUTStab(IWXUserTrackAdapter.DOM_MODULE, WXErrorCode.WX_SUCCESS);
+ if (WXTracing.isAvailable()) {
+ List<Stopwatch.ProcessEvent> events = Stopwatch.getProcessEvents();
+ for (Stopwatch.ProcessEvent event : events) {
+ submitPerformance(event.fname, "X", context.getInstanceId(), event.duration, event.startMillis, true);
+ }
+ }
}
public void addAnimationForDomTree(DOMActionContext context, WXDomObject domObject) {
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/102f2ed0/android/sdk/src/main/java/com/taobao/weex/dom/action/AbstractLayoutFinishAction.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/dom/action/AbstractLayoutFinishAction.java b/android/sdk/src/main/java/com/taobao/weex/dom/action/AbstractLayoutFinishAction.java
index 120e56c..a16f27a 100644
--- a/android/sdk/src/main/java/com/taobao/weex/dom/action/AbstractLayoutFinishAction.java
+++ b/android/sdk/src/main/java/com/taobao/weex/dom/action/AbstractLayoutFinishAction.java
@@ -21,7 +21,6 @@ package com.taobao.weex.dom.action;
import com.taobao.weex.WXSDKInstance;
import com.taobao.weex.adapter.IWXUserTrackAdapter;
import com.taobao.weex.common.WXErrorCode;
-import com.taobao.weex.common.WXRenderStrategy;
import com.taobao.weex.dom.DOMAction;
import com.taobao.weex.dom.DOMActionContext;
import com.taobao.weex.dom.RenderAction;
@@ -30,7 +29,7 @@ import com.taobao.weex.dom.WXDomObject;
/**
* Created by sospartan on 02/03/2017.
*/
-abstract class AbstractLayoutFinishAction implements DOMAction, RenderAction {
+abstract class AbstractLayoutFinishAction extends TraceableAction implements DOMAction, RenderAction {
protected int mLayoutWidth;
protected int mLayoutHeight;
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/102f2ed0/android/sdk/src/main/java/com/taobao/weex/dom/action/AddElementAction.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/dom/action/AddElementAction.java b/android/sdk/src/main/java/com/taobao/weex/dom/action/AddElementAction.java
index a4b3adf..e8b3721 100644
--- a/android/sdk/src/main/java/com/taobao/weex/dom/action/AddElementAction.java
+++ b/android/sdk/src/main/java/com/taobao/weex/dom/action/AddElementAction.java
@@ -25,11 +25,14 @@ import com.taobao.weex.common.WXErrorCode;
import com.taobao.weex.dom.DOMActionContext;
import com.taobao.weex.dom.RenderActionContext;
import com.taobao.weex.dom.WXDomObject;
+import com.taobao.weex.tracing.Stopwatch;
+import com.taobao.weex.tracing.WXTracing;
import com.taobao.weex.ui.component.WXComponent;
import com.taobao.weex.ui.component.WXVContainer;
-import com.taobao.weex.utils.Stopwatch;
import com.taobao.weex.utils.WXLogUtils;
+import java.util.List;
+
/**
* Created by sospartan on 22/02/2017.
*/
@@ -59,6 +62,7 @@ final class AddElementAction extends AbstractAddElementAction {
@Override
protected void appendDomToTree(DOMActionContext context, WXDomObject domObject) {
+ long startNanos = System.nanoTime();
WXDomObject parent;
mRef = domObject.getRef();
if ((parent = context.getDomByRef(mParentRef)) == null) {
@@ -68,6 +72,7 @@ final class AddElementAction extends AbstractAddElementAction {
//non-root and parent exist
parent.add(domObject, mAddIndex);
}
+ domObject.mDomThreadNanos += (System.nanoTime() - startNanos);
}
@Override
@@ -98,14 +103,31 @@ final class AddElementAction extends AbstractAddElementAction {
if (parent == null || component == null) {
return;
}
+
Stopwatch.tick();
parent.addChild(component, mAddIndex);
parent.createChildViewAt(mAddIndex);
- WXLogUtils.e("Tracing", "Component " + mRef + " createViewTree " + Stopwatch.tackAndTick() + " ms");
+ Stopwatch.split("createViewTree");
+
component.applyLayoutAndEvent(component);
- WXLogUtils.e("Tracing", "Component " + mRef + " applyLayoutAndEvent " + Stopwatch.tackAndTick() + " ms");
+ Stopwatch.split("applyLayoutAndEvent");
+
component.bindData(component);
- WXLogUtils.e("Tracing", "Component " + mRef + " bindData " + Stopwatch.tackAndTick() + " ms");
+ Stopwatch.split("bindData");
+
+ if (WXTracing.isAvailable()) {
+ String instanceId = context.getInstance().getInstanceId();
+ List<Stopwatch.ProcessEvent> splits = Stopwatch.getProcessEvents();
+ for (Stopwatch.ProcessEvent event : splits) {
+ submitPerformance(event.fname, "X", instanceId, event.duration, event.startMillis, true);
+ }
+ }
+ component.mTraceInfo.uiQueueTime = mUIQueueTime;
+ if (component.isLazy()) {
+ component.onRenderFinish(WXComponent.STATE_DOM_FINISH);
+ } else {
+ component.onRenderFinish(WXComponent.STATE_ALL_FINISH);
+ }
} catch (Exception e) {
WXLogUtils.e("add component failed.", e);
}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/102f2ed0/android/sdk/src/main/java/com/taobao/weex/dom/action/AddEventAction.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/dom/action/AddEventAction.java b/android/sdk/src/main/java/com/taobao/weex/dom/action/AddEventAction.java
index e051917..e0ee886 100644
--- a/android/sdk/src/main/java/com/taobao/weex/dom/action/AddEventAction.java
+++ b/android/sdk/src/main/java/com/taobao/weex/dom/action/AddEventAction.java
@@ -26,14 +26,16 @@ import com.taobao.weex.dom.DOMActionContext;
import com.taobao.weex.dom.RenderAction;
import com.taobao.weex.dom.RenderActionContext;
import com.taobao.weex.dom.WXDomObject;
+import com.taobao.weex.tracing.Stopwatch;
+import com.taobao.weex.tracing.WXTracing;
import com.taobao.weex.ui.component.WXComponent;
-import com.taobao.weex.utils.Stopwatch;
-import com.taobao.weex.utils.WXLogUtils;
+
+import java.util.List;
/**
* Created by sospartan on 01/03/2017.
*/
-class AddEventAction implements DOMAction, RenderAction {
+class AddEventAction extends TraceableAction implements DOMAction, RenderAction {
private final String mRef;
private final String mEvent;
@@ -49,6 +51,8 @@ class AddEventAction implements DOMAction, RenderAction {
if (context.isDestory()) {
return;
}
+
+ Stopwatch.tick();
WXSDKInstance instance = context.getInstance();
WXDomObject domObject = context.getDomByRef(mRef);
if (domObject == null) {
@@ -59,6 +63,11 @@ class AddEventAction implements DOMAction, RenderAction {
}
domObject.addEvent(mEvent);
mUpdatedDom = domObject;
+
+ if (WXTracing.isAvailable() && mBeginEvent != null) {
+ submitPerformance("addEventToDom", "X", instance.getInstanceId(), Stopwatch.tack(), Stopwatch.lastTickStamp(), true);
+ }
+
context.postRenderTask(this);
if (instance != null) {
@@ -73,9 +82,17 @@ class AddEventAction implements DOMAction, RenderAction {
//sync dom change to component
Stopwatch.tick();
comp.updateDom(mUpdatedDom);
- WXLogUtils.e("Tracing", "updateDom " + Stopwatch.tackAndTick() + " ms");
+ Stopwatch.split("updateDom");
+
comp.addEvent(mEvent);
- WXLogUtils.e("Tracing", "addEvent " + Stopwatch.tackAndTick() + " ms");
+ Stopwatch.split("addEventToComponent");
+
+ if (WXTracing.isAvailable() && mBeginEvent != null) {
+ List<Stopwatch.ProcessEvent> events = Stopwatch.getProcessEvents();
+ for (Stopwatch.ProcessEvent event : events) {
+ submitPerformance(event.fname, "X", comp.getInstanceId(), event.duration, event.startMillis, true);
+ }
+ }
}
}
}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/102f2ed0/android/sdk/src/main/java/com/taobao/weex/dom/action/CreateBodyAction.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/dom/action/CreateBodyAction.java b/android/sdk/src/main/java/com/taobao/weex/dom/action/CreateBodyAction.java
index c7ac391..8c4df7d 100644
--- a/android/sdk/src/main/java/com/taobao/weex/dom/action/CreateBodyAction.java
+++ b/android/sdk/src/main/java/com/taobao/weex/dom/action/CreateBodyAction.java
@@ -30,6 +30,8 @@ import com.taobao.weex.common.WXRenderStrategy;
import com.taobao.weex.dom.DOMActionContext;
import com.taobao.weex.dom.RenderActionContext;
import com.taobao.weex.dom.WXDomObject;
+import com.taobao.weex.tracing.Stopwatch;
+import com.taobao.weex.tracing.WXTracing;
import com.taobao.weex.ui.component.WXComponent;
import com.taobao.weex.ui.component.WXScroller;
import com.taobao.weex.utils.WXLogUtils;
@@ -48,6 +50,12 @@ class CreateBodyAction extends AbstractAddElementAction {
@Override
public void executeDom(DOMActionContext context) {
+ if (WXEnvironment.isApkDebugable()) {
+ WXTracing.TraceEvent execJsEndEvent = WXTracing.newEvent("executeBundleJS", context.getInstanceId(), -1);
+ execJsEndEvent.traceId = context.getInstance().mExecJSTraceId;
+ execJsEndEvent.ph = "E";
+ execJsEndEvent.submit();
+ }
addDomInternal(context, mData);
}
@@ -58,10 +66,12 @@ class CreateBodyAction extends AbstractAddElementAction {
@Override
protected void appendDomToTree(DOMActionContext context, WXDomObject domObject) {
+ long startNanos = System.nanoTime();
String instanceId = context.getInstanceId();
WXDomObject.prepareRoot(domObject,
WXViewUtils.getWebPxByWidth(WXViewUtils.getWeexHeight(instanceId), WXSDKManager.getInstanceViewPortWidth(instanceId)),
WXViewUtils.getWebPxByWidth(WXViewUtils.getWeexWidth(instanceId), WXSDKManager.getInstanceViewPortWidth(instanceId)));
+ domObject.mDomThreadNanos += (System.nanoTime() - startNanos);
}
@Override
@@ -84,17 +94,24 @@ class CreateBodyAction extends AbstractAddElementAction {
return;
}
try {
+ Stopwatch.tick();
long start = System.currentTimeMillis();
component.createView();
if (WXEnvironment.isApkDebugable()) {
WXLogUtils.renderPerformanceLog("createView", (System.currentTimeMillis() - start));
+ submitPerformance("createView", "X", instance.getInstanceId(), Stopwatch.tackAndTick(), start, true);
}
start = System.currentTimeMillis();
component.applyLayoutAndEvent(component);
+ if (WXTracing.isAvailable()) {
+ submitPerformance("applyLayoutAndEvent", "X", instance.getInstanceId(), Stopwatch.tackAndTick(), start, true);
+ }
+ start = System.currentTimeMillis();
component.bindData(component);
if (WXEnvironment.isApkDebugable()) {
WXLogUtils.renderPerformanceLog("bind", (System.currentTimeMillis() - start));
+ submitPerformance("bindData", "X", instance.getInstanceId(), Stopwatch.tack(), start, true);
}
if (component instanceof WXScroller) {
@@ -108,6 +125,8 @@ class CreateBodyAction extends AbstractAddElementAction {
instance.onCreateFinish();
}
instance.commitUTStab(IWXUserTrackAdapter.DOM_MODULE, WXErrorCode.WX_SUCCESS);
+ component.mTraceInfo.uiQueueTime = mUIQueueTime;
+ component.onRenderFinish(WXComponent.STATE_ALL_FINISH);
} catch (Exception e) {
WXLogUtils.e("create body failed.", e);
}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/102f2ed0/android/sdk/src/main/java/com/taobao/weex/dom/action/CreateFinishAction.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/dom/action/CreateFinishAction.java b/android/sdk/src/main/java/com/taobao/weex/dom/action/CreateFinishAction.java
index c92cf11..e581c4e 100644
--- a/android/sdk/src/main/java/com/taobao/weex/dom/action/CreateFinishAction.java
+++ b/android/sdk/src/main/java/com/taobao/weex/dom/action/CreateFinishAction.java
@@ -25,6 +25,8 @@ import com.taobao.weex.common.WXRenderStrategy;
import com.taobao.weex.common.WXThread;
import com.taobao.weex.dom.DOMActionContext;
import com.taobao.weex.dom.RenderActionContext;
+import com.taobao.weex.tracing.Stopwatch;
+import com.taobao.weex.tracing.WXTracing;
/**
* Created by sospartan on 02/03/2017.
@@ -54,5 +56,9 @@ final class CreateFinishAction extends AbstractLayoutFinishAction {
instance.onCreateFinish();
}
instance.onRenderSuccess(mLayoutWidth, mLayoutHeight);
+ if (WXTracing.isAvailable()) {
+ double renderTime = Stopwatch.millisUntilNow(context.getInstance().mRenderStartNanos);
+ submitPerformance("renderFinish", "X", instance.getInstanceId(), renderTime, System.currentTimeMillis());
+ }
}
}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/102f2ed0/android/sdk/src/main/java/com/taobao/weex/dom/action/RefreshFinishAction.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/dom/action/RefreshFinishAction.java b/android/sdk/src/main/java/com/taobao/weex/dom/action/RefreshFinishAction.java
index c46b8d9..2d87d11 100644
--- a/android/sdk/src/main/java/com/taobao/weex/dom/action/RefreshFinishAction.java
+++ b/android/sdk/src/main/java/com/taobao/weex/dom/action/RefreshFinishAction.java
@@ -20,6 +20,7 @@ package com.taobao.weex.dom.action;
import com.taobao.weex.WXSDKInstance;
import com.taobao.weex.dom.RenderActionContext;
+import com.taobao.weex.tracing.WXTracing;
/**
* Created by sospartan on 02/03/2017.
@@ -31,5 +32,8 @@ class RefreshFinishAction extends AbstractLayoutFinishAction {
public void executeRender(RenderActionContext context) {
WXSDKInstance instance = context.getInstance();
instance.onRefreshSuccess(mLayoutWidth, mLayoutHeight);
+ if (WXTracing.isAvailable()) {
+ submitPerformance("refreshFinish", "I", context.getInstance().getInstanceId(), 0, 0);
+ }
}
}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/102f2ed0/android/sdk/src/main/java/com/taobao/weex/dom/action/TraceableAction.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/dom/action/TraceableAction.java b/android/sdk/src/main/java/com/taobao/weex/dom/action/TraceableAction.java
new file mode 100644
index 0000000..5bd2689
--- /dev/null
+++ b/android/sdk/src/main/java/com/taobao/weex/dom/action/TraceableAction.java
@@ -0,0 +1,82 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package com.taobao.weex.dom.action;
+
+import com.taobao.weex.tracing.Stopwatch;
+import com.taobao.weex.tracing.WXTracing;
+
+/**
+ * Created by moxun on 2017/6/30.
+ */
+
+public class TraceableAction {
+ public int mTracingEventId;
+ public long mStartMillis;
+ public long mDomQueueTime;
+ public long mUIQueueTime;
+ public long mParseJsonNanos = -1;
+ protected WXTracing.TraceEvent mBeginEvent;
+
+ {
+ if (WXTracing.isAvailable()) {
+ mTracingEventId = WXTracing.nextId();
+ mStartMillis = System.currentTimeMillis();
+ }
+ }
+
+ protected WXTracing.TraceEvent submitPerformance(String fname, String ph, String instanceId, double duration, long ts, boolean... isSegment) {
+ if (WXTracing.isAvailable()) {
+ WXTracing.TraceEvent event = WXTracing.newEvent(fname, instanceId, mTracingEventId);
+ event.ts = ts;
+ event.ph = ph;
+ event.duration = duration;
+
+ if (isSegment != null && isSegment.length == 1) {
+ event.isSegment = isSegment[0];
+ }
+
+ event.submit();
+ return event;
+ }
+ return new WXTracing.TraceEvent();
+ }
+
+ public void onStartDomExecute(String instanceId, String fname, String ref, String type, String payload) {
+ if (WXTracing.isAvailable()) {
+ mBeginEvent = WXTracing.newEvent(fname, instanceId, -1);
+ mBeginEvent.traceId = mTracingEventId;
+ mBeginEvent.ts = mStartMillis;
+ mBeginEvent.ph = "B";
+ mBeginEvent.ref = ref;
+ mBeginEvent.name = type;
+ mBeginEvent.payload = payload;
+ mBeginEvent.parseJsonTime = Stopwatch.nanosToMillis(mParseJsonNanos);
+ mBeginEvent.submit();
+ }
+ }
+
+ public void onFinishUIExecute() {
+ if (WXTracing.isAvailable() && mBeginEvent != null) {
+ WXTracing.TraceEvent endEvent = WXTracing.newEvent(getClass().getSimpleName(), mBeginEvent.iid, -1);
+ endEvent.traceId = mBeginEvent.traceId;
+ endEvent.ph = "E";
+ endEvent.submit();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/102f2ed0/android/sdk/src/main/java/com/taobao/weex/dom/action/UpdateAttributeAction.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/dom/action/UpdateAttributeAction.java b/android/sdk/src/main/java/com/taobao/weex/dom/action/UpdateAttributeAction.java
index 3db776e..017bb53 100644
--- a/android/sdk/src/main/java/com/taobao/weex/dom/action/UpdateAttributeAction.java
+++ b/android/sdk/src/main/java/com/taobao/weex/dom/action/UpdateAttributeAction.java
@@ -33,7 +33,7 @@ import com.taobao.weex.ui.component.WXComponent;
* Created by sospartan on 28/02/2017.
*/
-class UpdateAttributeAction implements DOMAction, RenderAction {
+class UpdateAttributeAction extends TraceableAction implements DOMAction, RenderAction {
private final String mRef;
private final JSONObject mData;
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/102f2ed0/android/sdk/src/main/java/com/taobao/weex/dom/action/UpdateStyleAction.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/dom/action/UpdateStyleAction.java b/android/sdk/src/main/java/com/taobao/weex/dom/action/UpdateStyleAction.java
index aa56e70..a4dc8e9 100644
--- a/android/sdk/src/main/java/com/taobao/weex/dom/action/UpdateStyleAction.java
+++ b/android/sdk/src/main/java/com/taobao/weex/dom/action/UpdateStyleAction.java
@@ -39,7 +39,7 @@ import java.util.Map;
* Created by sospartan on 28/02/2017.
*/
-class UpdateStyleAction implements DOMAction, RenderAction {
+class UpdateStyleAction extends TraceableAction implements DOMAction, RenderAction {
private final String mRef;
private final JSONObject mData;
private final boolean mIsCausedByPesudo;
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/102f2ed0/android/sdk/src/main/java/com/taobao/weex/tracing/Stopwatch.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/tracing/Stopwatch.java b/android/sdk/src/main/java/com/taobao/weex/tracing/Stopwatch.java
new file mode 100644
index 0000000..10b8be2
--- /dev/null
+++ b/android/sdk/src/main/java/com/taobao/weex/tracing/Stopwatch.java
@@ -0,0 +1,132 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package com.taobao.weex.tracing;
+
+import com.taobao.weex.utils.WXLogUtils;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Created by moxun on 2017/6/2.
+ */
+
+public class Stopwatch {
+ private static final ThreadLocal<Stopwatch> sThreadLocal = new ThreadLocal<>();
+ private long startNanos;
+ private List<ProcessEvent> splits = new ArrayList<>();
+ private long startMillis;
+
+ private static void prepare() {
+ if (sThreadLocal.get() == null) {
+ sThreadLocal.set(new Stopwatch());
+ }
+ }
+
+ public static void tick() {
+ if (WXTracing.isAvailable()) {
+ try {
+ prepare();
+ if (sThreadLocal.get().startNanos != 0L) {
+ WXLogUtils.w("Stopwatch", "Stopwatch is not reset");
+ }
+ sThreadLocal.get().startNanos = System.nanoTime();
+ sThreadLocal.get().startMillis = System.currentTimeMillis();
+ } catch (Throwable t) {
+ t.printStackTrace();
+ }
+ }
+ }
+
+ public static void split(String fname) {
+ if (WXTracing.isAvailable()) {
+ try {
+ ProcessEvent event = new ProcessEvent();
+ long start = sThreadLocal.get().startMillis;
+ double millis = tackAndTick();
+ event.fname = fname;
+ event.duration = millis;
+ event.startMillis = start;
+ sThreadLocal.get().splits.add(event);
+ } catch (Throwable throwable) {
+ throwable.printStackTrace();
+ }
+ }
+ }
+
+ public static List<ProcessEvent> getProcessEvents() {
+ if (WXTracing.isAvailable()) {
+ tack();
+ List<ProcessEvent> existedEvents = sThreadLocal.get().splits;
+ sThreadLocal.get().splits = new ArrayList<>();
+ return existedEvents;
+ } else {
+ return Collections.emptyList();
+ }
+ }
+
+ public static double tack() {
+ if (WXTracing.isAvailable()) {
+ try {
+ long startNanos = sThreadLocal.get().startNanos;
+ if (startNanos == 0L) {
+ WXLogUtils.w("Stopwatch", "Should call Stopwatch.tick() before Stopwatch.tack() called");
+ }
+ long nanos = System.nanoTime() - startNanos;
+ sThreadLocal.get().startNanos = 0L;
+ return nanosToMillis(nanos);
+ } catch (Throwable throwable) {
+ throwable.printStackTrace();
+ }
+ }
+ return -1;
+ }
+
+ public static long lastTickStamp() {
+ if (WXTracing.isAvailable()) {
+ try {
+ return sThreadLocal.get().startMillis;
+ } catch (Throwable t) {
+ t.printStackTrace();
+ }
+ }
+ return -1;
+ }
+
+ public static double tackAndTick() {
+ double ms = tack();
+ tick();
+ return ms;
+ }
+
+ public static double nanosToMillis(long nanos) {
+ return nanos / 1000000.0;
+ }
+
+ public static double millisUntilNow(long startNanos) {
+ return nanosToMillis(System.nanoTime() - startNanos);
+ }
+
+ public static class ProcessEvent {
+ public String fname;
+ public double duration;
+ public long startMillis;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/102f2ed0/android/sdk/src/main/java/com/taobao/weex/tracing/WXTracing.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/tracing/WXTracing.java b/android/sdk/src/main/java/com/taobao/weex/tracing/WXTracing.java
new file mode 100644
index 0000000..7530322
--- /dev/null
+++ b/android/sdk/src/main/java/com/taobao/weex/tracing/WXTracing.java
@@ -0,0 +1,156 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package com.taobao.weex.tracing;
+
+import android.os.Looper;
+import android.util.SparseArray;
+
+import com.taobao.weex.WXEnvironment;
+import com.taobao.weex.WXSDKManager;
+import com.taobao.weex.adapter.ITracingAdapter;
+import com.taobao.weex.utils.WXLogUtils;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * Created by moxun on 2017/6/6.
+ */
+
+public class WXTracing {
+ private static final AtomicInteger sIdGenerator = new AtomicInteger(0);
+
+ public static int nextId() {
+ return sIdGenerator.getAndIncrement();
+ }
+
+ public static boolean isAvailable() {
+ return WXEnvironment.isApkDebugable();
+ }
+
+ public static synchronized void submit(TraceEvent event) {
+ ITracingAdapter tracingAdapter = WXSDKManager.getInstance().getTracingAdapter();
+ if (tracingAdapter != null) {
+ if (event.iid == null) {
+ WXLogUtils.w("WXTracing", "Event " + event.fname + " missing instance id");
+ }
+ tracingAdapter.submitTracingEvent(event);
+ }
+ }
+
+ public static class TraceEvent {
+ public String fname;
+ public String tname;
+ public String ph;
+ public int traceId;
+ public long ts;
+ public String iid;
+ public String ref;
+ public String parentRef;
+ public String name;
+ public String classname;
+ public int parentId = -1;
+ public double duration;
+
+ /**
+ * Internal use
+ */
+ public SparseArray<TraceEvent> subEvents;
+ public String payload;
+ public double parseJsonTime;
+ public boolean isSegment;
+ public Map<String, Object> extParams;
+ public boolean firstScreenFinish;
+
+ private boolean submitted;
+
+ public TraceEvent() {
+ ts = System.currentTimeMillis();
+ traceId = nextId();
+ tname = currentThreadName();
+ }
+
+ public JSONObject toJSONObject() {
+ JSONObject object = new JSONObject();
+ try {
+ object.put("parentId", parentId);
+ object.put("ref", ref);
+ object.put("parentRef", parentRef);
+ object.put("className", classname);
+ object.put("ts", ts);
+ object.put("traceId", traceId);
+ object.put("iid", iid);
+ object.put("duration", duration);
+ object.put("fName", fname);
+ object.put("ph", ph);
+ object.put("name", name);
+ object.put("tName", tname);
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+ return object;
+ }
+
+ public void submit() {
+ if (!submitted) {
+ submitted = true;
+ WXTracing.submit(this);
+ } else {
+ WXLogUtils.w("WXTracing", "Event " + traceId + " has been submitted.");
+ }
+ }
+ }
+
+ public static String currentThreadName() {
+ Thread thread = Thread.currentThread();
+ String name = thread.getName();
+
+ if ("WeexJSBridgeThread".equals(name)) {
+ return "JSThread";
+ } else if ("WeeXDomThread".equals(name)) {
+ return "DOMThread";
+ } else if (Looper.getMainLooper() == Looper.myLooper()) {
+ return "UIThread";
+ }
+
+ return name;
+ }
+
+ public static TraceEvent newEvent(String fname, String instanceId, int parentId) {
+ WXTracing.TraceEvent traceEvent = new TraceEvent();
+ traceEvent.fname = fname;
+ traceEvent.iid = instanceId;
+ traceEvent.traceId = WXTracing.nextId();
+ traceEvent.parentId = parentId;
+ return traceEvent;
+ }
+
+ public static class TraceInfo {
+ public int rootEventId;
+ public long domQueueTime;
+ public long uiQueueTime;
+ public long domThreadStart = -1;
+ public long domThreadNanos;
+ public long uiThreadStart = -1;
+ public long uiThreadNanos;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/102f2ed0/android/sdk/src/main/java/com/taobao/weex/ui/WXRenderManager.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/WXRenderManager.java b/android/sdk/src/main/java/com/taobao/weex/ui/WXRenderManager.java
index 77e1b1b..edcc560 100644
--- a/android/sdk/src/main/java/com/taobao/weex/ui/WXRenderManager.java
+++ b/android/sdk/src/main/java/com/taobao/weex/ui/WXRenderManager.java
@@ -18,18 +18,21 @@
*/
package com.taobao.weex.ui;
+import android.os.SystemClock;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import com.taobao.weex.WXSDKInstance;
import com.taobao.weex.common.WXRuntimeException;
import com.taobao.weex.common.WXThread;
-import com.taobao.weex.common.WXTracing;
import com.taobao.weex.dom.RenderAction;
import com.taobao.weex.dom.RenderActionContext;
import com.taobao.weex.dom.WXDomObject;
+import com.taobao.weex.dom.action.AbstractAddElementAction;
+import com.taobao.weex.dom.action.TraceableAction;
+import com.taobao.weex.tracing.Stopwatch;
+import com.taobao.weex.tracing.WXTracing;
import com.taobao.weex.ui.component.WXComponent;
-import com.taobao.weex.utils.WXLogUtils;
import com.taobao.weex.utils.WXUtils;
import java.util.ArrayList;
@@ -104,18 +107,33 @@ public class WXRenderManager {
}
public void runOnThread(final String instanceId, final RenderAction action) {
- final long start = System.nanoTime();
- final String actionName = WXTracing.getFunctionName(action.getClass());
+ final long start = SystemClock.uptimeMillis();
mWXRenderHandler.post(WXThread.secure(new Runnable() {
@Override
public void run() {
- long s = System.nanoTime();
- WXLogUtils.e("Tracing", "Method " + actionName + ", Queue time " + (s - start) + " ns");
if (mRegistries.get(instanceId) == null) {
return;
}
+ if (WXTracing.isAvailable() && action instanceof TraceableAction) {
+ ((TraceableAction) action).mUIQueueTime = SystemClock.uptimeMillis() - start;
+ }
+
+ long start = System.currentTimeMillis();
+ long uiNanos = System.nanoTime();
action.executeRender(getRenderContext(instanceId));
- WXLogUtils.e("Tracing", "Method " + actionName + ", Render time " + (System.nanoTime() - s) + " ns");
+
+ if (WXTracing.isAvailable()) {
+ uiNanos = System.nanoTime() - uiNanos;
+ if (action instanceof TraceableAction) {
+ if (!(action instanceof AbstractAddElementAction)) {
+ WXTracing.TraceEvent uiExecuteEvent = WXTracing.newEvent("UIExecute", instanceId, ((TraceableAction) action).mTracingEventId);
+ uiExecuteEvent.duration = Stopwatch.nanosToMillis(uiNanos);
+ uiExecuteEvent.ts = start;
+ uiExecuteEvent.submit();
+ }
+ ((TraceableAction) action).onFinishUIExecute();
+ }
+ }
}
}));
}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/102f2ed0/android/sdk/src/main/java/com/taobao/weex/ui/component/WXComponent.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/component/WXComponent.java b/android/sdk/src/main/java/com/taobao/weex/ui/component/WXComponent.java
index cc44e79..9864b1e 100644
--- a/android/sdk/src/main/java/com/taobao/weex/ui/component/WXComponent.java
+++ b/android/sdk/src/main/java/com/taobao/weex/ui/component/WXComponent.java
@@ -31,6 +31,7 @@ import android.os.Build;
import android.os.Message;
import android.support.annotation.CallSuper;
import android.support.annotation.CheckResult;
+import android.support.annotation.IntDef;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.view.ViewCompat;
@@ -76,6 +77,10 @@ import com.taobao.weex.utils.WXResourceUtils;
import com.taobao.weex.utils.WXUtils;
import com.taobao.weex.utils.WXViewUtils;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
@@ -1556,16 +1561,49 @@ public abstract class WXComponent<T extends View> implements IWXObject, IWXActi
WXSDKManager.getInstance().getWXDomManager().sendMessage(message);
}
- public void onRenderFinish() {
- if (isLazy()) {
- return;
+ public static final int STATE_DOM_FINISH = 0;
+ public static final int STATE_UI_FINISH = 1;
+ public static final int STATE_ALL_FINISH = 2;
+ @IntDef({STATE_DOM_FINISH, STATE_UI_FINISH, STATE_ALL_FINISH})
+ @Retention(RetentionPolicy.SOURCE)
+ @Target(ElementType.PARAMETER)
+ public @interface RenderState {}
+
+ @CallSuper
+ public void onRenderFinish(@RenderState int state) {
+ if (WXTracing.isAvailable()) {
+ double domTime = Stopwatch.nanosToMillis(((WXDomObject) mDomObj).mDomThreadNanos + mTraceInfo.domThreadNanos);
+ double uiTime = Stopwatch.nanosToMillis(mTraceInfo.uiThreadNanos);
+ if (state == STATE_ALL_FINISH || state == STATE_DOM_FINISH) {
+ WXTracing.TraceEvent domEvent = WXTracing.newEvent("DomExecute", getInstanceId(), mTraceInfo.rootEventId);
+ domEvent.ph = "X";
+ domEvent.duration = domTime;
+ domEvent.ts = mTraceInfo.domThreadStart;
+ domEvent.tname = "DOMThread";
+ domEvent.name = getDomObject().getType();
+ domEvent.classname = getClass().getSimpleName();
+ if (getParent() != null) {
+ domEvent.parentRef = getParent().getRef();
+ }
+ domEvent.submit();
+ }
+
+ if (state == STATE_ALL_FINISH || state == STATE_UI_FINISH) {
+ if (mTraceInfo.uiThreadStart != -1) {
+ WXTracing.TraceEvent uiEvent = WXTracing.newEvent("UIExecute", getInstanceId(), mTraceInfo.rootEventId);
+ uiEvent.ph = "X";
+ uiEvent.duration = uiTime;
+ uiEvent.ts = mTraceInfo.uiThreadStart;
+ uiEvent.name = getDomObject().getType();
+ uiEvent.classname = getClass().getSimpleName();
+ if (getParent() != null) {
+ uiEvent.parentRef = getParent().getRef();
+ }
+ uiEvent.submit();
+ } else {
+ WXLogUtils.w("onRenderFinish", "createView() not called");
+ }
+ }
}
- double domTime = Stopwatch.nanosToMillis(((WXDomObject) mDomObj).mDomThreadNanos + mTraceInfo.domThreadNanos);
- double uiTime = Stopwatch.nanosToMillis(mTraceInfo.uiThreadNanos);
- WXLogUtils.e("RenderFinish", "Ref: " + getRef() + ", type: " + mDomObj.getType() + ", dom: " + mTraceInfo.domQueueTime + "/" + domTime + ", ui: " + mTraceInfo.uiQueueTime + "/" + uiTime);
- WXTracing.TraceEvent domEvent = WXTracing.measureAndSubmit("dom " + mDomObj.getType() + "@" + getRef(), "X", mTraceInfo.rootEventId, getInstanceId(), domTime);
- domEvent.ts = mTraceInfo.domThreadStart;
- domEvent.tname = "DOMThread";
- WXTracing.measureAndSubmit("ui " + mDomObj.getType() + "@" + getRef(), "X", mTraceInfo.rootEventId, getInstanceId(), uiTime).ts = mTraceInfo.uiThreadStart;
}
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/102f2ed0/android/sdk/src/main/java/com/taobao/weex/ui/component/WXVContainer.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/component/WXVContainer.java b/android/sdk/src/main/java/com/taobao/weex/ui/component/WXVContainer.java
index afdad86..871b18a 100644
--- a/android/sdk/src/main/java/com/taobao/weex/ui/component/WXVContainer.java
+++ b/android/sdk/src/main/java/com/taobao/weex/ui/component/WXVContainer.java
@@ -93,6 +93,7 @@ public abstract class WXVContainer<T extends ViewGroup> extends WXComponent<T> {
@Override
public void applyLayoutAndEvent(WXComponent component) {
+ long startNanos = System.nanoTime();
if(!isLazy()) {
if (component == null) {
component = this;
@@ -105,6 +106,7 @@ public abstract class WXVContainer<T extends ViewGroup> extends WXComponent<T> {
}
}
+ mTraceInfo.uiThreadNanos += (System.nanoTime() - startNanos);
}
/**
@@ -141,6 +143,7 @@ public abstract class WXVContainer<T extends ViewGroup> extends WXComponent<T> {
}
@Override
public void bindData(WXComponent component) {
+ long startNanos = System.nanoTime();
if(!isLazy()) {
if (component == null) {
component = this;
@@ -151,6 +154,7 @@ public abstract class WXVContainer<T extends ViewGroup> extends WXComponent<T> {
getChild(i).bindData(((WXVContainer)component).getChild(i));
}
}
+ mTraceInfo.uiThreadNanos += (System.nanoTime() - startNanos);
}
@Override
@@ -240,6 +244,7 @@ public abstract class WXVContainer<T extends ViewGroup> extends WXComponent<T> {
}
public void addChild(WXComponent child, int index) {
+ long startNanos = System.nanoTime();
if (child == null || index < -1) {
return;
}
@@ -250,6 +255,7 @@ public abstract class WXVContainer<T extends ViewGroup> extends WXComponent<T> {
} else {
mChildren.add(index, child);
}
+ mTraceInfo.uiThreadNanos += (System.nanoTime() - startNanos);
}
public final int indexOf(WXComponent comp){
@@ -257,6 +263,7 @@ public abstract class WXVContainer<T extends ViewGroup> extends WXComponent<T> {
}
public void createChildViewAt(int index){
+ long startNanos = System.nanoTime();
int indexToCreate = index;
if(indexToCreate < 0){
indexToCreate = childCount()-1;
@@ -269,6 +276,7 @@ public abstract class WXVContainer<T extends ViewGroup> extends WXComponent<T> {
if(!child.isVirtualComponent()){
addSubView(child.getHostView(),indexToCreate);
}
+ mTraceInfo.uiThreadNanos += (System.nanoTime() - startNanos);
}
protected void addSubView(View child, int index) {
@@ -429,6 +437,16 @@ public abstract class WXVContainer<T extends ViewGroup> extends WXComponent<T> {
}
}
+ @Override
+ public void onRenderFinish(@RenderState int state) {
+ for (int i = 0; i < getChildCount(); i++) {
+ WXComponent child = getChild(i);
+ child.mTraceInfo.uiQueueTime = mTraceInfo.uiQueueTime;
+ child.onRenderFinish(state);
+ }
+ super.onRenderFinish(state);
+ }
+
/********************************
* end hook Activity life cycle callback
********************************************************/
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/102f2ed0/android/sdk/src/main/java/com/taobao/weex/ui/component/list/BasicListComponent.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/component/list/BasicListComponent.java b/android/sdk/src/main/java/com/taobao/weex/ui/component/list/BasicListComponent.java
index 9418a1f..08c6c8e 100644
--- a/android/sdk/src/main/java/com/taobao/weex/ui/component/list/BasicListComponent.java
+++ b/android/sdk/src/main/java/com/taobao/weex/ui/component/list/BasicListComponent.java
@@ -850,7 +850,7 @@ public abstract class BasicListComponent<T extends ViewGroup & ListComponentView
if (holder.getComponent() != null && holder.getComponent() instanceof WXCell) {
if(holder.isRecycled()) {
holder.bindData(component);
- component.onRenderFinish();
+ component.onRenderFinish(STATE_UI_FINISH);
}
if (mDragHelper == null || !mDragHelper.isDraggable()) {
return;
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/102f2ed0/android/sdk/src/main/java/com/taobao/weex/utils/WXLogUtils.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/utils/WXLogUtils.java b/android/sdk/src/main/java/com/taobao/weex/utils/WXLogUtils.java
index 1107003..43246ea 100644
--- a/android/sdk/src/main/java/com/taobao/weex/utils/WXLogUtils.java
+++ b/android/sdk/src/main/java/com/taobao/weex/utils/WXLogUtils.java
@@ -35,13 +35,12 @@ public class WXLogUtils {
public static final String WEEX_TAG = "weex";
public static final String WEEX_PERF_TAG = "weex_perf";
- public static boolean isShowLineNumber = false;
-
private static final String CLAZZ_NAME_DEBUG_TOOL = "com.taobao.weex.WXDebugTool";
private static final String CLAZZ_NAME_LOG_UTIL = "com.taobao.weex.devtools.common.LogUtil";
private static StringBuilder builder = new StringBuilder(50);
private static HashMap<String, Class> clazzMaps = new HashMap<>(2);
+ private static JsLogWatcher jsLogWatcher;
static {
clazzMaps.put(CLAZZ_NAME_DEBUG_TOOL, loadClass(CLAZZ_NAME_DEBUG_TOOL));
@@ -65,14 +64,13 @@ public class WXLogUtils {
if (WXEnvironment.isApkDebugable() || WXEnvironment.isPerf()) {
builder.setLength(0);
builder.append("[render time]").append(type).append(":").append(time);
- Log.d(WEEX_PERF_TAG, getLineNumber() + builder.substring(0));
+ Log.d(WEEX_PERF_TAG, builder.substring(0));
writeConsoleLog("debug", builder.substring(0));
}
}
private static void log(String tag, String msg, LogLevel level){
if (WXEnvironment.isApkDebugable() && msg != null && WXEnvironment.sLogLevel.compare(level) >= 0) {
- msg = getLineNumber() + msg;
Log.println(level.getPriority(),tag, msg);
writeConsoleLog(level.getName(), msg);
sendLog(level, msg);
@@ -109,8 +107,22 @@ public class WXLogUtils {
public static void d(String tag, String msg) {
if (WXEnvironment.isApkDebugable() && !TextUtils.isEmpty(msg) && WXEnvironment.sLogLevel.compare(LogLevel.DEBUG) >= 0) {
- msg = getLineNumber() + msg;
Log.d(tag, msg);
+
+ if ("jsLog".equals(tag) && jsLogWatcher != null) {
+ if (msg.endsWith("__DEBUG")) {
+ jsLogWatcher.onJsLog(Log.DEBUG, msg.replace("__DEBUG", ""));
+ } else if (msg.endsWith("__INFO")) {
+ jsLogWatcher.onJsLog(Log.DEBUG, msg.replace("__INFO", ""));
+ } else if (msg.endsWith("__WARN")) {
+ jsLogWatcher.onJsLog(Log.DEBUG, msg.replace("__WARN", ""));
+ } else if (msg.endsWith("__ERROR")) {
+ jsLogWatcher.onJsLog(Log.DEBUG, msg.replace("__ERROR", ""));
+ } else {
+ jsLogWatcher.onJsLog(Log.DEBUG, msg);
+ }
+ }
+
/** This log method will be invoked from jni code, so try to extract loglevel from message. **/
writeConsoleLog("debug", tag + ":" + msg);
if(msg.contains(" | __")){
@@ -268,22 +280,11 @@ public class WXLogUtils {
}
}
- /**
- * Why the index is 2 ?
- * StackTrace:
- * 0 = com.taobao.weex.utils.WXLogUtils.getLineNumber
- * 1 = com.taobao.weex.utils.WXLogUtils#x
- * 2 = the actual caller
- * …… more stack trace element
- * */
- private static String getLineNumber() {
- if (!isShowLineNumber) {
- return "";
- }
- StackTraceElement[] stackTrace = new Throwable().getStackTrace();
- final int index = 2;
- String className = stackTrace[index].getFileName();
- int lineNum = stackTrace[index].getLineNumber();
- return "(" + className + ":" + lineNum + ") ";
+ public static void setJsLogWatcher(JsLogWatcher watcher) {
+ jsLogWatcher = watcher;
+ }
+
+ public interface JsLogWatcher {
+ void onJsLog(int level, String log);
}
}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/102f2ed0/android/sdk/src/test/java/com/taobao/weex/utils/WXLogUtilsTest.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/test/java/com/taobao/weex/utils/WXLogUtilsTest.java b/android/sdk/src/test/java/com/taobao/weex/utils/WXLogUtilsTest.java
index ece6e0e..3fde10a 100644
--- a/android/sdk/src/test/java/com/taobao/weex/utils/WXLogUtilsTest.java
+++ b/android/sdk/src/test/java/com/taobao/weex/utils/WXLogUtilsTest.java
@@ -46,7 +46,6 @@ public class WXLogUtilsTest {
@Before
public void setUp() throws Exception {
- WXLogUtils.isShowLineNumber = true;
PowerMockito.mockStatic(WXEnvironment.class);
PowerMockito.when(WXEnvironment.isApkDebugable()).thenReturn(true);
}