-
Notifications
You must be signed in to change notification settings - Fork 2.9k
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
[HOLD for payment 2024-04-01] [$250] Android - App lags after adding code block in task description #34324
Comments
Job added to Upwork: https://www.upwork.com/jobs/~013b44c7d5e9e29617 |
Triggered auto assignment to @garrettmknight ( |
Triggered auto assignment to Contributor-plus team member for initial proposal review - @ntdiary ( |
Waiting on proposals |
ProposalPlease re-state the problem that we are trying to solve in this issue.The app lags when code is entered in description textbox What is the root cause of that problem?From what I have investigated so far, I think default value in the component is parsing the text entered into the textbox. When we enter the code above, I think the parser takes longer time to render which causes the lag. App/src/pages/tasks/NewTaskDetailsPage.js Line 116 in 8e2fb67
What changes do you think we should make in order to solve the problem?I think we should remove parser from default value attribute in text input and move it to where "task description" state default value is set. What alternative solutions did you explore? (Optional)NA |
ProposalPlease re-state the problem that we are trying to solve in this issue.Adding code block in task description makes the page laggy. What is the root cause of that problem?PR #29144 modified the task description input logic to support mark down. Task description is parsed to mark down before saving and vice versa when setting the default value to input. However the parsing logic which uses the method CPU Profiling above shows There are 3 locations in Task creation where App/src/pages/tasks/NewTaskDetailsPage.js Line 116 in 8ba2782
App/src/pages/tasks/TaskDescriptionPage.js Line 120 in 8ba2782
Note that Also the useEffect here is dependent on App/src/pages/tasks/NewTaskDetailsPage.js Lines 46 to 49 in d4c28a4
When navigating from NewTaskDetailPage to NewTaskPage(ConfirmTask) screen , the first screen is not unmounted by ReactNavigation. It keeps the page in memory for navigating back. This causes the useEffect to get executed when task object is updated in Onyx. Which also invokes the parser.replace method. So overall a computationally intensive method gets unnecessarily executed multiple times causing the app to lag. What changes do you think we should make in order to solve the problem?Update const URL_WEBSITE_REGEX = `${URL_PROTOCOL_REGEX}?((?:www\\.)?[a-z0-9](?=(?<label>[-a-z0-9]*[a-z0-9]))\\k<label>?\\.)+(?:${TLD_REGEX})(?:\\:${ALLOWED_PORTS}|\\b|(?=_))(?!@(?:[a-z\\d-]+\\.)+[a-z]{2,})`; This would prevent catastrophic backtracking issue with TLD regex. Then memoize the defaultValue prop using React.useMemo, so that parser.replace gets executed only when description changes. const defaultValue = useMemo(() => parser.htmlToMarkdown(parser.replace(taskDescription)), [taskDescription]); Also the useEffect should get executed only when the screen is focused. Update the logic to prevent unwanted execution offscreen. const isFocused = useIsFocused();
useEffect(() => {
// Update state only if screen is focused
if (isFocused) {
setTaskTitle(props.task.title);
setTaskDescription(parser.htmlToMarkdown(parser.replace(props.task.description || '')));
}
}, [props.task.title, props.task.description, isFocused]);
Result Here is the CPU profile after applying the fix. Overall time spent in parser.replace reduced to 2s from 6.3s. What alternative solutions did you explore? (Optional)The other area to focus on is actually optimising the parser.replace logic in ExpensiMark library. However it is in Expensify-Common repository and possibly shared by multiple apps. |
@ntdiary looks like we've got some proposals for this one. Can you take a look when you get a chance? |
Ah, sorry for the delay, I missed this issue, will review soon. |
Thank you all for the proposals. Although the related regular expressions are very complex, I still believe that optimizing them is the fundamental solution. Even with the use of |
📣 It's been a week! Do we have any satisfactory proposals yet? Do we need to adjust the bounty for this issue? 💸 |
Inline code is a valid input, and we support markdown syntax not only on this page, but also on other pages. So we should optimize the execution efficiency of the relevant regular expressions. |
Hey @ntdiary, I was of the assumption that we only show inline code on page load, as I did not see other components parsing the updated description text. Please let me know if that's not the correct behavior. |
I agree then, we must think of some way to optimize this regex. :) |
@ntdiary The real culprit is the huge tlds regex that's being used in const TLD_REGEX='(?:[a-zA-Z]{2,63}|xn--[a-zA-Z0-9-]{4,59})'; And here are the results for a single execution of parser.replace(). With original TLD_REGEX execution time is approximately 1s where as for simpler regex it is 10ms. Also it is important to note that the execution time is directly proportional to the input length. If I copy over the same test input 4 times, execution time with original regex becomes 4 seconds. That's 1s for around 350 characters. Which is quite huge!
So it boils down to the decision whether we can trim down the specific TLD names with in the TLD_REGEX. |
@ntdiary This seems to be working. I'll raise a new PR shortly. |
@aswin-s how's that PR coming along? |
Upwork job price has been updated to $250 |
Dropping price for regression |
Raised PR Expensify/expensify-common#666 |
PR is merged, awaiting deploy to test. |
@AndrewGable for expensify-common changes, when do we expect to be able to test them? Is it immediately? |
There needs to be an App PR to use the latest changes of expensify-common, then we can test |
PR #37814 has bumped expensify-common version, but QA is ongoing, so we can test in the next QA stage. :) |
Great - I'll test again on Monday! |
Tested and confirmed it's much faster. Setting for payment. |
All paid, closing. |
If you haven’t already, check out our contributing guidelines for onboarding and email [email protected] to request to join our Slack channel!
Version Number: 1.4.24-0
Reproducible in staging?: y
Reproducible in production?: y
If this was caught during regression testing, add the test name, ID and link from TestRail:
Email or phone of affected tester (no customers):
Logs: https://stackoverflow.com/c/expensify/questions/4856
Expensify/Expensify Issue URL:
Issue reported by: Applause internal team
Slack conversation:
Action Performed:
if (files.length > 0) {
// Prevent the default so we do not post the file name into the text box
event.preventDefault(); this.props.onPasteFile(event.clipboardData.files[0]);
return;
if (files.length > 0) {
// Prevent the default so we do not post the file name into the text box
event.preventDefault() this.props.onPasteFile(event.clipboardData.files[0]);
return;
Expected Result:
Able to create a task without significant delay
Actual Result:
The app lags after pasting the code block in the description field
Workaround:
unknown
Platforms:
Which of our officially supported platforms is this issue occurring on?
Screenshots/Videos
Add any screenshot/video evidence
Bug6338420_1704939519196.video_2024-01-10_21-17-46.mp4
View all open jobs on GitHub
Upwork Automation - Do Not Edit
The text was updated successfully, but these errors were encountered: