arunoda / react-komposer

Feed data into React components by composing containers.
MIT License
732 stars 70 forks source link

Loading component shows for a long period of time. #124

Closed Dartv closed 7 years ago

Dartv commented 7 years ago

For the initial subscription it takes react komposer about 5-10 seconds to actually show the data. This is just ridiculous because I tested the same subscription with blaze and it took about half a second to render the data. What is the problem with react-komposer? How can I get around this? I know that there is v2 floating around that MAYBE will resolve this issue, but this is critical for now and I absolutely need this to work properly as fast as possible. Btw I'm using fork from this pull request: https://github.com/kadirahq/react-komposer/pull/99 as I absolutely need functionality from there. There is the code:

const onPropsChange = (props, onData) => {
  const {
    discussionId,
    dispatch,
    sort = { createdAt: -1 },
    at = null,
    priorLimit = 50,
    followingLimit = 50
  } = props;
  const subOpts = { sort, at, priorLimit, followingLimit };
  const messagesSubscription = Meteor.subscribe('messages', discussionId, subOpts);
  const lastMessageSubscription = Meteor.subscribe('discussionMessagesLast', discussionId);
  const subscriptions = [messagesSubscription, lastMessageSubscription];

  dispatch(setLoading(true));

  const state = getDiscussionState();

  if (state.messages.length) {
    onData(null, state);
  }

  const isSubscriptionReady = handle => handle.ready();

  if (subscriptions.every(isSubscriptionReady)) {
    const query = { discussionId };
    const options = { sort: { createdAt: 1 } };
    const messages = Messages.find(query, options).fetch();

    const actions = [
      setLoading(false),
      setLastMessageId(get(LastDiscussionMessage.findOne(), 'lastMessageId')),
      setMessages(messages)
    ];

    dispatch(batchActions(actions));

    onData(null, getDiscussionState());
  }

  return () => {
    const stopSubscription = handle => handle.stop();

    subscriptions.map(stopSubscription);
  }
};

const shouldResubscribe = (props, nextProps) => {
  const omitProps = omitC(['at']);
  // we don't want to trigger subscription when user selects a message
  return !shallowEqual(omitProps(props), omitProps(nextProps));
}

export default composeAll(
  withProps(props =>
    ({ discussion: Discussions.findOne({ _id: props.discussionId }) })),
  composeWithTracker(onPropsChange, PreloaderPage, null, { shouldResubscribe }),
  connect(pickFromDiscussion(['at', 'sort', 'priorLimit', 'followingLimit']))
)(MessagesListWrapper);
Dartv commented 7 years ago

After a long testing I finally found the issue that was causing it. It was actually a call to a meteor method which was blocking the rendering process. It was really hard to debug this because the subscription was initialized and then the block was happening. So the tests were showing that the subscription takes 5-10 sec, so I assumed it was a problem with the package because in blaze everything worked fine. Another strange thing is that in blaze the method wasn't causing block.