00:00:03.480
I'm sorry about the pineapple thing. They asked for a controversial opinion, and that's the one I went with.
00:00:09.360
Because it does not belong on pizza, I'm sorry. We can talk about that later, though. Um, hello, thank you for having me.
00:00:15.559
I've never been to RubyConf before, so this has been really fun for me. I want to start off my talk by saying thanks to Toast Creative for allowing me to use the illustrations in my talk.
00:00:21.320
It is why it looks so pretty. And very importantly, this is my dog, Jello. The reason I'm mentioning this is because I use the word "jello" a bit in my talk.
00:00:27.400
People get confused and think it's the food, so today we're going to be talking about HTML.
00:00:35.200
We're going to look at how you can utilize it to improve the performance and accessibility of your websites and applications.
00:00:41.280
Now, I know HTML has nothing to do with Ruby, and everyone knows HTML, but I think it's true that HTML is very simple.
00:00:51.960
I'm very upfront about that. But because it's simple, we often make the mistake of assuming that it's not valuable.
00:01:03.120
I'm hoping to dispel that way of thinking today because it's something that we use a lot, and it plays a pivotal role in making good functional websites.
00:01:08.960
The functionality of a website is constructed from what we provide the browser, typically via HTML.
00:01:14.479
We specify whether we want a heading, what kind of heading it should be, a paragraph, a date, a form, a label. There's a whole suite of elements we can choose to best represent our content.
00:01:20.880
And then, of course, there's the div, which has no meaning and doesn't mean anything. When you use a div, it means the content can be anything.
00:01:31.880
But if you choose a generic element, you're going to get generic output, and you lose the benefits of the language.
00:01:38.040
This output can be hugely problematic for assistive technology and for accessibility.
00:01:43.320
Assistive technologies attempt to read our HTML to infer information about the page and its content. Not everyone and everything will interact with your page the same way; there are many technologies that try to read and consume our content, relying on us to use the language correctly.
00:02:01.240
This includes Google search bots, reading apps like Safari's reading mode, text-to-speech tools like Alexa and Siri, or accessibility tools like screen readers.
00:02:08.160
It's not just our eyes that are going to consume our content. The DOM and the HTML play a big part in how successful that can be.
00:02:25.760
Now, as the browser creates the DOM, it also modifies the DOM tree to form an 'accessibility tree' which takes the native semantics of HTML and creates an interface for reading and navigating a page.
00:02:41.120
A screen reader, for example, is able to interpret the accessibility tree and reproduce it as speech. Major browsers like Chrome and Firefox have accessibility tree inspectors that allow you to look at the accessibility tree.
00:02:58.200
The accessibility tree is made up of what we provide the DOM via HTML. If we don't utilize HTML well, what it generates is not very good.
00:03:10.040
A poorly structured page about my dog Jello, for instance, may just be made of divs, including the links at the top which have an onclick event. All you get from the accessibility tree is a bunch of sections and text leaves.
00:03:29.400
If you compare that to a page that uses more meaningful HTML, you can see there's a lot more information: paragraphs, graphics, block quotes, and landmarks. There's a more defined and meaningful structure.
00:03:49.319
A really good way to demonstrate this is actually with a screen reader. So we're going to listen to that. We're going to use Apple's VoiceOver for Mac, and we're going to look at the div page first.
00:04:10.000
So let's have a listen: "Home, good dogs, bad dog myths. Dogs, they are good. We are dedicated to educating the world on why dogs are good and how they can make your life good."
00:04:22.040
Mandy Michael, August third, 2018. Why are dogs good? Dogs are loyal, intelligent, devoted, and affectionate. They are known to improve our physical and mental health.
00:04:34.160
Mitch and Jello, also known as JelloSL, screen percent 20 shot percent. Okay, terrible image. It was a screenshot from Instagram; I didn't rename it and didn't use an alt attribute.
00:04:41.600
So it reads out that really terrible file name. Now, this was not very good. If you didn't notice, it said "third" instead of "August third" for the date.
00:04:53.080
It didn't tell us that there were links in the page. And the reason it didn't tell us is because, as far as the accessibility tree is concerned, it's just text. It doesn't know the on-click event is there.
00:05:10.160
So in comparison, let's listen to the one with better HTML: Navigation, main navigation, one item list, three items, visited link, home link, good dogs link, bad dog myths.
00:05:21.919
Heading level one, dogs. They are good. We are dedicated to educating the world on why dogs are good and how they can make your life good.
00:05:34.520
Mandy Michael, August third, 2018. Heading level two. Okay, I won't make you listen to the image again. It is better, but I feel like my point was made.
00:05:47.680
This is a really simple page and just a very small part of a really simple page, and the differences are quite noticeable. It told me how many links there were, that I had visited a link, that something was a link, and it read out headings.
00:06:05.560
The date was better, and all I did was pick HTML that represented the content. Now we have a functional page. Prior to that, it was not very functional.
00:06:18.680
The user had to do a lot of the heavy lifting and take on the cognitive load to try and figure out what was going on. It's not just accessibility that benefits from a more considered approach to HTML.
00:06:31.039
Overlooking HTML can lead to a very large complex DOM tree, and this can impact your load times. As users and scripts interact with your DOM, the browser has to recompute the position and styling of all nodes, which can severely impact rendering time.
00:06:47.760
Google's Lighthouse Performance Tool recommends less than 1,500 nodes and will warn at 800, so that should be an indicator that you want to be way on the low end of those numbers.
00:07:02.800
You might think that's a lot and that you'll never hit that, but more complex pages, especially in web apps with lots of widgets, tools, and features, can easily exceed this by mistake.
00:07:15.160
Especially if you're building at a component level, these days we build an isolated component with a div here and a div in that component and a component wrapper with more divs.
00:07:27.520
It's very easy to forget that all of these things have to come together on one page. While you might check that the component works, most people don't check what the actual HTML is on the page.
00:07:38.360
They've just checked the functionality, and as the accessibility tree is made up of what we provide the DOM, any performance impacts to the DOM further impact the accessibility tree.
00:07:50.480
I saw this great talk by Eric Bailey, who is an inclusive design advocate, and he says that when the accessibility tree is slowed down by excessive code, it can create a lack of synchronization between the current state of the page and what is being reported via assistive tech.
00:08:11.639
This results in a mismatch between the page and what the user is presented with via the accessibility tree.
00:08:18.360
So, as you can probably imagine, that's very confusing. You can kind of think of it like bad lag in a video game or bad dubbing, for example.
00:08:36.079
It's confusing, and users have to do a lot more work to figure out what's going on. In the worst-case scenario, it could crash the browser.
00:08:41.360
At the end of the day, everything that we put into our page impacts our performance and our accessibility. That includes every div, every button, and every link. Everything adds up to create these negative experiences with performance and accessibility.
00:08:58.600
So we need to dedicate some time to how we use our HTML. This was eight minutes of me talking just to say, don't just use divs. I'm not saying don't ever use them; they have a purpose.
00:09:16.840
Just don't only use divs. And when you are using HTML, use it correctly. For example, headings are very important, and they're numbered for a reason.
00:09:36.360
We're good with numbers, typically use them in order. They provide a clear structure and hierarchy for the page, and when you use them out of order, you mess with that hierarchy.
00:09:52.800
Headings are important for a number of reasons: Google Search bots use them to prioritize content and figure out what's important. They're also part of that little search preview in Google.
00:10:12.240
But importantly, they're very important for accessibility because users using assistive technology typically use headings to navigate the page via tooling, and that might be with keyboard shortcuts, through a screen reader, or something like the rotor.
00:10:30.640
The rotor is up on screen, which is kind of like a table of contents. It'll group things like links, headings, and landmarks, allowing people to navigate through and jump to sections on the page.
00:10:50.320
So if you don't use headings and you don't use them properly, you're taking away the user's ability to navigate your page. That would be like having no navigation and trying to figure out where you need to go by some imaginary lucky dip.
00:11:07.760
We should also use appropriately named elements for what we're building. If you have a header, use a header; a footer should be a footer; nav should be nav; article should be an article; label for labels; form for forms; button for buttons; section for sections; image for images.
00:11:28.320
HTML is intentionally simple; it's named to help you out. It's not a trap. Nobody's trying to trick you. I'll be the first to admit it's not always that simple.
00:11:44.480
We have link and anchor, which can be confusing, and sometimes it's not obvious what something should be, but it's a really good place to start because it is trying to be helpful.
00:12:07.920
It will improve your accessibility just by changing the HTML, so if that's the only thing you do for accessibility, that's a big step forward.
00:12:29.480
In some cases, it might also reduce the number of nodes on the page because you're simply being more considered in your approach.
00:12:46.200
More often than not, you should also make use of built-in functionality over creating your own. I know this isn't always easy to do, but it's a good place to start.
00:13:10.720
There are a lot of useful built-in features that don't require additional JavaScript. Now, I'm not sure about the Ruby community's position on JavaScript, but as a front-end developer, I have to say we definitely could use less of it in our websites.
00:13:31.240
So if you can use native functionality, you can have less of that. It also tends to work better across mobile devices and for accessibility as well. Not always, but typically, it's a lot better.
00:13:49.320
Definitely better than Stack Overflow code might be better than ChatGPT and co-pilot. I don't know, that might change over time as they get smarter.
00:14:07.960
There are some good things you can use, like details, which is like an accordion; the date picker, which I'm sure you're all familiar with.
00:14:22.640
Actually, this one's an interesting one: Date pickers are great for discoverable dates like appointments, you know, like next Tuesday in three weeks.
00:14:36.760
They are not great for dates of birth, especially the older you get. I don't like having to click back to the 1900s to find my year of birth.
00:14:54.200
It's a very humbling experience. There's a great article called "You Might Not Need a Date Picker" by Adrian Roselli; it's in my resources, and I highly recommend you read it.
00:15:07.920
You can just use a text input for the date of birth.
00:15:22.400
Another situation you might come across with these is where you get a design that is pretty but doesn't match the native style.
00:15:36.120
What I would say about that, between us, is just because it's in a design does not mean you have to do it. It's controversial, but I'm not saying be a jerk about it.
00:15:49.679
There's always room to have these discussions with designers. There's always room for compromise, especially if it's going to make functional accessible improvements to your page.
00:16:05.320
So don't feel like just because it's in the design it's something you have to do. Definitely ask about it if you can.
00:16:19.760
That said, there are also things with really good styling options, like the dialog, which is kind of like a modal where the page behind it is disabled.
00:16:33.480
Another option is the popover, which you might say is exactly the same as a dialog, but it's not. It does not disable the page; this is better for toast notifications or content pickers.
00:16:46.320
It's actually kind of new; it's been supported in the browsers for about a month now. There's also a JavaScript API, but who cares about that.
00:17:01.240
Of course, buttons have lots of useful features, but typically people these days do this. And I know we had the eight minutes of don't use divs, but I wanted to show my little table here.
00:17:14.360
Because it really drives the point home: buttons have all these features, specifically, they're very good for accessibility, announce, very assistive tech keyboard interaction, focusable.
00:17:30.760
Reported to the accessibility tree, divs, however, have none of that. If you use a div to replicate these features, you need to write more code, test more code, and maintain more code.
00:17:45.560
That means you've got more JavaScript on your page, which we've already established is a bad thing. I mean, I love JavaScript, don't get me wrong, but you don't need it to make a button.
00:18:03.760
When we already have an HTML element, don't make your life more difficult. When you make use of native functionality, it's basically like using a JavaScript library that's already built for you.
00:18:14.120
This means less JavaScript, smaller JavaScript bundle sizes, which improves the performance of our pages.
00:18:28.920
Now we're going to talk about optimizing and loading prioritization. To do that, I'm going to briefly talk about browser prioritization.
00:18:50.720
With HTTP/1, we would have multiple TCP connections, and they would load one resource at a time, so prioritization was based on whatever was requested first.
00:19:09.560
But with HTTP/2 and HTTP/3, this was changed. Instead of multiple connections, it was changed to a single connection with multiple requests at the same time.
00:19:30.360
However, that doesn't mean that every request can be responded to at the same time because a connection is limited in how much data it can send.
00:19:49.080
This is particularly true at the start of a connection, as we can only send a limited amount of data for one network round trip.
00:20:04.920
Eventually, the server has to decide which resource it's going to respond to first.
00:20:20.600
As a result, the order of prioritization can have a big impact on your performance because, as it prioritizes one thing, it's going to deprioritize another.
00:20:38.400
If you send the JavaScript first, your images are delayed, and vice versa. This is particularly important for render-blocking items like JavaScript and CSS.
00:20:56.320
We need to download them in full before they can be applied and executed.
00:21:12.800
Additionally, browsers prioritize things differently, so depending on how you have things set up, you might see noticeable differences between each browser for your performance.
00:21:29.600
So what can HTML do for this? They introduced priority hints, specifically the fetch priority attribute.
00:21:49.840
Fetch priority allows you to specify the priority of resource types like CSS, fonts, scripts, and images, allowing us to change that default priority from the browser.
00:22:07.680
It also gives us the opportunity to make things more consistent across browsers. It has three options: high, prioritize, low, deprioritize, and auto, which is what the browser does by default.
00:22:30.240
Now, often when people use this, they expect that if you set a high priority, it's the highest priority; if you set a low priority, it's the lowest priority, but that is not what happens.
00:22:47.560
It actually just sets a relative priority. It's only going to raise or lower the priority by a specified amount.
00:23:06.560
For example, in Chrome, stylesheets are the highest priority by default. If you set a fetch priority of high, it's going to retain the highest priority.
00:23:25.440
If you set a fetch priority of low to a stylesheet, instead of being a low priority, it will be downgraded to a high priority.
00:23:45.120
So in neither of these situations are we explicitly saying high or low priority; it's just adjusting it relative to the browser rules.
00:24:14.320
A really good place to use this is in image carousels that marketing teams love. If you set a fetch priority of high to the first active image, it will request that quicker and therefore download quicker, improving your performance metrics.
00:24:36.160
This is particularly effective if it's in the viewport as part of the largest contentful paint.
00:24:56.200
If you set it to low, they will come after that first main one, so it's a really good way to utilize this.
00:25:06.600
Browser support is very good; I would say Chrome, Safari, Edge, and the associated mobile browsers all support it. However, it's not supported in Firefox yet.
00:25:18.400
They're actively working on it. The best thing about HTML is it'll just ignore it if it doesn't know what to do, so you can use it in the other browsers and wait for Firefox.
00:25:38.200
Next, I want to talk about requesting a resource from the server. This can take a really long time, so if you can handle it ahead of time, you can make your websites and applications feel a lot faster.
00:25:56.960
To do this, we use resource hints. There are two options: preconnect and DNS prefetch.
00:26:13.760
We use them with the rel attribute. So rel='preconnect' and rel='dns-prefetch', you can apply this to a link element in the head of your document.
00:26:28.640
If we look at preconnect first, it essentially informs the browser that your page intends to establish a connection to another domain and that you'd like the process to start as soon as possible.
00:26:49.520
This can speed up load times by about 100 to 500 milliseconds by establishing early connections. It's really handy for image CDNs and streaming media.
00:27:10.400
However, if you're making a lot of connections to third-party domains, preconnecting to all of them is counterproductive, so it's best to preconnect only on critical connections.
00:27:28.240
For everything else, you can use DNS prefetch, which saves time on the first step of the DNS lookup, usually about 20 to 120 milliseconds.
00:27:47.000
Now, that might not seem like a lot, but in a positive way, this time adds up. If you can save 50 to 100 milliseconds multiple times on multiple resources, you'll start to see performance improvements.
00:28:03.680
Preconnect has great support. DNS prefetch is only supported on HTTP and not HTTPS in Firefox. It's also not supported in iOS Safari or the Android browser.
00:28:20.720
But again, you can still use it in the others.
00:28:37.040
Finally, we are going to discuss preload. Preload is probably the most commonly used performance HTML feature. We use it the same way that we use the other two I just talked about, with the rel attribute on a link element and a value of preload.
00:28:56.640
What it does is help to prepare resources that you don't need right now but will need later. Keep in mind, again, when you preload one thing, you prioritize that and deprioritize another.
00:29:21.760
As a result, you only want to use that on critical connections, like preconnecting.
00:29:37.640
Unfortunately, people often misuse it. Zack Leatherman did this great tweet that I loved. If you use preload on everything or in the wrong places, you can actually make things worse.
00:29:49.840
I'll use this example from Robin Marks, which is a response to that previous tweet. What we see is an example without preload and with preload.
00:30:09.760
In the first example, the image request is deferred until after the JavaScript is downloaded, and it takes about 2.25 seconds, which is quite a long time.
00:30:24.920
In the second example, the image is requested alongside the JavaScript, and it's downloaded quicker, which is great.
00:30:39.760
However, what is more likely to happen is your image and your JavaScript are going to fight for bandwidth and priority, delaying both the JavaScript and the image download.
00:30:54.680
In some cases, the image might even download before the JavaScript, creating a janky page experience.
00:31:10.880
So you need to be careful about how you use this feature. You need to test it because it might not give you the results you were expecting.
00:31:28.480
Preload should be used for assets not loaded directly by the HTML but critical to the page experience. Consider things inside CSS, like fonts and images, or anything loaded by JavaScript, such as JSON, imported scripts, web workers, or large videos.
00:31:42.720
Finally, I wanted to talk about 103 early hints. This is not HTML; it is an HTTP status code called 103 early hints.
00:31:58.160
The reason I wanted to mention this is that early hints define new interactions between a client and a server.
00:32:15.360
You can utilize everything I've just talked about: DNS prefetch, preload, fetch priority, and preconnect.
00:32:30.640
For example, it will allow the browser to preconnect to sites or start preloading resources even before the server has prepared and sent the final response.
00:32:49.640
While the syntax is a little different, the great part about this is that it's transferable knowledge. You know if you live in that land more than you do in HTML or vice versa.
00:33:06.240
Sometimes you'll find it's better in early hints versus HTML and vice versa. Support is pretty good.
00:33:22.880
Preload is not supported in Safari, and behind a flag in Firefox.
00:33:39.760
So, what I want to finish with is to please make the most of HTML. Spend a bit of time learning it and how you can apply it to your pages for your content.
00:33:56.960
You'll make things more useful and more usable, not just for performance and accessibility, but for our users and different technologies as well.
00:34:14.640
All by using a technology you're already familiar with, just using it a little bit better.
00:34:31.360
There is so much to be gained from using HTML well. It's not difficult to learn, and there's absolutely nothing to lose.
00:34:49.960
Thank you very much! I hope you got something out of my talk. If you have questions, please come speak to me or reach out on my social networks. My resources are up on GitHub through this QR code. Thank you!