Progressive Enhancement - What It Is and Isn’t, a Practical Introduction With Svelte
AI Generated Video Summary
1. Introduction to Progressive Enhancement
Hey there. I'm Elliott Johnson and I'm so glad you've chosen to be here with me today. A huge thank you to the organizers of the JS Nation Conf for their hard work coordinating everything and allowing me to speak.
By way of introduction, I'm a software engineer at Versell working in our growth department. In my spare time, I help maintain Svelte and SvelteKit. I started my professional life as a business intelligence analyst and moved on from there to analytical data architecture. It was around this time that I realized that wasn't really what I wanted to be doing and started my long slide into software engineering, ending up a front-end engineer with an uncomfortable amount of backend experience.
The front-end space is very different to any of those spaces I worked in before, specifically regarding feature support. In other spaces, this isn't as big a concern. When you control the hardware and software, you can just deploy what you want for the most part. If you need more bandwidth, just buy it. If you need more processing power, just upgrade your instance. If you need a new version, upgrade your software. In the front-end space, though, you're shipping code to places you can't control. To Dan with the slow internet. Or Carla with the phone that's ten years old that she can't afford to replace. Or to Ebenezer, the owner of all the latest tech that can run anything you throw at him. To somebody in a developing country where the best phone they can afford is the equivalent of ten-year-old hardware. These people will experience the sites I write in different ways, and if I don't write my application with all of them in mind, I am going to degrade their experience.
2. Feature Detection and Graceful Degradation
So, like, if you wanted to use the geolocation API, you could check to see that the key geolocation is defined in the Navigator object. There are a multitude of ways, but the important thing is thinking about, hey, I want to use this feature. I know it's not supported in a lot of browsers. Maybe it's really new. I should probably check to see that it's there before I use it.
But in some circumstances, that's not really realistic. We might be using a library that accesses features like this somewhat unpredictably and we don't really have a way of wrapping all of those in guard checks to provide fallbacks and enhancements. So, another way that we can do this is to not detect whether additional features are supported, but be ready for them to fail and fall back to better-supported defaults when they do. This is technically known as graceful degradation, not progressive enhancement, but they're basically the same thing in opposite directions, and they're so complementary that I like to lump them together. If that offends you, that's too bad.
3. Polyfills for Browser Functionality
Polyfills are a commonly used way to emulate new browser functionality in old browsers. They can have downsides like reduced performance or edge cases where they don't work correctly, but if you understand the trade-offs and are prepared to accept them, they can be a good solution.
And the last way that I've seen commonly used is polyfills. These are basically when you have some new browser functionality like, I don't know, object.create that might not be supported in old browsers, and you want to be able to So you write code that emulates that behavior and inject it if the feature is not supported. These typically have some sort of downside, like reduced performance or edge cases where they don't work correctly. But if you know the trade-offs, and you're prepared to accept them, and you're knowledgeable about what accepting them is going to do to you, then they can be a good solution.
4. What Progressive Enhancement is Not
5. Building Apps in SvelteKit
The goal of today's talk is to introduce you to building apps in SvelteKit and show you how easy it is to develop progressively enhanced apps. I created an app to generate humorous acronyms using a trained naïve Bayes classifier. The app meets my requirements of displaying random acronyms, enabling sharing, and working well on slow internet connections. Let me give you a tour of the implementation, starting with the root page that generates a random acronym and provides functionalities to reject, copy, and rotate it.
Now that we've established what we're talking about, let's abandon theory and jump into practice. The goal of today's talk is to both introduce you to building apps in SvelteKit and to show you how easy SvelteKit makes it to develop progressively enhanced apps.
We all know the acronym LGTM. Looks good to me or looks good to merch, depending on your context. For months, I've been coming up with bogus acronyms for this, like lumpy gorillas teach math, lunar grandeur tantalizes minimally, laggards growl to murder, etc., and posting these acronyms as my approval comments on PRs. I got a bit tired of having to be creative, so I came up with an app to create these acronyms for me. Simply using random combinations of words starting with LGT and M is certainly not good enough. You would end up with too much nonsense and not enough comedy, so I went with a little more thorough route, training a naïve Bayes classifier with a few thousand good and bad acronym combinations and running 100,000 random acronyms through that. It's not perfect, but it's plenty good.
We have the ability to share exactly what we're seeing because we've got two query parameters that represent both the orientation and the ID of this acronym so that it will never change. We can always share this. They'll come here and they'll see it.
We have a lib folder and a routes folder. Lib folder is where all of your, your, your library code lives, your components, uh, your database connection. You know, anything that you would consider shared code. The routes folder is like many other meta frameworks, the way that we define our routes in spelt kit, we use a file system-based router that uses folder paths as your route and the files inside of those folder paths determine the behavior of that route. So you can see here at the root that we saw that displays the square with the acronym in it, we have a layout file, a server file, and a spelt component. So basically what this means is that everything under this route is going to be wrapped in this layout, which is just a main around the content with some formatting applied to it and some CSS imported. And then we're going to have a server side load for this route, and a page for this route. And then we also have our train route, which you just saw, which also has a server file and a page file, and a success route, which you'll see later. I'm going to skip talking about this for now. If we have time, I'll come back to it, but I don't think we are.
7. Svelte Components and DOM Content
We have two special exports here. We have data and form. Both of those are populated from our page.server.ts file and they are automatically typed, so you can see our data is page data and our form is action data. So if I type like data.blah, those are things that I'm returning from my load function on the server. If I type form.law, these are all of the responses that my form handlers can send from the back end. It's quite a nice little feature. I quite enjoy it. If you look at our DOM content here, this is pretty simple. It really is pretty close to a native form submit. We have a form with a method of post. All of these have an action that points to the current URL with a query parameter. This might look a little bit weird. What this is really saying is I want to go to train because that's the route that I'm on right now and I want to append a query parameter called slash train. That query parameter is going to point us at a form action in this file.
8. Form Submission and File Uploader
As you can see, we have a use enhanced function that emulates native form submission behavior on the client side. It reloads the page without destroying all DOM contents. The configuration argument allows for defining behavior during submit, such as preventing form reset and updating selected values. The file uploader provides a seamless upload experience without requiring a page reload.
9. Form Submission and Progressive Enhancement