15 Apr 2019
7 min read
Single Page Apps
With a "progressive web app" of a moderate level of complexity you need a team of people to make it work. You end up with a massive portion of your codebase being just for the frontend. Seriously. Getting things to load in the right order is a difficult problem that we're just throwing even more software at (see Redux and friends). What if you could just do away with all of that?
Shout out to Elm for being pretty dang awesome, however.
Plain Old HTML and CSS
For Slimvoice I wanted to go against the grain of the modern JS hype train and make the app entirely server rendered. You might say "Ah! But Matt! The user must reload every page when using your app, which must be slow!" to which I say phooey. All of my assets are gzipped and cached, which leaves only the HTML to transfer as you interact. I don't have loading spinners. It's faster than many PWAs I use by a long shot.
The Checkbox/Label Trick
<div id="myToggledUI"> containing some UI that you would like to show and hide.
Immediately above that, create an
<input type="checkbox" id="myToggle" style="display: none;">. This will make an invisible checkbox in the DOM.
Whatever DOM node you would like to use as the toggle control, wrap it in a
<label for="myToggle"></label> tag where the for attribute matches the id of the checkbox.
Use this CSS to hook it all up.
This CSS says that the # myToggledUI element immediately preceded by a checked # myToggle element should be shown, otherwise hidden. The ~ operator is pretty cool! Here's a full working example.
Here's a modal built with a
<div>, and a checkbox. The "Cancel" button is another
<label> for the same checkbox, so clicking it closes the modal. There is a gray overlay behind the modal (position: fixed;) that also happens to be a
<label> for the same checkbox, so clicking outside of the modal closes it as well. No React components. No click event listeners. Just plain and simple HTML.
I haven't done so here, but you can add any CSS transitions that you like to this technique. No ReactCSSTransitionGroup here.
Forms & Input Validation
Many inputs have validation options built-in. The Mozilla documentation is comprehensive.
- Don't forget about the required attribute, that prevents a form from submitting until a particular field is filled out.
- Number inputs have
- Text inputs can be of type
- Text inputs have minlength and maxlength.
:invalidCSS selectors allow for a better UX.
1.Why can't we have a standard search element that filters a list on the client side (similar to how
filter: worked on Angular 1)?
2.Wouldn't a standard HTML element for drag-and-drop sorting be awesome?
3.More advanced validation functionality, like comparing equality of two different form fields.
4.The ability to do the modal/checkbox trick above without it feeling like a hack and writing weird CSS.
Did it work? Absolutely. A full reload of the biggest page is 230 KB over the Internet. Since I'm caching and gzipping everything, each subsequent pageview is around 6 KB; far smaller than the SPAs I've seen with equivalent functionality. Slimvoice is fast and small but doesn't compromise on UX. Users are loving it so far. See it for yourself at https://slimvoice.co.
Absolutely nothing is complex about my code. I would feel comfortable handing the entire codebase off to someone else without explaining anything. I don't know anyone who can realistically say that about a React/Webpack frontend.
- You probably don't need a "Progressive Web App." Seriously evaluate if your app needs such complexity.
- The boss/client may demand a PWA because it's cool and popular and will back it up with a bunch of hand-wavy reasons. Make sure those reasons are legitimate.
- Stop tracking people. Don't allow other companies to do so on your behalf. You will survive without Google Analytics. You will survive without Intercom. Serve everything from your own domain.
- Don't be scared. You can build it yourself! You don't need a framework!
- Don't follow the hype. Make critical decisions about why one approach is better than another, despite what the marketing page says or what everyone else is doing. The people selling the cool new stuff are typically sweeping the downsides under the rug. Everything has a cost.
And of course, thanks to my amazing wife who designed the splash page, helped with the UI, and encouraged me to write this post!
Follow the author on Twitter here