Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

improve profile screen performance #18281

Merged
merged 1 commit into from
Dec 22, 2023

Conversation

flexsurfer
Copy link
Member

so it seems like there is a quick simple way to improve performance, by moving part of views into next js task by using timeout

@status-im-auto
Copy link
Member

status-im-auto commented Dec 22, 2023

Jenkins Builds

Commit #️⃣ Finished (UTC) Duration Platform Result
✔️ 99cb41a #1 2023-12-22 12:14:37 ~5 min tests 📄log
✔️ 99cb41a #1 2023-12-22 12:18:13 ~8 min android-e2e 🤖apk 📲
✔️ 99cb41a #1 2023-12-22 12:18:17 ~8 min android 🤖apk 📲
✔️ 99cb41a #1 2023-12-22 12:21:03 ~11 min ios 📱ipa 📲

Copy link
Contributor

@mohsen-ghafouri mohsen-ghafouri left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for take care of this

@status-im-auto
Copy link
Member

56% of end-end tests have passed

Total executed tests: 48
Failed tests: 16
Expected to fail tests: 5
Passed tests: 27
Not executed tests: 1
IDs of not executed tests: 704614 
IDs of failed tests: 703194,702859,702777,703133,702851,702840,703086,702894,702850,704615,702839,702838,702844,702843,703629,702841 
IDs of expected to fail tests: 702732,702948,703503,702731,702808 

Not executed tests (1)

Click to expand
  • Rerun not executed tests
  • Failed tests (16)

    Click to expand
  • Rerun failed tests

  • Class TestCommunityOneDeviceMerged:

    1. test_restore_multiaccount_with_waku_backup_remove_switch, id: 703133

    Device 1: Find `Button` by `accessibility id`: `show-profiles`
    Device 1: Tap on found: Button

    critical/chats/test_public_chat_browsing.py:273: in test_restore_multiaccount_with_waku_backup_remove_switch
        self.errors.verify_no_errors()
    base_test_case.py:191: in verify_no_errors
        pytest.fail('\n '.join([self.errors.pop(0) for _ in range(len(self.errors))]))
     zQ3...pJN5P was not restored as a contact from waku backup!
    E    zQ3...UxXqE was not restored as a contact from waku backup!
    E    admin_open was not restored from waku-backup!!
    E    member_open was not restored from waku-backup!!
    E    admin_closed was not restored from waku-backup!!
    E    member_closed was not restored from waku-backup!!
    



    Device sessions

    Class TestActivityCenterContactRequestMultipleDevicePR:

    1. test_add_contact_field_validation, id: 702777

    Test setup failed: activity_center/test_activity_center.py:27: in prepare_devices
        self.profile_link_2 = self.home_2.get_link_to_profile()
    ../views/home_view.py:567: in get_link_to_profile
        self.link_to_profile_text.wait_for_visibility_of_element()
    ../views/base_element.py:139: in wait_for_visibility_of_element
        raise TimeoutException(
     Device 2: Text by xpath:`(//*[@content-desc='link-to-profile']/preceding-sibling::*[1]/android.widget.TextView)[1]` is not found on the screen after wait_for_visibility_of_element
    



    2. test_activity_center_contact_request_accept_swipe_mark_all_as_read, id: 702851

    Test setup failed: activity_center/test_activity_center.py:27: in prepare_devices
        self.profile_link_2 = self.home_2.get_link_to_profile()
    ../views/home_view.py:567: in get_link_to_profile
        self.link_to_profile_text.wait_for_visibility_of_element()
    ../views/base_element.py:139: in wait_for_visibility_of_element
        raise TimeoutException(
     Device 2: Text by xpath:`(//*[@content-desc='link-to-profile']/preceding-sibling::*[1]/android.widget.TextView)[1]` is not found on the screen after wait_for_visibility_of_element
    



    3. test_activity_center_contact_request_decline, id: 702850

    Device 2: Find Button by accessibility id: show-qr-button
    Device 2: Tap on found: Button

    Test setup failed: activity_center/test_activity_center.py:27: in prepare_devices
        self.profile_link_2 = self.home_2.get_link_to_profile()
    ../views/home_view.py:567: in get_link_to_profile
        self.link_to_profile_text.wait_for_visibility_of_element()
    ../views/base_element.py:139: in wait_for_visibility_of_element
        raise TimeoutException(
     Device 2: Text by xpath:`(//*[@content-desc='link-to-profile']/preceding-sibling::*[1]/android.widget.TextView)[1]` is not found on the screen after wait_for_visibility_of_element
    



    Device sessions

    Class TestCommunityMultipleDeviceMergedTwo:

    1. test_community_join_when_node_owner_offline, id: 703629

    Device 1: ## Creating open community
    Device 1: Find Button by accessibility id: new-communities-button

    critical/chats/test_public_chat_browsing.py:1080: in test_community_join_when_node_owner_offline
        self.home_1.create_community(community_type="open")
    ../views/home_view.py:478: in create_community
        self.plus_community_button.click()
    ../views/base_element.py:90: in click
        self.find_element().click()
    ../views/base_element.py:84: in find_element
        raise exception
    ../views/base_element.py:77: in find_element
        return self.driver.find_element(self.by, self.locator)
    /home/jenkins/.local/lib/python3.10/site-packages/appium/webdriver/webdriver.py:409: in find_element
        return self.execute(RemoteCommand.FIND_ELEMENT, {'using': by, 'value': value})['value']
    /home/jenkins/.local/lib/python3.10/site-packages/selenium/webdriver/remote/webdriver.py:345: in execute
        self.error_handler.check_response(response)
    /home/jenkins/.local/lib/python3.10/site-packages/appium/webdriver/errorhandler.py:122: in check_response
        raise exception_class(msg=message, stacktrace=format_stacktrace(stacktrace))
     An unknown server-side error occurred while processing the command. Original error: Timed out after 37756ms waiting for the root AccessibilityNodeInfo in the active window. Make sure the active window is not constantly hogging the main UI thread (e.g. the application is being idle long enough), so the accessibility manager could do its work
    E   Stacktrace:
    E   io.appium.uiautomator2.common.exceptions.UiAutomator2Exception: Timed out after 37756ms waiting for the root AccessibilityNodeInfo in the active window. Make sure the active window is not constantly hogging the main UI thread (e.g. the application is being idle long enough), so the accessibility manager could do its work
    E   	at io.appium.uiautomator2.utils.AXWindowHelpers.getActiveWindowRoot(AXWindowHelpers.java:84)
    E   	at io.appium.uiautomator2.utils.AXWindowHelpers.getCachedWindowRoots(AXWindowHelpers.java:152)
    E   	at io.appium.uiautomator2.model.internal.CustomUiDevice.findObject(CustomUiDevice.java:118)
    E   	at io.appium.uiautomator2.utils.ElementLocationHelpers.findElement(ElementLocationHelpers.java:150)
    E   	at io.appium.uiautomator2.handler.FindElement.safeHandle(FindElement.java:60)
    E   	at io.appium.uiautomator2.handler.request.SafeRequestHandler.handle(SafeRequestHandler.java:59)
    E   	at io.appium.uiautomator2.server.AppiumServlet.handleRequest(AppiumServlet.java:277)
    E   	at io.appium.uiautomator2.server.AppiumServlet.handleHttpRequest(AppiumServlet.java:271)
    E   	at io.appium.uiautomator2.http.ServerHandler.channelRead(ServerHandler.java:68)
    E   	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:366)
    E   	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:352)
    E   	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:345)
    E   	at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:102)
    E   	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:366)
    E   	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:352)
    E   	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:345)
    E   	at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelRead(CombinedChannelDuplexHandler.java:435)
    E   	at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:293)
    E   	at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:267)
    E   	at io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:250)
    E   	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:366)
    E   	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:352)
    E   	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:345)
    E   	at io.netty.handler.timeout.IdleStateHandler.channelRead(IdleStateHandler.java:266)
    E   	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:366)
    E   	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:352)
    E   	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:345)
    E   	at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1294)
    E   	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:366)
    E   	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:352)
    E   	at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:911)
    E   	at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:131)
    E   	at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:611)
    E   	at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:552)
    E   	at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:466)
    E   	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:438)
    E   	at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:140)
    E   	at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:144)
    E   	at java.lang.Thread.run(Thread.java:1012)
    



    Device sessions

    Class TestCommunityMultipleDeviceMerged:

    1. test_community_several_images_send_reply, id: 703194

    Test setup failed: critical/chats/test_public_chat_browsing.py:288: in prepare_devices
        self.public_key_2 = self.home_2.get_public_key_via_share_profile_tab()
    ../views/home_view.py:573: in get_public_key_via_share_profile_tab
        link_to_profile = self.get_link_to_profile()
    ../views/home_view.py:567: in get_link_to_profile
        self.link_to_profile_text.wait_for_visibility_of_element()
    ../views/base_element.py:139: in wait_for_visibility_of_element
        raise TimeoutException(
     Device 2: Text by xpath:`(//*[@content-desc='link-to-profile']/preceding-sibling::*[1]/android.widget.TextView)[1]` is not found on the screen after wait_for_visibility_of_element
    



    2. test_community_one_image_send_reply, id: 702859

    Test setup failed: critical/chats/test_public_chat_browsing.py:288: in prepare_devices
        self.public_key_2 = self.home_2.get_public_key_via_share_profile_tab()
    ../views/home_view.py:573: in get_public_key_via_share_profile_tab
        link_to_profile = self.get_link_to_profile()
    ../views/home_view.py:567: in get_link_to_profile
        self.link_to_profile_text.wait_for_visibility_of_element()
    ../views/base_element.py:139: in wait_for_visibility_of_element
        raise TimeoutException(
     Device 2: Text by xpath:`(//*[@content-desc='link-to-profile']/preceding-sibling::*[1]/android.widget.TextView)[1]` is not found on the screen after wait_for_visibility_of_element
    



    3. test_community_emoji_send_copy_paste_reply, id: 702840

    Test setup failed: critical/chats/test_public_chat_browsing.py:288: in prepare_devices
        self.public_key_2 = self.home_2.get_public_key_via_share_profile_tab()
    ../views/home_view.py:573: in get_public_key_via_share_profile_tab
        link_to_profile = self.get_link_to_profile()
    ../views/home_view.py:567: in get_link_to_profile
        self.link_to_profile_text.wait_for_visibility_of_element()
    ../views/base_element.py:139: in wait_for_visibility_of_element
        raise TimeoutException(
     Device 2: Text by xpath:`(//*[@content-desc='link-to-profile']/preceding-sibling::*[1]/android.widget.TextView)[1]` is not found on the screen after wait_for_visibility_of_element
    



    4. test_community_mark_all_messages_as_read, id: 703086

    Test setup failed: critical/chats/test_public_chat_browsing.py:288: in prepare_devices
        self.public_key_2 = self.home_2.get_public_key_via_share_profile_tab()
    ../views/home_view.py:573: in get_public_key_via_share_profile_tab
        link_to_profile = self.get_link_to_profile()
    ../views/home_view.py:567: in get_link_to_profile
        self.link_to_profile_text.wait_for_visibility_of_element()
    ../views/base_element.py:139: in wait_for_visibility_of_element
        raise TimeoutException(
     Device 2: Text by xpath:`(//*[@content-desc='link-to-profile']/preceding-sibling::*[1]/android.widget.TextView)[1]` is not found on the screen after wait_for_visibility_of_element
    



    5. test_community_contact_block_unblock_offline, id: 702894

    Test setup failed: critical/chats/test_public_chat_browsing.py:288: in prepare_devices
        self.public_key_2 = self.home_2.get_public_key_via_share_profile_tab()
    ../views/home_view.py:573: in get_public_key_via_share_profile_tab
        link_to_profile = self.get_link_to_profile()
    ../views/home_view.py:567: in get_link_to_profile
        self.link_to_profile_text.wait_for_visibility_of_element()
    ../views/base_element.py:139: in wait_for_visibility_of_element
        raise TimeoutException(
     Device 2: Text by xpath:`(//*[@content-desc='link-to-profile']/preceding-sibling::*[1]/android.widget.TextView)[1]` is not found on the screen after wait_for_visibility_of_element 
    

    [[Message can be missed after unblock: https://github.com//issues/16873]]

    6. test_community_edit_delete_message_when_offline, id: 704615

    Test setup failed: critical/chats/test_public_chat_browsing.py:288: in prepare_devices
        self.public_key_2 = self.home_2.get_public_key_via_share_profile_tab()
    ../views/home_view.py:573: in get_public_key_via_share_profile_tab
        link_to_profile = self.get_link_to_profile()
    ../views/home_view.py:567: in get_link_to_profile
        self.link_to_profile_text.wait_for_visibility_of_element()
    ../views/base_element.py:139: in wait_for_visibility_of_element
        raise TimeoutException(
     Device 2: Text by xpath:`(//*[@content-desc='link-to-profile']/preceding-sibling::*[1]/android.widget.TextView)[1]` is not found on the screen after wait_for_visibility_of_element
    



    7. test_community_message_delete, id: 702839

    Test setup failed: critical/chats/test_public_chat_browsing.py:288: in prepare_devices
        self.public_key_2 = self.home_2.get_public_key_via_share_profile_tab()
    ../views/home_view.py:573: in get_public_key_via_share_profile_tab
        link_to_profile = self.get_link_to_profile()
    ../views/home_view.py:567: in get_link_to_profile
        self.link_to_profile_text.wait_for_visibility_of_element()
    ../views/base_element.py:139: in wait_for_visibility_of_element
        raise TimeoutException(
     Device 2: Text by xpath:`(//*[@content-desc='link-to-profile']/preceding-sibling::*[1]/android.widget.TextView)[1]` is not found on the screen after wait_for_visibility_of_element
    



    8. test_community_message_send_check_timestamps_sender_username, id: 702838

    Device 2: Find Button by accessibility id: show-qr-button
    Device 2: Tap on found: Button

    Test setup failed: critical/chats/test_public_chat_browsing.py:288: in prepare_devices
        self.public_key_2 = self.home_2.get_public_key_via_share_profile_tab()
    ../views/home_view.py:573: in get_public_key_via_share_profile_tab
        link_to_profile = self.get_link_to_profile()
    ../views/home_view.py:567: in get_link_to_profile
        self.link_to_profile_text.wait_for_visibility_of_element()
    ../views/base_element.py:139: in wait_for_visibility_of_element
        raise TimeoutException(
     Device 2: Text by xpath:`(//*[@content-desc='link-to-profile']/preceding-sibling::*[1]/android.widget.TextView)[1]` is not found on the screen after wait_for_visibility_of_element
    



    Device sessions

    9. test_community_links_with_previews_github_youtube_twitter_gif_send_enable, id: 702844

    Test setup failed: critical/chats/test_public_chat_browsing.py:288: in prepare_devices
        self.public_key_2 = self.home_2.get_public_key_via_share_profile_tab()
    ../views/home_view.py:573: in get_public_key_via_share_profile_tab
        link_to_profile = self.get_link_to_profile()
    ../views/home_view.py:567: in get_link_to_profile
        self.link_to_profile_text.wait_for_visibility_of_element()
    ../views/base_element.py:139: in wait_for_visibility_of_element
        raise TimeoutException(
     Device 2: Text by xpath:`(//*[@content-desc='link-to-profile']/preceding-sibling::*[1]/android.widget.TextView)[1]` is not found on the screen after wait_for_visibility_of_element
    



    10. test_community_message_edit, id: 702843

    Test setup failed: critical/chats/test_public_chat_browsing.py:288: in prepare_devices
        self.public_key_2 = self.home_2.get_public_key_via_share_profile_tab()
    ../views/home_view.py:573: in get_public_key_via_share_profile_tab
        link_to_profile = self.get_link_to_profile()
    ../views/home_view.py:567: in get_link_to_profile
        self.link_to_profile_text.wait_for_visibility_of_element()
    ../views/base_element.py:139: in wait_for_visibility_of_element
        raise TimeoutException(
     Device 2: Text by xpath:`(//*[@content-desc='link-to-profile']/preceding-sibling::*[1]/android.widget.TextView)[1]` is not found on the screen after wait_for_visibility_of_element
    



    11. test_community_unread_messages_badge, id: 702841

    Test setup failed: critical/chats/test_public_chat_browsing.py:288: in prepare_devices
        self.public_key_2 = self.home_2.get_public_key_via_share_profile_tab()
    ../views/home_view.py:573: in get_public_key_via_share_profile_tab
        link_to_profile = self.get_link_to_profile()
    ../views/home_view.py:567: in get_link_to_profile
        self.link_to_profile_text.wait_for_visibility_of_element()
    ../views/base_element.py:139: in wait_for_visibility_of_element
        raise TimeoutException(
     Device 2: Text by xpath:`(//*[@content-desc='link-to-profile']/preceding-sibling::*[1]/android.widget.TextView)[1]` is not found on the screen after wait_for_visibility_of_element
    



    Expected to fail tests (5)

    Click to expand

    Class TestCommunityOneDeviceMerged:

    1. test_community_discovery, id: 703503

    Test is not run, e2e blocker  
    

    [[reason: [NOTRUN] Curated communities not loading, https://github.com//issues/17852]]

    Class TestOneToOneChatMultipleSharedDevicesNewUi:

    1. test_1_1_chat_pin_messages, id: 702731

    Test is not run, e2e blocker  
    

    [[reason: [NOTRUN] Pin feature is in development]]

    Class TestGroupChatMultipleDeviceMergedNewUI:

    1. test_group_chat_pin_messages, id: 702732

    Test is not run, e2e blocker  
    

    [[reason: [NOTRUN] Pin feature is in development]]

    2. test_group_chat_offline_pn, id: 702808

    Device 3: Looking for a message by text: message from old member
    Device 3: Looking for a message by text: message from new member

    critical/chats/test_group_chat.py:324: in test_group_chat_offline_pn
        self.errors.verify_no_errors()
    base_test_case.py:191: in verify_no_errors
        pytest.fail('\n '.join([self.errors.pop(0) for _ in range(len(self.errors))]))
     Messages PN was not fetched from offline 
    

    [[Data delivery issue]]

    Device sessions

    Class TestCommunityMultipleDeviceMergedTwo:

    1. test_community_hashtag_links_to_community_channels, id: 702948

    Device 2: ChatMessageInput element not found
    Device 2: Looking for a message by text: #cats

    critical/chats/test_public_chat_browsing.py:1040: in test_community_hashtag_links_to_community_channels
        self.channel_2.chat_element_by_text(message_with_hashtag).click_on_link_inside_message_body()
    ../views/chat_view.py:193: in click_on_link_inside_message_body
        self.message_body.wait_for_visibility_of_element(30)
    ../views/base_element.py:139: in wait_for_visibility_of_element
        raise TimeoutException(
     Device 2: Text by xpath:`//android.view.ViewGroup[@content-desc='chat-item']//android.widget.TextView[contains(@text,'#cats')]` is not found on the screen after wait_for_visibility_of_element ; 
     RemoteDisconnected
    

    [[Can't navigate to a channel by hashtag link, https://github.com//issues/18095]]

    Device sessions

    Passed tests (27)

    Click to expand

    Class TestOneToOneChatMultipleSharedDevicesNewUi:

    1. test_1_1_chat_emoji_send_reply_and_open_link, id: 702782
    Device sessions

    2. test_1_1_chat_text_message_delete_push_disappear, id: 702733
    Device sessions

    3. test_1_1_chat_push_emoji, id: 702813
    Device sessions

    4. test_1_1_chat_non_latin_messages_stack_update_profile_photo, id: 702745
    Device sessions

    5. test_1_1_chat_edit_message, id: 702855
    Device sessions

    6. test_1_1_chat_send_image_save_and_share, id: 703391
    Device sessions

    7. test_1_1_chat_message_reaction, id: 702730
    Device sessions

    Class TestDeepLinksOneDevice:

    1. test_links_open_universal_links_from_chat, id: 704613
    Device sessions

    2. test_links_deep_links, id: 702775
    Device sessions

    Class TestOneToOneChatMultipleSharedDevicesNewUiTwo:

    1. test_1_1_chat_delete_via_long_press_relogin, id: 702784
    Device sessions

    2. test_1_1_chat_is_shown_message_sent_delivered_from_offline, id: 702783
    Device sessions

    3. test_1_1_chat_mute_chat, id: 703496
    Device sessions

    Class TestGroupChatMultipleDeviceMergedNewUI:

    1. test_group_chat_mute_chat, id: 703495
    Device sessions

    2. test_group_chat_send_image_save_and_share, id: 703297
    Device sessions

    3. test_group_chat_reactions, id: 703202
    Device sessions

    4. test_group_chat_join_send_text_messages_push, id: 702807
    Device sessions

    Class TestCommunityMultipleDeviceMergedTwo:

    1. test_community_markdown_support, id: 702809
    Device sessions

    2. test_community_mentions_push_notification, id: 702786
    Device sessions

    3. test_community_leave, id: 702845
    Device sessions

    Class TestActivityMultipleDevicePR:

    1. test_navigation_jump_to, id: 702936
    Device sessions

    2. test_activity_center_reply_read_unread_delete_filter_swipe, id: 702947
    Device sessions

    Class TestCommunityOneDeviceMerged:

    1. test_community_copy_and_paste_message_in_chat_input, id: 702742
    Device sessions

    2. test_community_undo_delete_message, id: 702869
    Device sessions

    3. test_community_navigate_to_channel_when_relaunch, id: 702846
    Device sessions

    4. test_community_mute_community_and_channel, id: 703382
    Device sessions

    Class TestActivityMultipleDevicePRTwo:

    1. test_activity_center_mentions, id: 702957
    Device sessions

    2. test_activity_center_admin_notification_accept_swipe, id: 702958
    Device sessions

    @flexsurfer
    Copy link
    Member Author

    @status-im/mobile-qa could you pls confirm e2e not related

    @yevh-berdnyk
    Copy link
    Contributor

    @status-im/mobile-qa could you pls confirm e2e not related

    I'm afraid it is related. The most of the failures are caused by the screen size change when getting a link to profile - the element is not intractable. This is how it looks like now:

    And in develop:

    @flexsurfer flexsurfer merged commit 31acb8e into develop Dec 22, 2023
    6 of 7 checks passed
    @flexsurfer flexsurfer deleted the feature/improve-profile-screen-performance branch December 22, 2023 15:59
    @flexsurfer
    Copy link
    Member Author

    merged because these changes not related to this PR

    @churik
    Copy link
    Member

    churik commented Dec 22, 2023

    it is likely related to last wallet changes, communicated to wallet team

    @flexsurfer
    Copy link
    Member Author

    introduced here #18167

    Copy link
    Contributor

    @ulisesmac ulisesmac left a comment

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    Hey @flexsurfer
    I know this has been merged, but I wanted to share some questions.

    Comment on lines -18 to -22
    [rn/flat-list
    {:data data
    :style (style/settings-items props)
    :render-fn settings-item/view
    :separator [rn/view {:style (style/settings-separator props)}]}]])
    Copy link
    Contributor

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    I've always wondered if our flat-list wrapper is properly transforming the render-fn in terms of performance.

    Also, that wrapper is doing many things. Have we considered if that is the part of the problem? We use this wrapper a lot, and it's involved in many performance issues because of flat-list, so it's worth checking (or did we already check?).

    Copy link
    Contributor

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    One thing we certainly don't do is avoid regenerating anonymous functions. For our lower-level components we can do better using something like the factory functions explained in https://github.com/day8/re-frame/blob/39adca93673f334dc751ee2d99d340b51a9cc6db/docs/on-stable-dom-handlers.md#more-advanced-again

    Copy link
    Contributor

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    Thanks for replying to this comment also in the other PR! :)

    I read that in the past, about a fabric of fabrics, I found it a little confusing and probably hard to maintain, but it works.

    It'd be good to revisit our flat list implementation then :) - and if we apply that performance technique, make sure it's well documented -

    Copy link
    Contributor

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    I agree with you, the factory function technique should be used only in critical places. To me the infrastructure/abstractions we build should be as optimal as possible because they're reused over and over, and the flat-list component is one such place.

    Thanks for raising your concern, it's something I don't remember seeing being discussed in the last year or so.

    Comment on lines -37 to +39
    #js {:length 48 :offset (* 48 index) :index index})
    #js {:length 100 :offset (* 100 index) :index index})
    Copy link
    Contributor

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    I'm wondering why this has been changed. Were the dimensions wrong? does this affect the UI?

    Copy link
    Member Author

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    it's just a random number, i just wanted to reserve more space

    Copy link
    Contributor

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    I believe getItemLayout should reflect the actual item dimensions:

    getItemLayout is an optional optimization that allows skipping the measurement of dynamic content if you know the size (height or width) of items ahead of time.

    https://reactnative.dev/docs/flatlist#getitemlayout

    So maybe changing this for random values might have an unexpected behavior

    Copy link
    Member Author

    @flexsurfer flexsurfer Dec 22, 2023

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    yes it should, but here it's used only for first "empty" rendering, and then the layout will be calculated by real item size, in this case, it will be different for items

    Copy link
    Contributor

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    Sorry, I'm not understanding how this will be done.

    Do you mean that if we pass wrong dimensions, RN will only use them for the first rendering and in following renders they will be automatically calculated?
    Does RN know that calculations are wrong?

    Many questions, just not sure what the approach used here will do.

    src/utils/re_frame.cljs Show resolved Hide resolved
    (defn delay-render
    [content]
    (let [render? (reagent/atom false)]
    (js/setTimeout #(reset! render? true) 0)
    Copy link
    Contributor

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    Have you considered setImmediate?

    Copy link
    Member Author

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    no why? setTimeout fits perfectly here

    Copy link
    Contributor

    @ulisesmac ulisesmac Dec 22, 2023

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    Just because of reading.

    We are setting a timeout as zero, so there is no "time" involved. SetImmediate sounds as what we want 🤔

    Now I'm wondering if removing the timeout gives the same result:

    (let [render? (reagent/atom false)
          _       (reset! render? true)]
      (fn [] 
        ,,,))

    Since once an atom is changed, reagent perform the updates the next cycle, so it means the first time the component is rendered using false and the second time with true 🤔

    Copy link
    Member Author

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    probably, but for me (js/setTimeout 0) is known thing, so i'm sure it works how it should

    Copy link
    Contributor

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    Update on this:
    It won't work, the atom is always received in the render function as false.
    I also tried using setImmediate (to trigger the atom reset! at the end of the JS cycle) and it works too!

    One thing I've just noticed is that we are not receiving content in the render function, it means, if content changes, it won't trigger a re-render.

    Is this by mistake or intended?
    As @ilmotta said, since this is a general purpose component, and content can be anything, maybe we should receive content in the render fn

    Copy link
    Member Author

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    in this case it's intentional,ok i think it would be better to move it to profile settings namespace, because there is confusion now, this was done only for this current case but for some reason i decided to put it into utils re-frame namespace

    Copy link
    Contributor

    @ilmotta ilmotta left a comment

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    Interesting work @flexsurfer!

    I think the solution is fine, if it works it works, but I wanted to hear more about this solution and where it wouldn't work in the PR description, because clearly we shouldn't delay rendering everywhere, so where does the abstraction breaks you know?

    I'm (just) slightly concerned we might apply this workaround in too many places, masking other performance problems that should be solved before.

    But let's see, nice work in any case!

    ^{:key item}
    [:<>
    [settings-item/view item]
    (when-not (= item (last data))
    Copy link
    Contributor

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    Just a note @flexsurfer. last is inefficient for larger sequences because like a linked list, Clojure has to go one element at a time to find the last one. There's no sort of pointer to the last element. Much faster in larger lists is to grab the index of the last item and compare to that. Also the comparison with = would be much faster than comparing item, which is a more complex structure.

    Take a look at CLJS source code, last is expensive.

    (defn last
      "Return the last item in coll, in linear time"
      [s]
      (let [sn (next s)]
        (if-not (nil? sn)
          (recur sn)
          (first s))))

    Copy link
    Contributor

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    We could restrict the type of data to be a vector and use peek instead.

    Btw, I wonder how expensive the transformation from list to vector is and what is faster:

    (peek (vec data))
    vs
    (last data)

    In case we receive a list.
    I guess vec transforms in O(n), but whishing it's not 😅

    Copy link
    Member Author

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    in this current case it's fine i guess because we know there will be a small number of items, and i don't think it's super critical here, just don't like indexes in clojure code :)

    Copy link
    Contributor

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    Interesting question @ulisesmac, I don't know either without benchmarks.

    In general, we should just not call last inside a loop of a collection, it's quite inefficient, unless we know it's a vector as you hinted.

    I think just calling (-> data count dec) is significantly cheaper than trying to convert to a vector and repeatedly call last inside a loop because then we can just do a number comparison of (= index last-index), which is probably as fast as we can go to identify the last element.

    Copy link
    Contributor

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    In general, we should just not call last inside a loop of a collection, it's quite inefficient, unless we know it's a vector as you hinted.

    I agree, we could just extract that calculation outside the for loop.

    (defn delay-render
    [content]
    (let [render? (reagent/atom false)]
    (js/setTimeout #(reset! render? true) 0)
    Copy link
    Contributor

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    The RN doc says setTimeout or setImmediate may delay animations. runAfterInteractions doesn't suffer from that, although only experimentation can tell if it works better.

    Source: https://reactnative.dev/docs/next/timers

    Copy link
    Member Author

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    we don't have animations here, what kind of animation they might delay? setTimeout just put code in the next js task

    Copy link
    Contributor

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    delay-render is a general component, and content can be anything. How can this function know there's no animation?

    Copy link
    Member Author

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    that's expected, if you delay component :)

    Copy link
    Member Author

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    but i think documentation is old, and that about times there were only js animation based on timers etc , now with reanimated it's not actual anymore

    Copy link
    Contributor

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    You said there are no animations here, but there's no way to know from here. My point is just that setTimeout with 0 is a workaround that may delay animations as pointed by the RN docs, and there's no way for this function to know what content does.

    At the very least I think it should be investigated how this solution fares against content that has animations versus using runAfterInteractions.

    This of course in a future branch/PR because this one is already merged.

    Copy link
    Member Author

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    i said that because i believe docs says that if you have animation in your code somewhere , like in the parent component it will be affected by setTimeout because Timeout has a priority, but in our case if you use delay you know that entire component will be delayed, so offcourse animation will be delayed as well, if content has it, so it should be obvious for developer who uses delay, but again, i don't say it's a general solution, so probably we should move it in separate namespace and add description how to use it, for now it must be used only in this current case, and in other cases it should be used with understanding how it works

    Copy link
    Contributor

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    and add description how to use it, for now it must be used only in this current case,

    That would be great @flexsurfer.

    and in other cases it should be used with understanding how it works

    👍🏼 perfect

    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Projects
    Archived in project
    Archived in project
    Development

    Successfully merging this pull request may close these issues.

    8 participants