Slide 1

Slide 1 text

@stefanjudis Everything You Should Know About Web Development in 2022

Slide 2

Slide 2 text

@stefanjudis Things You Should Know About Frontend Development in 2022

Slide 3

Slide 3 text

Good old times!

Slide 4

Slide 4 text

Disclaimer

Slide 5

Slide 5 text

css-tricks.com/the-great-divide/

Slide 6

Slide 6 text

Use the platform JavaScript all the way! Apps Sites

Slide 7

Slide 7 text

@stefanjudis stefanjudis.com Heyo, I'm Stefan!

Slide 8

Slide 8 text

webweekly.email

Slide 9

Slide 9 text

TypeScript GraphQL Grid webp Font Display :focus-within ESM Lazy Loading PWA JAMStack Zero-Config JavaScript Cypress Serverless Web Components

Slide 10

Slide 10 text

It's fine to disagree... (Back then and today)

Slide 11

Slide 11 text

... and I'll miss topics you consider important. (Back then and today)

Slide 12

Slide 12 text

TypeScript GraphQL Grid webp Font Display :focus-within ESM Lazy Loading PWA JAMStack Zero-Config JavaScript Cypress Serverless Web Components

Slide 13

Slide 13 text

TypeScript GraphQL Grid webp Font Display :focus-within ESM Lazy Loading PWA JAMStack Zero-Config JavaScript Cypress Serverless Web Components Played out

Slide 14

Slide 14 text

TypeScript GraphQL Grid webp Font Display :focus-within ESM Lazy Loading PWA JAMStack Zero-Config JavaScript Cypress Serverless Web Components Evolved

Slide 15

Slide 15 text

TypeScript GraphQL Grid webp Font Display :focus-within ESM Lazy Loading PWA JAMStack Zero-Config JavaScript Cypress Serverless Web Components Sorta played out

Slide 16

Slide 16 text

The state of the platform

Slide 17

Slide 17 text

.grid { grid-template-columns: [a] auto [b] minmax(min-content, 1fr) [b c d] repeat(2, [e] 40px) repeat(5, auto); } CSS Grid and its incredible power arrived!

Slide 18

Slide 18 text

AVIF arrived! 2000 x 1333px Original 333KB MozJPG 115KB Webp 72KB AVIF 32KB

Slide 19

Slide 19 text

* caniuse.com/avif * Partial support

Slide 20

Slide 20 text

55!

Slide 21

Slide 21 text

:fullscreen :modal :picture-in-picture :auto-fill :enabled :disabled :read-only :read-write :placeholder-shown :default :checked :indeterminate :blank :valid :invalid :in-range :out-of-range :required :optional :user-invalid :dir() :lang() :any-link :link :visited :local-link :target :target-within :scope :playing :paused :current :past :future :root :empty :nth-child :nth-last-child :first-child :last-child :only-child :nth-of-type :nth-last-of-type :first-of-type :last-of-type :only-of-type :hover :active :focus :focus-visible :focus-within :is() :not() :where() :has()

Slide 22

Slide 22 text

:fullscreen :modal :picture-in-picture :auto-fill :enabled :disabled :read-only :read-write :placeholder-shown :default :checked :indeterminate :blank :valid :invalid :in-range :out-of-range :required :optional :user-invalid :dir() :lang() :any-link :link :visited :local-link :target :target-within :scope :playing :paused :current :past :future :root :empty :nth-child :nth-last-child :first-child :last-child :only-child :nth-of-type :nth-last-of-type :first-of-type :last-of-type :only-of-type :hover :active :focus :focus-visible :focus-within :is() :not() :where() :has()

Slide 23

Slide 23 text

section h1, article h1, aside h1, nav h1 { font-size: 25px; } :is(section, article, aside, nav) h1 { font-size: 25px; } :where(section, article, aside, nav) h1 { font-size: 25px; } :is() and :where() Specificity: 0,0,2 Specificity: 0,0,1

Slide 24

Slide 24 text

:has() The parent family selector Game changer alert!

Slide 25

Slide 25 text

form:has(:focus) {} form:has(:invalid) {} form:has(:valid) {} form:has(:placeholder-shown) {} Form handling codepen.io/jh3y/pen/YzYJLvy

Slide 26

Slide 26 text

figure:has(> figcaption) { /$ ..& *( } a:not(:has(> svg)) { /$ ..& *( } article:has(>h1):has(>h2) { /$ ..& *( } h1:has(+ p) { /$ ..& *( } form:has(:focus-visible) { /$ ..& *( }

Slide 27

Slide 27 text

Hello World!
Hello<*div>
world!<*div> <*div>

Slide 28

Slide 28 text

Hello World!
Hello<*div>
world!<*div> <*div> div { background: blue; color: white; }

Slide 29

Slide 29 text

Hello World!
Hello<*div>
world!<*div> <*div> div > div { background: blue; color: white; }

Slide 30

Slide 30 text

Hello World!
Hello<*div>
world!<*div> <*div> div:has(> div) { background: blue; color: white; }

Slide 31

Slide 31 text

Hello
Hello<*div>
world!<*div> <*div> div + div { background: blue; color: white; } World!

Slide 32

Slide 32 text

Hello World!
Hello<*div>
world!<*div> <*div> div:has(+ div) { background: blue; color: white; }

Slide 33

Slide 33 text

We yet have to discover all the new :has() patterns!

Slide 34

Slide 34 text

* caniuse.com/css-has * Behind layout.css.has-selector.enabled flag

Slide 35

Slide 35 text

developer.chrome.com/blog/has-m105/ webkit.org/blog/13096/css-has-pseudo-class/

Slide 36

Slide 36 text

@container Container queries Game changer alert!

Slide 37

Slide 37 text

Hello world!<*section> <*div> .container { container-type: inline-size; container-name: article; } Hello world!

Slide 38

Slide 38 text

Hello world!<*section> <*div> .container { container: article / inline-size; } Hello world!

Slide 39

Slide 39 text

.container { container: article / inline-size; } section { background: blue; } Hello world!
Hello world!<*section> <*div>

Slide 40

Slide 40 text

.container { container: article / inline-size; } section { background: blue; } @container article (min-width: 200px) { section { background: red; } } Hello world!
Hello world!<*section> <*div>

Slide 41

Slide 41 text

.container { container: article / inline-size; } section { background: blue; } @container article (min-width: 200px) { section { background: red; } } Hello world!
Hello world!<*section> <*div> 150px

Slide 42

Slide 42 text

.container { container: article / inline-size; } section { background: blue; } @container article (min-width: 200px) { section { background: red; } } Hello world!
Hello world!<*section> <*div> 250px

Slide 43

Slide 43 text

.container { container: article / inline-size; } section { background: blue; } @container article (min-width: 200px) { section { background: red; } } Hello world!
Hello world!<*section> <*div> 150px

Slide 44

Slide 44 text

100 vw 100 vh 100 cqw 100 cqh New units!

Slide 45

Slide 45 text

Speaking of units... All browsers ship large, small, and dynamic viewport units!

Slide 46

Slide 46 text

web.dev/viewport-units/

Slide 47

Slide 47 text

.posts { container-name: posts; } @container posts (background-color: #f8a100) { .post { color: #fff; } } The future — Container Style Queries

Slide 48

Slide 48 text

.posts { container-name: posts; } @container posts (-,mode: blue) { .post { color: #fff; } } The future — Container Style Queries

Slide 49

Slide 49 text

* caniuse.com/css-container-queries * Staring with version 109 shipping Jan 2023. Container Size Queries

Slide 50

Slide 50 text

Truly Component-driven CSS Container queries enable you to style elements based on their size whereas :has() lets you style them based on their content!

Slide 51

Slide 51 text

Truly Component-driven CSS Container queries enable you to style elements based on their size whereas :has() lets you style them based on their content! THIS IS HUGE!!!

Slide 52

Slide 52 text

Nevertheless, the web needs more components!

Slide 53

Slide 53 text

open-ui.org

Slide 54

Slide 54 text

Alert Avatar Badge Breadcrumb Button Card Checkbox Datepicker Dialog File Flex Focusgroup Icon Image Menu Popup Radio Button Select Skeleton Slider Switch Table Tabs Text Toast Tooltip

Slide 55

Slide 55 text

Alert Avatar Badge Breadcrumb Button Card Checkbox Datepicker Dialog File Flex Focusgroup Icon Image Menu Popup Radio Button Select Skeleton Slider Switch Table Tabs Text Toast Tooltip

Slide 56

Slide 56 text

Pick one<*button> <*span> <*div>
Benedek<*option> Carmen<*option> Jeremias<*option> <*div> <*div> <*selectmenu> selectmenu and popup open-ui.org/prototypes/selectmenu Not ready yet...

Slide 57

Slide 57 text

microsoftedge.github.io/Demos/selectmenu/

Slide 58

Slide 58 text

const dialog = document.querySelector('dialog'); dialog.showModal(); // to close the dialog use `close` dialog.close(); A new Dialog API

Slide 59

Slide 59 text

web.dev/building-a-dialog-component/

Slide 60

Slide 60 text

View transitions Huge game changer alert!

Slide 61

Slide 61 text

async function navigate(data) { if (!document.createDocumentTransition) { await updateTheDOMSomehow(data); return; } const transition = document.createDocumentTransition(); await transition.start(async () =. { await updateTheDOMSomehow(); }); }

Slide 62

Slide 62 text

View transitions SPA

Slide 63

Slide 63 text

MPA

Slide 64

Slide 64 text

github.com/WICG/view-transitions

Slide 65

Slide 65 text

front-end.social/@jensimmons/109423185383982313

Slide 66

Slide 66 text

TypeScript goes mainstream...

Slide 67

Slide 67 text

2021.stateofjs.com/en-US/opinions

Slide 68

Slide 68 text

octoverse.github.com/2022/top-programming-languages

Slide 69

Slide 69 text

Do I really need this?

Slide 70

Slide 70 text

No content

Slide 71

Slide 71 text

/** * @param {string} p1 - A string param. * @param {string=} p2 - An optional param (Closure syntax) * @param {string} [p3] - Another optional param (JSDoc syntax). * @param {string} [p4="test"] - An optional param with a default value * @return {string} This is the result *( function someMethod(p1, p2, p3, p4 = 'test') { // TODO }

Slide 72

Slide 72 text

function someMethod( p1: string, p2?: string, p3?: string, p4 = "test" ): string { // TODO }

Slide 73

Slide 73 text

TypeScript Less time spent in docs Fewer bugs Max developer productivity

Slide 74

Slide 74 text

github.com/tc39/proposal-type-annotations

Slide 75

Slide 75 text

TypeScript is the language we need for complex stu!.

Slide 76

Slide 76 text

No content

Slide 77

Slide 77 text

trpc.io

Slide 78

Slide 78 text

The state of the web

Slide 79

Slide 79 text

No content

Slide 80

Slide 80 text

Everybody uses React because everybody uses React because everybody uses React.

Slide 81

Slide 81 text

But what for?

Slide 82

Slide 82 text

Video platforms Blogs Shops Image & Illustration software Marketing sites Games Productivity Apps PWAs Streaming sites Social Networks

Slide 83

Slide 83 text

Website Web App

Slide 84

Slide 84 text

Website Web App Grey zone

Slide 85

Slide 85 text

Website Web App Grey zone

Slide 86

Slide 86 text

MPA vs. SPA Multi Page App Single Page App

Slide 87

Slide 87 text

First render (All of it!) index.html main.css jQuery.js A Fetch-Render Waterfall some-spaghetti.js DB Calls API Calls API Calls API Calls Server Browser index.html DB Calls API Calls API Calls API Calls All done!

Slide 88

Slide 88 text

<*App> App Sidebar Nav Main TweetBox Tweets SideBar Trends OtherNonSense Data for OtherNonSense Data for Trends Data for Tweets A Render-Fetch Waterfall (aka "fetch as you render")

Slide 89

Slide 89 text

<*App> App Sidebar Nav Main TweetBox Tweets SideBar Trends OtherNonSense Data for OtherNonSense Data for Trends Data for Tweets A Render-Fetch Waterfall (aka "fetch as you render") Network? CPU? Memory?

Slide 90

Slide 90 text

You can make your server fast, but you can't control the user's network. Remix docs

Slide 91

Slide 91 text

The JAMStack era

Slide 92

Slide 92 text

The Jamstack era

Slide 93

Slide 93 text

The modern web development era?

Slide 94

Slide 94 text

No content

Slide 95

Slide 95 text

SSR Server Side Rendering

Slide 96

Slide 96 text

SSR Server Side Rendering CSR Client Side Rendering

Slide 97

Slide 97 text

SSR Server Side Rendering CSR Client Side Rendering SSG Static Site Rendering

Slide 98

Slide 98 text

SSR Server Side Rendering CSR Client Side Rendering SSG Static Site Rendering DPR Incremental Static Regeneration Distributed Persistent Rendering ISR

Slide 99

Slide 99 text

What should you use? As always, it depends...

Slide 100

Slide 100 text

... but every tech choice has trade o!!

Slide 101

Slide 101 text

No content

Slide 102

Slide 102 text

No content

Slide 103

Slide 103 text

No content

Slide 104

Slide 104 text

No content

Slide 105

Slide 105 text

No content

Slide 106

Slide 106 text

No content

Slide 107

Slide 107 text

No content

Slide 108

Slide 108 text

Islands

Slide 109

Slide 109 text

No content

Slide 110

Slide 110 text

www.patterns.dev/posts/islands-architecture/ jasonformat.com/islands-architecture/

Slide 111

Slide 111 text

We'll live on the edge Partially at least

Slide 112

Slide 112 text

Server delivering HTML CSS, JavaScript, Images coming from a CDN

Slide 113

Slide 113 text

HTML, CSS, JavaScript, Images coming from a CDN

Slide 114

Slide 114 text

HTML, CSS, JavaScript, Images coming from a CDN Edge compute

Slide 115

Slide 115 text

No content

Slide 116

Slide 116 text

No content

Slide 117

Slide 117 text

No content

Slide 118

Slide 118 text

We yet have to learn what "edge" means but frameworks will lead the way.

Slide 119

Slide 119 text

Tooling advances and moves away from JavaScript

Slide 120

Slide 120 text

esbuild.github.io

Slide 121

Slide 121 text

swc.rs rome.tools

Slide 122

Slide 122 text

Testing evolved

Slide 123

Slide 123 text

Slide from my 2019 talk

Slide 124

Slide 124 text

No content

Slide 125

Slide 125 text

No content

Slide 126

Slide 126 text

No content

Slide 127

Slide 127 text

// @ts-check const { test, expect } = require("@playwright/test"); test.describe("navigation", () =. { test.beforeEach(async ({ page }) =. { // Go to the starting url before each test. await page.goto("https://playwright.dev/"); }); test("main navigation", async ({ page }) =. { // Assertions use the expect API. await expect(page).toHaveURL("https://playwright.dev/"); }); });

Slide 128

Slide 128 text

npx playwright test -,workers 4 // playwright.config.js const config = { workers: process.env.CI ? 2 : undefined, }; module.exports = config;

Slide 129

Slide 129 text

const button = page.locator('button') await page.locator(click) expect(button).toBeHidden() Auto-wait and web-first assertions make waitFor statements redundant.

Slide 130

Slide 130 text

Playwright testing (one moment in time) Playwright monitoring (over time)

Slide 131

Slide 131 text

Will we move up the stack?

Slide 132

Slide 132 text

www.youtube.com/watch?v=hWjT_OOBdOc

Slide 133

Slide 133 text

Higher level components

Slide 134

Slide 134 text

// pages/_app.js import { Inter } from '@next/font/google' // If loading a variable font, you don't need to specify the font weight const inter = Inter({ subsets: ['latin'] }) export default function MyApp({ Component, pageProps }) { return ( ) } next/image Higher level components

Slide 135

Slide 135 text

Let's see where we'll go next...

Slide 136

Slide 136 text

Container Queries :has() View Transitions AVIF Playwright Rendering patterns Popup Edge Compute End-to-end Type Safety Rust/Go Tooling

Slide 137

Slide 137 text

How to stay up to date?

Slide 138

Slide 138 text

github.com/mdn/browser-compat-data/releases

Slide 139

Slide 139 text

webweekly.email

Slide 140

Slide 140 text

javascriptweekly.com wdrl.info esnextnews.com webtoolsweekly.com bytes.dev

Slide 141

Slide 141 text

www.stefanjudis.com/blogroll/

Slide 142

Slide 142 text

No content

Slide 143

Slide 143 text

You can't always be cutting edge...

Slide 144

Slide 144 text

... use what works for you!

Slide 145

Slide 145 text

@stefanjudis www.stefanjudis.com Thanks.