keframe icon indicating copy to clipboard operation
keframe copied to clipboard

Nested `FrameSeparateWidget`s causes widget to be stuck in placeholder state

Open keithcwk opened this issue 3 years ago • 1 comments

NewsStack is a page containing NewsStackBody and NewsStackMore.

NewsStackBody contains a list of FrameSeparatedWidget where its child is NewsStackCard NewsStackCard is a widget that renders a FrameSeparateWidget based on switch case NewsStackMore acts like a suggestion list, when clicked, it pushes the navigator to a new instance of NewsStack

The problem here is that, during the initial open of NewsStack (from home page) everything loads perfectly, however, when opening another NewsStack page by clicking on NewsStackMore, the FrameSeparateWidget seems to always be stuck in the placeholder widget.

The code here is not entirely accurate, more of a pseudocode, but the main idea here is that, on initial open, nested FrameSeparateWidgets work fine, when there are more layers, it gets stuck in placeholder.

Things i tried:

  1. Letting the page load and wait for the child to appear. Yes it does, but it takes a long time (minutes)
  2. Instead of doing two layers of FrameSeparateWidget, I tried using only one layer. Same thing happens, just takes slightly lesser time to load
NewsStack() => 
  return Scaffold(
     body: CustomScrollView(
       slivers: [
           NewsStackBody(),
           NewsStackMore(),
         ],
      ),
  );
  NewsStackBody() => 
   for (var content in list)
    return FrameSeparateWidget(
         placeHolder: customPlaceholder(),
        child: NewsStackCard(),
     );
NewsStackCard()=>
   case (a) => return FrameSeparateWidget(placeholder: customPlaceholder(), child: widgetA(),
   case (b) => return FrameSeparateWidget(placeholder: customPlaceholder(), child: widgetB(),

keithcwk avatar Aug 15 '22 09:08 keithcwk

Screenshot 2022-08-15 at 5 55 21 PM

A new finding that I have while doing a print statement here is that, when opening the first page, the taskQueue's length will increase, approximately to 12,000. After waiting for the taskQueue to be cleared (length == 1), navigating to the next page will immediately load the new page's content.

My conclusion here is that, the delay/persistent state of the placeholder widget is due to the taskQueue not being paused/cleared when navigating to the next page.

A temporary workaround that I have, is to clear the taskQueue of the previous instance upon creating a new instance. I am aware that this is obviously not a good solution especially when there are multiple FrameSeparateWidgets but this is what i found useful for my use case, and it is effective when having minimal amount of FrameSeparateWidgets.

Do update me if you have any new findings @Nayuta403

keithcwk avatar Aug 15 '22 09:08 keithcwk

Is the taskQueue 12000 in length? This is very strange indeed

Nayuta403 avatar Aug 17 '22 03:08 Nayuta403

@Nayuta403 I added the print statement to _runTasks() instead, to print the _taskQueue.length. The link below shows a demo of the frame count increasing to more than 10000. I noticed that initially it's still a very small amount, but as i scroll, the number increases drastically. Is this normal?

Could this be happening because of nested FrameSeparateWidgets?

If indeed this is not normal, may I know what can I do to prevent this?

https://drive.google.com/file/d/1miVtoa8CwvzHlfE-K-AZASveyYi4EgFM/view?usp=sharing

keithcwk avatar Aug 18 '22 03:08 keithcwk

OMG, this queue length doesn't look normal. The fastest way is to set this property to control the maximum length of the queue

https://github.com/LianjiaTech/keframe/blob/8b10b65a64f546abb927c858337cc44652dd4d5a/lib/src/frame_separate_task.dart#L24

For example, set it to 100 (this is the maximum number of FrameSepWidget components that can be on the screen at any one time).

Let's see if it works, and then we can see why is it happening

ps: Your app looks so beautiful

Nayuta403 avatar Aug 18 '22 10:08 Nayuta403

image

At the beginning of the video there is a sudden increase in the number of FramesepWidgets. It seems a little strange. Can you post where FrameSepWidget is used

Nayuta403 avatar Aug 18 '22 13:08 Nayuta403

At the same time,I do not recommend using FrameSepWidget as a child nested with FrameSepWidget. It should only need to be used on the child.

NewsStackBody() => 
   for (var content in list)
    return FrameSeparateWidget(
         placeHolder: customPlaceholder(),
        child: NewsStackCard(),
     );
NewsStackCard()=>
   case (a) => return FrameSeparateWidget(placeholder: customPlaceholder(), child: widgetA(),
   case (b) => return FrameSeparateWidget(placeholder: customPlaceholder(), child: widgetB(),

you're already using FrameSepWidget in your NewStackCard

Nayuta403 avatar Aug 18 '22 13:08 Nayuta403

@Nayuta403 First off, thank you so much for your time and effort to reply to this thread and looking into this!

As you suggested from this conversation, I tried wrapping only the child with the FrameSeparateWidget, which looks something like this:

  NewsStackBody() => 
   for (var content in list)
      return NewsStackCard();

  NewsStackCard()=>
  	 case (a) => return FrameSeparateWidget(placeholder: customPlaceholder(), child: widgetA(),
     case (b) => return FrameSeparateWidget(placeholder: customPlaceholder(), child: widgetB(),

And also, i adjusted the maxTaskSize to 100 in both line 24, and also modified the resetMaxTaskSize() function to reset to 100. Here is a demo of the page.

It seems to eliminate the high queue issue, and we can see that even stacking NewsStack pages on the navigator does not contain a significant lag as per the previous demo. So, thank you for the suggestion!

May I suggest that a parameter can be introduced so that we can adjust the maxTaskSize based on the app's needs?

keithcwk avatar Aug 19 '22 03:08 keithcwk

There is this parameter, which can be accessed here

https://github.com/LianjiaTech/keframe/blob/8b10b65a64f546abb927c858337cc44652dd4d5a/lib/src/size_cache_widget.dart#L17

Nayuta403 avatar Aug 22 '22 03:08 Nayuta403

@Nayuta403 thanks for the suggestion! will mark this issue as resolved and close this PR

keithcwk avatar Aug 30 '22 04:08 keithcwk