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

How to improve performance? #275

Open
TheTushar2696 opened this issue Oct 8, 2022 · 14 comments
Open

How to improve performance? #275

TheTushar2696 opened this issue Oct 8, 2022 · 14 comments

Comments

@TheTushar2696
Copy link

Hi @pdpino @hoangnm

I am using this library, the overall features looks damm good and I also appreciate how we are continuously trying to make it better, I have a question, How to improve the performance in my app, Just listing down the things I am doing for the week view,
Note: Consider that I have a lot of events
-As soon as the week view loads I am formatting the events in the format the library takes input using reducer functions as mentioned in the examples

  • I am initially fetching all the events in one month
  • I am fetching more events by using the onSwipeNext prop which gives us the date, I have a useEffect with the dependency of the current date that gets passed to the calendar
  • If the user passes the date range for the current range I call the ApI to fetch more events for the new set of range (using reducer functions)
  • Also there is one more feature so if in our app if a user is creating a new event of a future date, we are using goToDate to navigate to that date where the event is created.

I feel the app becomes a bit sluggish when I am doing all these stuff
Screenshot 2022-10-08 at 1 47 45 PM

I am passing the above props to the calendar

Currently I am using react-native-week-view 0.22.0

Please suggest me anything that can help to get rid of this

Thanks in advance

@pdpino
Copy link
Collaborator

pdpino commented Oct 12, 2022

Hi @TheTushar2696, sorry the late reply

We are currently trying to improve this (#209), so I don't have a definitive answer right now. I hope we are able to give more suggestions on this soon. For now:

  1. Suggestion: selectedDate can be a constant (sounds weird, but is correct) --> should prevent useless re-render

    • this prop indicates the initial selected date, i.e. the date shown in the first render
    • the prop name should be initialSelectedDate, or something including initial
    • to actually change the date in the screen use the method goToDate() (you are correct on this)
  2. Can you show your code for the API fetch and map/reduce call to the library format? I guess is roughly something like this:

const [events, setEvents] = useState([ ]);

const callAPI = async () => {
  const apiEvents = await callAPI(...);

  // I want to see what is done here: map, reduce, etc
  const libEvents = apiEvents.map(event => ({ startDate: ..., endDate: ... }))
  setEvents(libEvents);
}

a user is creating a new event of a future date, we are using goToDate to navigate to that date where the event is created

  1. Currently this will be very slow if the target date is far away. I intend to improve this soon

@TheTushar2696
Copy link
Author

@pdpino I have created a reducer function instead of using useState() to fetch events, Inside that getFormattedTasksForWeekView() I am using a for loop
Screenshot 2022-10-13 at 11 12 56 PM
Screenshot 2022-10-13 at 11 13 54 PM

@pdpino
Copy link
Collaborator

pdpino commented Oct 13, 2022

This is what I'm understanding: each time the app queries the API (e.g. after scrolling and reaching new dates), the app triggers the action CalendarActions.SetEvents, which processes all events from the DB (not only the newly received ones). Then all events are returned in the variable formatedTasks.
Is this correct?

@TheTushar2696
Copy link
Author

TheTushar2696 commented Oct 13, 2022

@pdpino No, It only processes the new events , since we are updating the store with the new events and those are only passed to the reducer function,

@pdpino
Copy link
Collaborator

pdpino commented Oct 14, 2022

@TheTushar2696 for now I can comment the following:
Each <Event /> displayed inside the WeekView is a PureComponent --> you should avoid shallow changes in props when there are no actual changes in the task/event. Roughly, you should avoid useless shallow changes in these props:

<Event
  event={event}
  EventComponent={EventComponent}
  containerStyle={eventContainerStyle}
  editEventConfig={editEventConfig}
  dragEventConfig={dragEventConfig}   // you are not using it yet
/>
  • Does any of the event changes shallowly, when in fact the task itself has not been modified? (I'm asking about each event, not the whole array events={tasks})
    • You can provide if you want the code related to tasks to check this
  • The rest of the props mentioned, I suggest you create them outside <WeekView />'s parent component, or with useMemo()

@TheTushar2696
Copy link
Author

TheTushar2696 commented Oct 14, 2022

@pdpino
Just FYI as mentioned in the above, I am making changes to the event style based on some key, as there was some business requirement, do you think that can be a reason of the slugginesh
Screenshot 2022-10-15 at 12 43 28 AM

If yes, is there any workaround for the same

@TheTushar2696
Copy link
Author

hi @pdpino

Any thoughts on the above

@pdpino
Copy link
Collaborator

pdpino commented Oct 21, 2022

I'm trying to improve performance on our end, alongside fixing the bug in #259

In your CustomEventComponent: I wonder if the require('../Assets...') could be non-optimal, options might be pre-fetching the images, async load them, etc (but that's out of the scope of this library). You might have already thought of this.

Can you show the full code where the variable tasks is updated? (the one in events={tasks})

@TheTushar2696
Copy link
Author

TheTushar2696 commented Oct 21, 2022

Hi @pdpino

Actually Ive noticed if we are not giving any customEventComponent or DayComponent the sluggish behaviour reduces to some extent

Sharing code for updating events: I fire an action to setEvents(also gets called when component is mounted), this action when triggered calls getFormattedTasksForWeekView()
Screenshot 2022-10-21 at 12 56 45 PM

`export const getFormattedTasksForWeekView = (
  apiResponse: TaskResponse[],
  suggestionsTasks: any,
) => {
  let result: any = []
  if (suggestionsTasks?.data?.length > 0) {
    let myMap = new Map<string, Suggestion>(
      suggestionsTasks?.data.map((obj: Suggestion) => {
        if (obj.taskDetails.recurringTaskId) {
          return [obj.taskDetails.recurringTaskId, obj]
        } else {
          return [obj.taskDetails.id, obj]
        }
      }),
    )

    apiResponse.map(item => {
      if (item.recurringTaskId && myMap.get(item.recurringTaskId)) {
        result.push({ ...item, isSuggestion: true })
      } else if (myMap.get(item.id)) {
        result.push({ ...item, isSuggestion: true })
      } else {
        result.push({ ...item, isSuggestion: false })
      }
    })
  }

  if (result.length === 0) {
    result = apiResponse
  }

  let formatedTasks = []
  for (let i = 0; i < result.length; i++) {
    formatedTasks.push({
      ...result[i],
      description: result[i].title,
      startDate: new Date(result[i].startAtUtc),
      endDate: new Date(result[i].endAtUtc),
      color: getLabelFromRelationIdAndFamilyId(result[i].familyMemberId, result[i].relationshipId)
        ?.color,
      isTimeSlot: true,
    })
  }
  return formatedTasks
}
`


@hoangnm
Copy link
Owner

hoangnm commented Oct 21, 2022

I'm also thinking that having different logic inside a custom event component could be an issue. Could you measure how faster it is with the default event?

@TheTushar2696
Copy link
Author

@hoangnm Not too smooth but a bit better that this logic that I have

@TheTushar2696
Copy link
Author

@pdpino @hoangnm Is there any other way with which we can achieve the above and not hamper the performance at the same time?

@pdpino
Copy link
Collaborator

pdpino commented Nov 3, 2022

@TheTushar2696 sorry not yet. I'm working on performance at the same time I debug #259, I expect to have updates soon

@sushitrash06
Copy link

Why can't I customize the width of the columns? When I use the timetable, only 6 days appear because the last day gets cut off. @hoangnm

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

No branches or pull requests

4 participants