By luke on 2019-02-27
Sluggish, unresponsive, and slow web apps aren’t exactly a new talking point, whether it be on the desktop
or the web. With the rewrite of rigby’s frontend, I’ve attempted to reduce these issues, and (in my opinion)
I’ve done an OK job. I’d like to talk about what steps I took to get here.
The original rigby design used Go’s standard HTML templating library, and the new design is a ReactJS SPA (Single Page Application).
Both choices have their own pros and cons - heres some lists:
Pros:
- Lightweight pages
- Great for SEO
Cons:
- Extremely difficult development process
- Lots of boilerplate HTML
- Difficulty in adding interactivity (like voting up posts without leaving the page)
- Small feature set of capability in Go templates
- Etremely difficult debugging experience
- Not really scalable to a large project
Pros:
- Much easier development process
- Richer interactivity
- Less repetition of HTML boilerplate
- Scalable to larger projects
Cons:
- SEO is a lot worse
- Potentially large bundle sizes (more on that later)
- Having to compile a website :(
- Worse performance on older machines and mobile devices
Of course, I’ve already chosen React, but I also took several steps to reduce problems I knew would come up.
SEO is a tough problem to crack, but it’s also not one of my largest priorities right now. The site is small, I’m not actively marketing
it, and I honestly don’t want to deal with the problems that would arise out of a 100x user increase. That being said, SEO problems
also come up in things like metadata scraping for platforms like Discord or Twitter. I haven’t addressed this yet, but I don’t think
it will be an impossible task. If you know of any solutions, please let me know!
A lot of articles complaining about web apps bring up this argument, and it’s not an invalid one - horribly written React sites
can be ridiculously large. Rigby is rather limited in its scope right now, but I’ve still considered this issue to be of high importance,
and it will continue to be so going forward. All of rigby’s page structures and CSS are stored in a JS bundle created by webpack, so all
sizes are for the entirety of the site, without the dynamically loaded content like posts and comments.
The site is written in React, but the actual library in use is [Preact], which is a lovely project with a conveniently small footprint.
To use external React libraries like react-markdown
, which is used to render this post, preact provides preact-compat
(short for compatibility) which enables me to write completely valid React code without the larger runtime, which shaved off quite a bit
of kilobytes from the resulting bundle size.
Furthermore, all static assets (the JS bundle, and all the icons) are cached to essentially never expire. This ensures you’ll only have
to load the bundle once, even if you visit the site on multiple separate occasions. A problem with this heavy caching is that updates
to the JS bundle won’t reach the user quickly (if at all), but with hashed script paths (main.2c04d97e7ed8707a69d2.js
) we don’t need to
worry about this. The new script will be downloaded and cached by the browser whenever a new version is ready. Thanks webpack!
All JS scripts and libraries are minified by webpack when building, which reduces the bundle size from around 650kb to 150kb. To reduce this further, all static assets
are also compressed using gzip
, which reduces the bundle size of our JS to around 1/4th of its actual size. Using all these steps, we
manage to take a 650kb JS bundle, being requested on each reload, down to a 40kb bundle requested only once. Not bad!
We all have 32gb of ram so why should I care? This might be a topic for another time…
Comments
This is a great post. You might know this, but Bding re-wrote a section of the OJSE front end with React. I don’t really like the SPA model, for the reasons you stated, and OJSE still doesn’t use it, but I’m going to be thinking about this as I use React. I had considered switching to Prereact, and with your recommendation I definitely will (unless I can’t get it working).
I still don’t like the flash of empty page that comes with a SPA app; I think the browser’s loading indicator makes more sense and is friendlier.
Thanks! That means a lot. I did see bding's react stuff - what were you guys using before? A templating library? Also, as for the loading animation, that can be fixed if I just add it, haven't gotten around to that yet :)
I was using a combination of ES5 JS and Django’s template language before React. I’m still not convinced it will be the best long term decision. In part because of bloat, the page went from 5kb to like 50 (even with preact optimizations), and also because I don’t know if people will be using React in another year or two.
Are you accounting for the initial cost of both without considering the “long term” savings of an SPA? I think for rigby the user only has to load ~7 pages before the SPA is more efficient than HTML (disregarding API calls). I think your consideration about the longevity of the framework shouldn’t be too much cause for concern, Facebook is still a large player and the ecosystem is pretty mature, especially compared to something like Vue.
Those are both fair points. Right now there’s only one page on OJSE that uses React, so it’s hard to gauge how much code will be repeated or reused between pages. And I don’t really fear another framework becoming more popular, but really people switching away from frameworks as we know them. 3 years ago React wasn’t on my radar, it was jQuery that people were using to help write code and manage browser compatibility.
\"100x user increase\" hAHa
..?
new reply
I would recommend adding a spacing in between comments, it would make it way easier to read, but so far this looks awesome!
new reply
A back arrow would also be nice! And padding at the bottom of the page.\n
new reply
new comment