jessesquires / JSQMessagesViewController

An elegant messages UI library for iOS
https://www.jessesquires.com/blog/officially-deprecating-jsqmessagesviewcontroller/
Other
11.14k stars 2.81k forks source link

Inverted Mode #665

Closed chadpod closed 7 years ago

chadpod commented 10 years ago

Take a look at https://github.com/slackhq/SlackTextViewController

They use transforms to support an inverted mode which might solve quite a few of the issues we have seen. Gets around the newest message at the bottom necessitating loading all the messages. Considering this is how the vast majority of chat views work, sucks Apple didn't give us a cleaner way to do it.

Thoughts?

DDany commented 9 years ago

Great idea.

llz456 commented 9 years ago

It took me some time to finish this. The settings of the demo app now has a 'Enable Inverted Mode' switch. You can try out both modes on a slow device and see the big difference. The annoying screen flicker is gone, and the initial display is faster because it only needs to compute and render cells that will be initially displayed. Say bye-bye to 'scroll-to-bottom' :-)

jessesquires commented 9 years ago

Hey @chadpod / @llz456

Gets around the newest message at the bottom necessitating loading all the messages.

I'm not quite sure "Inverted Mode" is solving the correct problem.

Having the newest message at the bottom does not necessitate loading all messages. This is the purpose of the "Load Earlier Messages" header, or the new UI in iMessage with a spinner. You can truncate your content to the N most recent, then load previous messages in pages when the user scrolls up.

llz456 commented 9 years ago

@jessesquires

Without inverted mode, it needs to render the first number of cells (to fill up screen), then last number of cells (to fill up screen) due to 'scroll-to-bottom' action. Here are the log messages from cellForItemAtIndexPath: method:

2015-11-17 21:13:39.011 JSQMessages[64615:3392106] cellForItemAtIndexPath called for item 0 2015-11-17 21:13:39.019 JSQMessages[64615:3392106] cellForItemAtIndexPath called for item 1 2015-11-17 21:13:39.023 JSQMessages[64615:3392106] cellForItemAtIndexPath called for item 2 2015-11-17 21:13:39.027 JSQMessages[64615:3392106] cellForItemAtIndexPath called for item 3 2015-11-17 21:13:39.059 JSQMessages[64615:3392106] cellForItemAtIndexPath called for item 4 2015-11-17 21:13:39.065 JSQMessages[64615:3392106] cellForItemAtIndexPath called for item 5 2015-11-17 21:13:39.070 JSQMessages[64615:3392106] cellForItemAtIndexPath called for item 6 2015-11-17 21:13:39.113 JSQMessages[64615:3392106] cellForItemAtIndexPath called for item 28 2015-11-17 21:13:39.115 JSQMessages[64615:3392106] cellForItemAtIndexPath called for item 29 2015-11-17 21:13:39.116 JSQMessages[64615:3392106] cellForItemAtIndexPath called for item 30 2015-11-17 21:13:39.118 JSQMessages[64615:3392106] cellForItemAtIndexPath called for item 31 2015-11-17 21:13:39.119 JSQMessages[64615:3392106] cellForItemAtIndexPath called for item 32 2015-11-17 21:13:39.121 JSQMessages[64615:3392106] cellForItemAtIndexPath called for item 33 2015-11-17 21:13:39.124 JSQMessages[64615:3392106] cellForItemAtIndexPath called for item 34

With inverted mode, it only needs to render the cells of most recent messages:

2015-11-17 21:15:17.462 JSQMessages[64680:3393855] cellForItemAtIndexPath called for item 0 2015-11-17 21:15:17.471 JSQMessages[64680:3393855] cellForItemAtIndexPath called for item 1 2015-11-17 21:15:17.475 JSQMessages[64680:3393855] cellForItemAtIndexPath called for item 2 2015-11-17 21:15:17.479 JSQMessages[64680:3393855] cellForItemAtIndexPath called for item 3 2015-11-17 21:15:17.482 JSQMessages[64680:3393855] cellForItemAtIndexPath called for item 4 2015-11-17 21:15:17.542 JSQMessages[64680:3393855] cellForItemAtIndexPath called for item 5 2015-11-17 21:15:17.547 JSQMessages[64680:3393855] cellForItemAtIndexPath called for item 6

Log messages explains how the annoying screen flicker effect happens. With inverted mode, no more flicker, and the initial rendering time gets cut into half (only render the cells that need to be rendered.) There is still huge user base out there running apps on slow devices. Any improvement to JSQMessages means a lot to those users.

I was investigating performance issues of some existing implementation of conversation page on slow devices. #665 just gave me idea of another area of further enhancement. Thanks, @chadpod :)

@jessesquires once you make TTTAttributedLabel, and inverted mode into 8.0 release, I will love to switch to JSQMessages for the app I'm working on. I really like JSQMessages, Easy to integrate, customize, and makes my code base slim! Thanks!

jessesquires commented 9 years ago

@llz456 - I understand what inverted mode is doing.

What I'm suggesting is that this is trying to optimize the wrong thing.

For example:

  1. Don't try to load 100+ messages at once. Instead, only load the last 10 messages.
  2. Keep a self.allMessages and self.displayedMessages array.
  3. Take your array of 0-99 messages (self.allMessages), remove the last 10 messages (that is, the messages at indices 90-99)
  4. Put these 10 messages in self.displayedMessages (which is what the library will be displaying)
  5. When the user scrolls up, show the "load earlier messages" button
  6. When the user presses this button, load another 10 messages. Again, remove the last 10 messages from self.allMessages and prepend them to self.displayMessages

Does that make sense?

This would be the proper solution that addresses the core problem. An "inverted mode" is merely treating a symptom.

llz456 commented 9 years ago

@jessesquires - your suggestion is exactly most implementations of conversation page do these days. I am not exception.

Now the issue here is that with 10 messages prepared for initial display, but only 5 of them can fit on to the screen, the 'scroll-to-bottom' action causes to render 10 of them, but inverted mode only renders the 5 messages that can be shown on the screen. That is what inverted mode is really about: get rid of screen flicker, and render only necessary cells for initial display.

One of the major feedback from conversation page users is about the noticeable delay for the initial display on slow devices. And that's the challenge I am facing now.

jessesquires commented 8 years ago

@llz456

Now the issue here is that with 10 messages prepared for initial display, but only 5 of them can fit on to the screen

Then why not only load the most recent 5?

jaddoescad commented 8 years ago

It's so easy to paginate with inverted mode thanks!

jessesquires commented 7 years ago

Hello everyone!

I'm sorry to inform the community that I'm officially deprecating this project. 😢 Please read my blog post for details:

http://www.jessesquires.com/blog/officially-deprecating-jsqmessagesviewcontroller/

Thus, I'm closing all issues and pull requests and making the necessary updates to formally deprecate the library. I'm sorry if this is unexpected or disappointing. Please know that this was an extremely difficult decision to make. I'd like to thank everyone here for contributing and making this project so great. It was a fun 4 years. 😊

Thanks for understanding, — jsq

slxl commented 6 years ago

@llz456 used in my project, thanks for contribution!