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

[Proposal] Modernize Frontend #1283

Open
milomg opened this issue Jul 1, 2022 · 2 comments
Open

[Proposal] Modernize Frontend #1283

milomg opened this issue Jul 1, 2022 · 2 comments

Comments

@milomg
Copy link
Contributor

milomg commented Jul 1, 2022

I took a look at the frontend, and had a few ideas for possible changes to modernize the frontend which will make the build faster and the frontend slightly faster, but mainly make it easier to add new features. I'm happy to explore any of these proposals in PRs if you are interested


Proposal 1: Switch from webpack to esbuild

Esbuild is a new bundler that is designed to be extremely performant, and has achieved great strides in compatibility and usability. It is used in production at companies like Figma.

We should use esbuild instead of webpack because it is less complicated and can be up to 100x faster while producing a minified output using the production build of React (which is substantially faster).

To do this, all you need to do is create a build.js file that looks something like this:

import { build } from "esbuild"

build({
  entryPoints: [
    "./js/search/search.jsx",
    "./js/grid/grid.jsx",
    "./js/graph/main.jsx",
    "./js/post/post.jsx",
    "./js/draw/main.jsx",
    "./js/generate/generate.jsx",
    "./style/app.css",
  ],
  outdir: "public",
  bundle: true,
  watch: true,
})

And then in package.json, change the watch script to "watch": "node build.js", and slightly tweak the script location in app/Scripts.hs. Note that in production, minify: true should also be enabled.

Proposal 2: Switch to Preact

Preact is a lightweight drop in react replacement (existing react libraries will still work). It substantially reduces bundle size, and in my local testing dramatically improved the performance of zooming the graph. The quick process for switching to preact depends on the build tool but usually is done by adding the following config:

"alias": {
  "react": "preact/compat",
  "react-dom": "preact/compat"
}

One important caveat to note is that while executing your app is the same for both react and preact, the internal structures are slightly different and so testing libraries may need to change. (A more substantial change might be to switch to Svelte or Solid which market themselves as performant and simpler modern alternatives to React)

Proposal 3: Switch to pnpm

pnpm is an alternative to yarn. It uses a clever trick around symlinks to efficiently cache modules without needing to store them in git. I've found it to be more stable and easier to use than yarn. This would also clean up the git repo by removing the .yarn/ folder

Proposal 4: Switch to TypeScript

This is a huge change, but provides great benefits for developing the code because it ensures that things like PropTypes are checked at compile time and have high quality IDE completion. Better IDE completion means that you can type this.props.parents.forEach and typescript will know that you are iterating over an array of nodes and suggest that one function you can call on a node is focusPrereqs (this helps eliminate typos and make sure that you never run into undefined variables)

Other ideas

  • It would be nice to remove jquery in favor of the native javascript fetch() function.
  • Converting the codebase to modern React style using hooks instead of class components may yield some performance improvements
  • One technique might be to split out the client from the server and run them on separate ports. This allows development versions of the client to include extra features like hot module reloading, while production bundles can be served extremely efficiently from nginx or cached at the edge on Cloudflare or Netlify, and also have a dynamic Haskell server. You can avoid issues about cross origin requests by having the client server proxy requests to /api to the other port.
@milomg
Copy link
Contributor Author

milomg commented Mar 26, 2024

I ended up making courseflow as a lightweight alternative to prototype these ideas. https://courseflow.netlify.app/

@milomg milomg closed this as completed Mar 26, 2024
@david-yz-liu
Copy link
Contributor

@modderme123 thanks a lot for creating this issue, and sorry I haven't had a chance to pay much attention to it. Your suggestions were very good, as well as the very cool app that you've created. I'm going to reopen this issue so that it stays (at least somewhat) visible to me!

@david-yz-liu david-yz-liu reopened this Mar 26, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants