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

WIP: split .js, load some asynchronously & on-demand, use ESM #7586

Closed
wants to merge 2 commits into from

Conversation

WofWca
Copy link
Contributor

@WofWca WofWca commented May 3, 2022

Proposed changes

This is super WIP, for now look at it as a discussion rather than a full-fledged MR.

In order to improve page loading performance, it would be cool to load some JS asynchronously and on-demand, and tree-shake some of it. Examples: shortcuts, syntax highlighting, username autocompletion.
Here's the audit I ran:

image

As you can see, on my PC it takes ~400ms to load a prefetched page (i.e. it's only rendering, not including network download). You can imagine it's a little worse on mobile.

First step to this is rewriting the scripts with imports.

This also makes the code easier to maintain as there's fewer global vars.

TODO:

Checklist

  • Lint and unit tests pass locally with my changes.
  • I have added tests that prove my fix is effective or that my feature works.
  • I have added documentation to describe my feature.
  • I have squashed my commits into logic units.
  • I have described the changes in the commit messages.

Other information

@WofWca WofWca changed the title WIP: split .js, use ESM WIP: split .js, load some asynchronously & on-demand, use ESM May 3, 2022
Copy link
Member

@nijel nijel left a comment

Choose a reason for hiding this comment

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

Generally, any improvements to the JavaScript are welcome. The tricky part is that there are basically no tests for it, so it's super easy to break something. The current split out editor files are a typical example of that - it was tested by the author, me when merging and several issues were discovered months after merging in some not that frequently used features.

I think imports is something we can go for directly without a compatibility layer - we already started to use arrow functions two years ago and that was IMHO bigger drop in supported browsers than this.

<script defer data-cfasync="false" src="{% static 'vendor/mousetrap.js' %}{{ cache_param }}"></script>
<script defer data-cfasync="false" src="{% static 'vendor/mousetrap-global-bind.js' %}{{ cache_param }}"></script>
<script defer data-cfasync="false" src="{% static 'vendor/clipboard.js' %}{{ cache_param }}"></script>
<!-- TODO separate bootstrap? https://getbootstrap.com/docs/5.1/getting-started/javascript/#using-bootstrap-as-a-module -->
Copy link
Member

Choose a reason for hiding this comment

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

We're still at Bootstrap 3.4.1, see #2916

import Cookies from "./vendor/js.cookie.js";
import autosize from "./vendor/autosize.js";
// TODO perf: import Mousetrap dynamically.
import Mousetrap from "./vendor/mousetrap.js";
Copy link
Member

Choose a reason for hiding this comment

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

Mousetrap is IMHO used on nearly every page - it is used to catch Ctrl+Enter for form submission.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, I saw that. Still, adding a bind asynchronously is possible.

@WofWca
Copy link
Contributor Author

WofWca commented May 8, 2022

EDIT: nvm, some libs do window.LibName = ..., so you can just import them and use that instead of their exports. See

import "./vendor/tribute.js"; // It does `window.Tribute =`
/* Username autocompletion */
var tribute = new Tribute({
.

A problem here is that the dependencies don't use ESM (native export and import), they do UMD or something else, so if you attempt to import them natively, the browser says that "the imported module doesn't provide export named ...".
So looks like we can't do without a transpiler.

@github-actions
Copy link

github-actions bot commented Jun 9, 2022

This pull request has been automatically marked as stale because there wasn’t any recent activity.

It will be closed soon if no further action occurs.

Thank you for your contributions!

@github-actions github-actions bot added the wontfix Nobody will work on this. label Jun 9, 2022
@github-actions github-actions bot closed this Jun 23, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
wontfix Nobody will work on this.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants