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

UX: Show loading spinner while loading dependencies for ace-editor #26099

Merged
merged 1 commit into from Mar 10, 2024

Conversation

tgxworld
Copy link
Contributor

@tgxworld tgxworld commented Mar 8, 2024

Why this change?

On a slow network, using the AceEditor component will result in a blob
of text being shown first before being swapped out with the ace.js
editor after it has completed loading.

There is also a problem when setting the theme for the editor which
would result in a "flash" as reported in
ajaxorg/ace#3286. To avoid this, we need to
load the theme js file before displaying the editor.

What does this change do?

  1. Adds a loading spinner and set the div.ace with a .hidden class.
  2. Once all the relevant scripts and initialization is done, we will
    then remove the loading spinner and remove div.ace.

Reviewer notes

There are no tests here but I discovered this problem when trying to write a system tests and interacting with the ace editor. Because of the previous flashing behaviour, any interactions with the ace editor is unreliable and leads to flaky system tests.

Recording

Before

Kapture 2024-03-08 at 14 26 10

After

Kapture 2024-03-08 at 14 27 55

Comment on lines 59 to 61
await waitUntil(() => {
return document.querySelectorAll(".ace_line")[0];
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🏌️

Suggested change
await waitUntil(() => {
return document.querySelectorAll(".ace_line")[0];
});
await waitUntil(() => document.querySelector(".ace_line"));

Comment on lines 63 to 67
const indexOf = document
.querySelectorAll(".ace_line")[0]
.innerHTML.indexOf("[");

assert.ok(indexOf >= 0);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const indexOf = document
.querySelectorAll(".ace_line")[0]
.innerHTML.indexOf("[");
assert.ok(indexOf >= 0);
assert.dom(".ace_line").hasText("[");

@@ -166,14 +178,17 @@ export default class AceEditor extends Component {
}

@bind
setAceTheme() {
aceTheme() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we turn it into a getter?

Comment on lines 1 to 5
{{loading-spinner size="small"}}
{{/if}}

<div class="ace hidden">{{this.content}}</div>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we not render rather than setting the hidden class?

Suggested change
{{#if this.isLoading}}
{{loading-spinner size="small"}}
{{/if}}
<div class="ace hidden">{{this.content}}</div>
{{#if this.isLoading}}
{{loading-spinner size="small"}}
{{else}}
<div class="ace">{{this.content}}</div>
{{/if}}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It turns out I can. Initially, I was hiding it because the theme file took time to load and I wanted to avoid the flash. Now that I am loading the theme file upfront, I don't need to hide the div anymore.

window.ace.require(["ace/ace"], (loadedAce) => {
loadedAce.config.set("loadWorkerFromBlob", false);
loadedAce.config.set("workerPath", getURL("/javascripts/ace")); // Do not use CDN for workers
loadScript(`/javascripts/ace/theme-${this.aceTheme()}.js`).then(() => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We didn't have to load the theme separately before?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup it was loaded on demand previously which resulted in the "flash". You can see it clearly in the before screenshot I posted. The solution stated in ajaxorg/ace#3286 is to load the theme file first.

@tgxworld tgxworld force-pushed the fix_ace_editor branch 2 times, most recently from 663d819 to 437f3f4 Compare March 10, 2024 22:13
Why this change?

On a slow network, using the `AceEditor` component will result in a blob
of text being shown first before being swapped out with the `ace.js`
editor after it has completed loading.

There is also a problem when setting the theme for the editor which
would result in a "flash" as reported in
ajaxorg/ace#3286. To avoid this, we need to
load the theme js file before displaying the editor.

What does this change do?

1. Adds a loading spinner and set the `div.ace` with a `.hidden` class.
2. Once all the relevant scripts and initialization is done, we will
   then remove the loading spinner and remove `div.ace`.
@tgxworld tgxworld merged commit 7d8dd0d into main Mar 10, 2024
16 checks passed
@tgxworld tgxworld deleted the fix_ace_editor branch March 10, 2024 22:56
@tgxworld
Copy link
Contributor Author

Thank you for reviewing @OsamaSayegh and @CvX 👍

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