[Originally presented at Web Directions - Summit 2022]
Front-End development has changed a lot in the last 15 years. Browser compatibility has stabilised, browsers have added a *lot* of functionality, JavaScript has had a massive makeover and CSS has added lots of tools that make hard things easy. But in the middle, we wrote a lot of code - and you might have to read it.
In this talk I'll go through a modern history of front-end best practices. We'll look at how the tools available, and the constraints we had, impacted the way we built. Hopefully this will help you understand how we got where we are, and how to approach code (and browser APIs) that work in an old paradigm.
Here's a quote from the wikipedia article for the History of the World Wide Web.
That's the same year Taylor Swift was born. That's as old as me. The web is a millenial and it's being roasted on Tik Tok.
Okay so not actually. He came up with the idea in 1989, then published his proposal in 1990 and it wasn't really popularised until Mosaic in 1993.
When you give an id an element, the id becomes a global variable.
So you can just write "hello" as a variable name and get the element. No getElemementById or querySelector anything tricky. Just a good honest variable.Here I'm setting the text of the element to be "gday".
When I do that, the element is updated to have the text gday
Here it is together. We give the element an id, set the text inside it to be "gday", and even though the text was originally Hello, it's now gday.
It's strange that every single element with an id has its own global variable.
What happens if that clashes with your own names and scopes?
Why does getElementById exist if I can just do this?
Why does my HTML leak out into my JavaScript namespaces?
Well someone at Microsoft in like 1990-whatever thought this would be convenient.
So they added it to Internet Explorer.
Back then scripts were short and tightly coupled with their HTML.
You gave the element an id, so why not access it with that ID?
It made sense.
And once Internet Explorer implemented it, all the other browsers had to add it.
Then it got used a lot and now it's a web standard.
Even though the web standard says that you shouldn't use it.
The whole web is like this. It's this chaos of layers and history and people doing their best.
Best practices of the past impacting how we work today.
The web is made of weird stuff that really only made sense in its original historic context.
There's more legacy code out there than fresh beautiful modern best practices.
One of the web's big strengths is that it's fully backwards compatible. But that also means that nothing ever really goes away.
So you're gonna have to learn it and understand it.
I could do a whole talk on "Weird stuff from internet explorer", but let's not.
In 2007 Apple released the iPhone and it totally changed the way people use the web.
When the iPhone was released you couldn't make apps, but you could use Safari.
The developer docs even included a guide for how to make web apps for iPhone.
This seems like a good place to start.
In this time we saw the rise of SAAS and Web Applications.
A lot of web apps, and a lot of web standards were built in this time.
The company I work for (Stile Education) started around 2012, and there's code in our codebase from that era.
I'm sure many of you can relate.
The iPhone came along at an interesting time in Web Development.
Apple refused to support flash, which was the main way to make app-like web applications.
Web applications were becoming possible with "just" HTML, CSS and JavaScript.
You didn't need to embed Java, or Flash anymore.
With mobile devices, came small screens.
This was a problem for websites.
Let's talk about best practices in building layouts over the years.
The 960 grid system was introduced by Nathan Smith in around 2008.
When the web started most people had the same size screen.
Then different screen sizes and resolutions became common.
If you built for one size, the website would just sit in the top left on a bigger screen.
It looked weird.
The 960 grid just chose a width that was small enough it would work on most computers.
Your content was 960px wide, centered, everything else was blank space.
This was an innovation!
The grid was divided up in 12 columns.
Because 12 is divisible by 2, 3, 4 and 6 it made it easy to make complex layouts.
With mobile devices, came small screens. The original iPhone had a resolution of 320x480.
At the time most computers had a resolution of at least 1024x768.
This was a problem for websites built with 960. They would display small like this, zoomed out.
It was really hard to click buttons, or read text. You'd have to build a whole separate website for mobile.
It was time for our grids to become responsive.
Mark Otto and Jacob Thornton, a couple of keen web developers at Twitter (RIP)
realised that they kept building the same stuff.
So they came up with the idea for Bootstrap.
It was a layout system and a set of components that could help you build a
website fast.
In the process they kind of invented design systems.
It was incredibly popular, and still is to this day.
In V1 they just used the 960 grid approach, but in V2 they added a Responsive Grid.
And this was a cool idea.
This was made possible by media queries. They used a media query for each size, and changed the size of the grid at certain breakpoints.
This became a common best practice from then onwards.
Here we have two columns with a gap of four width between them.
It would be the same layout on different devices, but it would resize the columns on mobile.
By version three in 2014 this grid system was becoming more and more capable.
You could adjust how many columns an element took up, depending on what device was loading the page.
Here you can see we have the `xs` and `md` options to decide how many columns to use on small and large screens.
But this sort of approach can be hard to manage, you need to do a lot of fiddly work with grids at every size.
Now that we have Flexbox the elements and classes needed to create this kind of grid all seem a bit much.
People don't really use grids like this, or at least I don't. I wonder why?
Maybe with better primitives for layout, we don't need something like column layouts.
Those grids might still exist at the design stage, but when you build it out you don't need it anymore.
With the popularity of the iPhone we got the rise of cool apps.
… like this app that makes your iphone into a beer. Yum yum. You don't see innovation like this anymore!
We wanted to make cool apps with animation and dynamic behaviour!
A really popular best practice for making web apps is Decoration which is a pattern made popular by…..
jQuery was released by John Resig in late 2006 and soon became incredibly popular.
jQuery is on like 80% of websites, that's wild.
You can see up here that red line is jQuery.
Compare that to the react brown line down the very bottom right.
How many people in here have jQuery in their codebase?
Let's just quickly look over how this works. So let's say we've served some HTML.
We want some of it to be displayed when you click the "Show More" button.
See here this paragraph is hidden.
You have JavaScript that goes through and finds each selector and adds your JS on top.
The $ sign is the jQuery library. Yes, $ is a valid variable name in JavaScript and John Resig stole it.
Here I've found all buttons that have the btn-reveal class, then decorated them.
This approach is really powerful. It's performant. It's like the new SSR islands architecture but from 2008.
This approach is still widely used, and makes a lot of sense.
Rendering your HTML server-side, and then sprinkling in just a little bit of
JavaScript can be a really performant way to build web apps.
If you're interested in trying this out, Hotwire and HTMX are two interesting
JavaScript frameworks that take this approach.
This was the best part about jQuery. It was really easy to grab something from the server, and then update the page.
Let's say we had a form like this, it's got a name and a message and a post button.
We want to live update the page, not wait for a whole reload so we use jQuery.
jQuery posts the data to the server, and the server responds with some HTML and we put that in the page.
The big problem here is tight coupling between the front and backend.
Server has to render fragments.
What if we want to change something elsewhere in the page hierarchy?
It gets unwieldy quickly.
So around this time Ruby on Rails was incredibly popular.
And with this an architecture called "Model View Controller" was also really popular.
The model is responsible for data storage and syncing.
The controller is responsible for orchestration and updates between the model and view.
The view is responsible for displaying the data from the model.
AngularJS was launched by Google in 2010, just a few months later Backbone was released by Jeremy Ashkenas.
These frameworks both used this MVC pattern, but I'm a bit more familiar with Backbone.
In Backbone the MVC is arranged slightly differently. You have a "Collection" which represents a group of models.
Like posts, or articles.
Then you instantiate each view for that collection, with the appropriate model passed in.
This all became very complicated very quickly. Especially making sure that data was in sync across the whole app.
Events flying everywhere.
Selecting the DOM to make small targeted updates.
Sometimes it can feel like these labels and groupings were a bit arbitrary.
It lead to everything having to fit in the bucket of "view" or "model".
And now we've kind of all settled on using reactive components instead.
We still have separate different architectural parts, but we invent specific tools for solving these individual problems.
We're finding better primitives for expressing what we want to build.
Rather than grouping them all together as "controller" or "model".
To make all these dynamic web apps we'll need to include code that someone else has written.
I can't build all this stuff myself!
I also love deleting code.
That's a lot of files! Can we speed up loading these somehow?
But, these loads would block eachother, because of HTTP 1.0. In HTTP 1.0 the browser can only make three requests at once.
In 2009 Ryan Dahl released NodeJS. Then in 2010 Isaac Z. Schlueter released NPM.
Npm had some really good features, and was well loved because there were so many packages there!And people on the frontend wanted it too. So in 2014 a bunch of people built Webpack.
So you use the same require syntax that node uses. Webpack will read this file, recognise those dependencies, and then figure out what to do.
Unfortunately these bundles got bigger and bigger
With HTTP2 and HTTP3 we no longer have these requests limits. The browser can make hundreds of requests at once.
So why not use web standards? Browsers now support ESModules for imports natively.
What do you think happens in this example?
In Chrome and Safari you'll get a `HTMLCollection` if you try `window.hello`.
Which is what the spec says. Even though id is meant to be unique on the page.
But in Firefox you'll get the first element.
Isn't that the most web thing ever?
In Chrome and Safari you'll get a `HTMLCollection` if you try `window.hello`.
Which is what the spec says. Even though id is meant to be unique on the page.
But in Firefox you'll get the first element.
Isn't that the most web thing ever?