Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ConstraintLayout onMeasure very slow

Tags:

so I tried refactoring some of my recycler ViewHolders to ConstraintLayouts. After I did it I was shocked after what I saw. Inflating a single view takes 20x more time than usual LinearLayout. It actually skips so many frames while doing it.

EDIT: Version of constraint layout is not relevant. Tried different combinations had almost the same results.

Can any one explain why is this happening? Maybe it's not designed for such "heavy" views?

Here is a root XML that is used in ViewHolder:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/white"
    android:elevation="@dimen/param_2"
    android:orientation="vertical"
    android:stateListAnimator="@animator/material_selector">

    <LinearLayout
        android:id="@+id/order_view_tabs_container"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="@dimen/param_2"
        android:padding="@dimen/param_4"
        android:background="@color/white"
        android:divider="@drawable/empty_horizontal_divider"
        android:elevation="@dimen/param_2"
        android:orientation="horizontal"
        android:showDividers="middle"
        android:visibility="gone"/>

    <include layout="@layout/order_list_item_constraint"/>

    </LinearLayout>

And here is order_list_item_constraint.xml

<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="@dimen/param_4"
    android:clipToPadding="false">

    <TextView
        android:id="@+id/delivery_status"
        style="@style/DefaultText.Normal"
        android:layout_width="0dp"
        android:layout_height="50dp"
        android:layout_marginEnd="4dp"
        android:padding="4dp"
        android:background="@color/white"
        android:elevation="2dp"
        android:gravity="center_vertical"
        android:text="@string/main_swipe_list_item_info_title_delivered_time"
        app:layout_constraintEnd_toStartOf="@id/mid_guideline"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        tools:layout_editor_absoluteY="4dp"/>

    <TextView
        android:id="@+id/order_list_item_order_title"
        style="@style/FullListItemInfoText"
        android:layout_width="0dp"
        android:layout_marginTop="4dp"
        android:text="@string/main_swipe_list_item_info_title_order"
        android:textColor="@color/red_900"
        app:layout_constraintEnd_toEndOf="@id/mid_guideline"
        app:layout_constraintStart_toStartOf="@id/start_guideline"
        app:layout_constraintTop_toBottomOf="@+id/delivery_status"/>

    <TextView
        android:id="@+id/order_list_item_order_id"
        style="@style/FullListItemInfoDetailsText"
        android:layout_width="0dp"
        app:layout_constraintEnd_toEndOf="@id/mid_guideline"
        app:layout_constraintStart_toStartOf="@+id/start_guideline"
        app:layout_constraintTop_toBottomOf="@id/order_list_item_order_title"
        />

    <TextView
        android:id="@+id/order_list_item_price_title"
        style="@style/FullListItemInfoText"
        android:layout_width="0dp"
        android:layout_marginTop="4dp"
        android:text="@string/main_swipe_list_item_info_title_sum"
        app:layout_constraintEnd_toEndOf="@id/mid_guideline"
        app:layout_constraintStart_toStartOf="@id/start_guideline"
        app:layout_constraintTop_toBottomOf="@+id/order_list_item_order_id"
        />

    <TextView
        android:id="@+id/order_list_item_price"
        style="@style/FullListItemInfoDetailsText"
        android:layout_width="0dp"
        app:layout_constraintEnd_toEndOf="@id/mid_guideline"
        app:layout_constraintStart_toStartOf="@+id/start_guideline"
        app:layout_constraintTop_toBottomOf="@id/order_list_item_price_title"
        />


    <TextView
        android:id="@+id/order_list_item_threshold_title"
        style="@style/FullListItemInfoText"
        android:layout_width="0dp"
        android:layout_marginTop="4dp"
        android:text="@string/order_full_list_item_threshold_value_title"
        app:layout_constraintEnd_toEndOf="@id/mid_guideline"
        app:layout_constraintStart_toStartOf="@id/start_guideline"
        app:layout_constraintTop_toBottomOf="@+id/order_list_item_price"
        />

    <TextView
        android:id="@+id/order_list_item_threshold_value"
        style="@style/FullListItemInfoDetailsText"
        android:layout_width="0dp"
        app:layout_constraintEnd_toEndOf="@id/mid_guideline"
        app:layout_constraintStart_toStartOf="@+id/start_guideline"
        app:layout_constraintTop_toBottomOf="@id/order_list_item_threshold_title"
        />


    <TextView
        android:id="@+id/order_list_item_sl_title"
        style="@style/FullListItemInfoText"
        android:layout_width="0dp"
        android:layout_marginTop="@dimen/param_4"
        android:text="@string/main_swipe_list_item_info_title_service_level"
        app:layout_constraintEnd_toEndOf="@id/mid_guideline"
        app:layout_constraintStart_toStartOf="@id/start_guideline"
        app:layout_constraintTop_toBottomOf="@+id/order_list_item_threshold_value"/>


    <TextView
        android:id="@+id/order_list_item_service_level_title"
        style="@style/FullListItemInfoDetailsText"
        android:textStyle="bold"
        android:layout_width="0dp"
        android:textSize="@dimen/text_size_12"
        app:layout_constraintEnd_toEndOf="@id/mid_guideline"
        app:layout_constraintStart_toStartOf="@id/start_guideline"
        app:layout_constraintTop_toBottomOf="@+id/order_list_item_sl_title"/>

    <TextView
        android:id="@+id/order_list_item_service_level_try_on"
        style="@style/FullListItemInfoDetailsText"
        android:layout_width="0dp"
        android:textSize="@dimen/text_size_12"
        app:layout_constraintEnd_toEndOf="@id/mid_guideline"
        app:layout_constraintStart_toStartOf="@id/start_guideline"
        app:layout_constraintTop_toBottomOf="@+id/order_list_item_service_level_title"/>


    <TextView
        android:id="@+id/order_list_item_service_level_partial_purchase"
        style="@style/FullListItemInfoDetailsText"
        android:layout_width="0dp"
        android:textSize="@dimen/text_size_12"
        app:layout_constraintEnd_toEndOf="@id/mid_guideline"
        app:layout_constraintStart_toStartOf="@id/start_guideline"
        app:layout_constraintTop_toBottomOf="@+id/order_list_item_service_level_try_on"/>


    <com.express.mobile.customView.MyNetworkImageView
        android:id="@+id/order_list_item_image_map"
        android:layout_width="0dp"
        android:layout_height="144dp"
        android:elevation="2dp"
        android:scaleType="centerCrop"
        android:visibility="visible"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="@id/mid_guideline"
        app:layout_constraintTop_toTopOf="parent"/>

    <ImageView
        android:id="@+id/order_list_item_map_pin"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:paddingBottom="@dimen/param_30"
        android:contentDescription="@null"
        android:elevation="2dp"
        android:src="@drawable/ic_map_pin_sz_1"
        android:visibility="gone"
        app:layout_constrainedHeight="true"
        app:layout_constrainedWidth="true"
        app:layout_constraintBottom_toBottomOf="@id/order_list_item_image_map"
        app:layout_constraintEnd_toEndOf="@id/order_list_item_image_map"
        app:layout_constraintStart_toStartOf="@id/order_list_item_image_map"
        app:layout_constraintTop_toTopOf="@id/order_list_item_image_map"/>


    <include
        android:id="@+id/order_list_item_map_interval_box"
        layout="@layout/map_interval_box"
        android:layout_width="wrap_content"
        android:layout_height="@dimen/param_48"
        app:layout_constrainedWidth="true"
        app:layout_constraintStart_toStartOf="@id/order_list_item_image_map"/>

    <TextView
        android:id="@+id/order_list_item_timer"
        style="@style/WhiteText.Large"
        android:textStyle="bold"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="@drawable/order_full_list_item_delivery_status_box_borders"
        android:elevation="2dp"
        android:gravity="center"
        android:text="@string/timer_zero_time_value_text"
        android:textSize="@dimen/text_size_24"
        android:visibility="gone"
        app:layout_constraintBottom_toBottomOf="@id/order_list_item_map_interval_box"
        app:layout_constraintEnd_toEndOf="@id/order_list_item_map_interval_box"
        app:layout_constraintStart_toStartOf="@id/order_list_item_map_interval_box"
        app:layout_constraintTop_toTopOf="@id/order_list_item_map_interval_box"/>


    <ImageView
        android:id="@+id/order_list_item_partner_icon"
        android:layout_width="@dimen/param_40"
        android:layout_height="@dimen/param_40"
        android:layout_margin="4dp"
        android:background="@drawable/order_mod_icon"
        android:backgroundTint="@color/red_800"
        android:contentDescription="@null"
        android:elevation="@dimen/param_4"
        android:scaleType="center"
        android:src="@drawable/ic_partner"
        android:visibility="gone"
        app:layout_constraintBottom_toBottomOf="@+id/order_list_item_image_map"
        app:layout_constraintStart_toStartOf="@+id/order_list_item_image_map"/>

    <ImageView
        android:id="@+id/order_list_item_prepaid_icon"
        android:layout_width="@dimen/param_40"
        android:layout_height="@dimen/param_40"
        android:layout_margin="4dp"
        android:background="@drawable/order_mod_icon"
        android:backgroundTint="@color/green_800"
        android:contentDescription="@null"
        android:elevation="@dimen/param_4"
        android:scaleType="center"
        android:src="@drawable/ic_prepaid"
        android:visibility="gone"
        app:layout_constraintBottom_toBottomOf="@+id/order_list_item_image_map"
        app:layout_constraintStart_toEndOf="@id/order_list_item_partner_icon"/>

    <ImageView
        android:id="@+id/order_list_item_microcredit_icon"
        android:layout_width="@dimen/param_40"
        android:layout_height="@dimen/param_40"
        android:layout_margin="4dp"
        android:background="@drawable/order_mod_icon"
        android:backgroundTint="@color/blue_grey_700"
        android:contentDescription="@null"
        android:elevation="@dimen/param_4"
        android:scaleType="center"
        android:src="@drawable/ic_microcredit"
        android:visibility="gone"
        app:layout_constraintBottom_toBottomOf="@+id/order_list_item_image_map"
        app:layout_constraintStart_toEndOf="@id/order_list_item_prepaid_icon"/>


    <ImageView
        android:id="@+id/order_list_item_ongoing_icon"
        android:layout_width="@dimen/param_40"
        android:layout_height="@dimen/param_40"
        android:layout_margin="4dp"
        android:background="@drawable/order_mod_icon"
        android:backgroundTint="@color/colorPrimaryDark"
        android:contentDescription="@null"
        android:elevation="@dimen/param_4"
        android:scaleType="center"
        android:src="@drawable/ic_delivery_time_ongoing"
        android:visibility="gone"
        app:layout_constraintBottom_toBottomOf="@+id/order_list_item_image_map"
        app:layout_constraintStart_toEndOf="@id/order_list_item_microcredit_icon"/>


    <TextView
        android:id="@+id/order_list_item_name"
        style="@style/FullListItemInfoDetailsText"
        android:layout_width="0dp"
        android:layout_height="@dimen/param_20"
        android:layout_marginTop="8dp"
        android:drawablePadding="@dimen/param_8"
        android:drawableStart="@drawable/ic_man"
        android:maxLines="1"
        app:layout_constraintEnd_toStartOf="@id/order_list_item_call_icon"
        app:layout_constraintStart_toStartOf="@id/mid_guideline"
        app:layout_constraintTop_toBottomOf="@id/order_list_item_image_map"/>

    <TextView
        android:id="@+id/order_list_item_phone"
        style="@style/FullListItemInfoDetailsText"
        android:layout_width="0dp"
        android:layout_height="@dimen/param_20"
        android:layout_marginStart="@dimen/param_28"
        android:maxLines="1"
        app:layout_constraintEnd_toStartOf="@id/order_list_item_call_icon"
        app:layout_constraintStart_toStartOf="@id/mid_guideline"
        app:layout_constraintTop_toBottomOf="@id/order_list_item_name"/>

    <ImageView
        android:id="@+id/address_icon"
        android:layout_width="@dimen/param_20"
        android:layout_height="@dimen/param_20"
        android:layout_marginTop="4dp"
        android:contentDescription="@null"
        android:src="@drawable/ic_address"
        app:layout_constraintStart_toStartOf="@id/mid_guideline"
        app:layout_constraintTop_toBottomOf="@id/order_list_item_phone"/>

    <TextView
        android:id="@+id/order_list_item_address"
        style="@style/FullListItemInfoDetailsText"
        android:layout_width="0dp"
        android:layout_weight="1"
        android:layout_marginTop="4dp"
        android:layout_marginStart="8dp"
        android:layout_marginEnd="4dp"
        android:minLines="2"
        app:layout_constraintEnd_toStartOf="@id/order_list_item_call_icon"
        app:layout_constraintStart_toEndOf="@id/address_icon"
        app:layout_constraintTop_toBottomOf="@id/order_list_item_phone"/>


    <ImageView
        android:id="@+id/order_list_item_call_icon"
        android:layout_width="38dp"
        android:layout_height="38dp"
        android:padding="@dimen/param_8"
        android:background="@drawable/order_mod_icon"
        android:contentDescription="@null"
        android:elevation="@dimen/param_4"
        android:src="@drawable/ic_call"
        android:visibility="visible"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="@id/order_list_item_name"/>


    <ImageView
        android:id="@+id/order_list_item_navigate_icon"
        android:layout_width="38dp"
        android:layout_height="38dp"
        android:padding="@dimen/param_8"
        android:background="@drawable/order_mod_icon"
        android:contentDescription="@null"
        android:elevation="@dimen/param_4"
        android:src="@drawable/ic_order_navigate"
        android:visibility="visible"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="@id/order_list_item_address"/>


    <android.support.constraint.Guideline
        android:id="@+id/mid_guideline"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintGuide_end="360dp"/>


    <android.support.constraint.Guideline
        android:id="@+id/start_guideline"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintGuide_begin="4dp"
        app:layout_constraintStart_toStartOf="parent"/>


     </android.support.constraint.ConstraintLayout>

Here is proof of problem. All child views have measure times around 0.1ms HierarchyViewer

Comparing a simple LinearLayout enter image description here

EDIT2: Here is a layout version with LinearLayout's: https://pastebin.com/ZvffUHnw

like image 995
Kęstas Venslauskas Avatar asked Feb 09 '18 11:02

Kęstas Venslauskas


People also ask

Is constraint layout slow?

Results show that the fastest layout is Relative Layout, but difference between this and Linear Layout is really small, what we can't say about Constraint Layout. More complex layout but results are the same, flat Constraint Layout is slower than nested Linear Layout.

Which is better RelativeLayout or ConstraintLayout?

ConstraintLayout has flat view hierarchy unlike other layouts, so does a better performance than relative layout. Yes, this is the biggest advantage of Constraint Layout, the only single layout can handle your UI.

Can we use LinearLayout in ConstraintLayout?

Most of what can be achieved in LinearLayout and RelativeLayout can be done in ConstraintLayout.

Is ConstraintLayout a ViewGroup?

A ConstraintLayout is a ViewGroup which allows you to position and size widgets in a flexible way. Note: ConstraintLayout is available as a support library that you can use on Android systems starting with API level 9 (Gingerbread).


1 Answers

That's definitely not expected -- I'll have to investigate more to see what's causing it. Note that 1.1 beta is right now going to be slower than 1.0, all the optimizer passes aren't enabled. At first glance there's a lot of textview with 0dp width, which is pretty costly -- like with linear layout, 0dp is going to result in a double measure. E.g. instead of:

<TextView
    android:id="@+id/order_list_item_order_title"
    android:layout_width="0dp"
    android:layout_height="20dp"
    android:layout_marginTop="4dp"
    android:text="@string/main_swipe_list_item_info_title_order"
    app:layout_constraintEnd_toEndOf="@id/mid_guideline"
    app:layout_constraintStart_toStartOf="@id/start_guideline"
    app:layout_constraintTop_toBottomOf="@+id/delivery_status"/>

You could do:

<TextView
    android:id="@+id/order_list_item_order_title"
    android:layout_width="wrap_content"
    android:layout_height="20dp"
    android:layout_marginTop="4dp"
    android:text="@string/main_swipe_list_item_info_title_order"
    app:layout_constraintStart_toStartOf="@id/start_guideline"
    app:layout_constraintTop_toBottomOf="@+id/delivery_status"/>

You don't need to have both a start and end constraints here as well, as you are using guidelines.

Note that in general, HierarchyViewer isn't going to be giving you accurate measurements (that said with such a difference, something seems wrong there).

How does your com.express.mobile.customView.MyNetworkImageView custom view handles measures? as you set it to 0dp it will also be double-measured in your layout.

Finally, Could you add what's in your included layout order_list_item_map_interval_box ?

edit 1.1 beta 6 should improve performances quite a log

like image 192
Nicolas Roard Avatar answered Oct 17 '22 01:10

Nicolas Roard