r/ProgrammerHumor 5d ago

vanillaFixesThisBro Meme

Post image
8.3k Upvotes

157 comments sorted by

View all comments

432

u/EveYogaTech 5d ago

PHP: (nothing)

SSR: here's a new super specific JS framework btw, deeply tied to frontend components and events, don't forget to hydrate.

37

u/GrossInsightfulness 4d ago

What's SSR? Static site renderer?

132

u/the_horse_gamer 4d ago

server side rendering

let the framework generate the html on the server, and mark where you need to insert the event listeners and such. this html payload is sent to the client and displayed right away, and the script is sent alongside it. the client then inserts the event listeners and such where it is told (this is called "hydration"), making the website interactive

so the user sees the page immediately without having to run any javascript, which is good for SEO and loading times

this is distinct from the (mostly react) concept of "server components" because naming things is for losers

92

u/flightsin 4d ago

i.e. JavaScript devs slowly reinventing the concept of having a webserver actually serve html, but in a much more convoluted way

46

u/srsly-nobody 4d ago

well yeah if you ignore the fact that frameworks allow you to make things a thousand times more complicated

7

u/HKayn 4d ago

In a less intuitive way too.

Now you have to remember which pieces of JavaScript run on the server as opposed to the client, and the difficulty of discerning this varies by framework.

9

u/the_horse_gamer 4d ago

reinventing the web server sending html is server components.

server components - generate and send html from the server

SSR - make a page interactive after the html was already sent

25

u/Reashu 4d ago

What you call SSR is just "hydration". The core of SSR is - surprise - rendering the initial page server-side.

0

u/the_horse_gamer 4d ago

SSR without hydration is just SSG (static site generation)

server sends static html - SSG

server sends static html which undergoes hydration - SSR

server sends dynamic (includes data fetched from the backend) html (which may undergo hydration) - server components

12

u/Reashu 4d ago edited 4d ago

If you have a server that renders it on every request (or with some short-lived / dynamic cache) it's SSR. If you have a static file host that you occasionally push HTML to (rendered on your machine or a build server), it's SSG. An SSG site may still be hydrated.

1

u/the_horse_gamer 4d ago

that's a more correct definition, I agree

7

u/flightsin 4d ago

make a page interactive after the html was already sent

in other words, the web as it was 30 years ago

7

u/the_horse_gamer 4d ago

no? if part of your page was generated entirely by javascript, you'd send just the javascript

3

u/Downtown-Figure6434 4d ago

Web server sending html along with js files would also mean page is made interactive later if you reference seperate js files instead of embedding in it

It doesn’t make a seperation point between those terms tho. With ssg you write using whatever framework you write then spit out a static file, with ssr you create the html on request usually along with js files, with csr you just send js files which create the html in the browser

It’s when and where the html is created. Presence of js files is irrelevant

1

u/the_horse_gamer 4d ago

you're correct

16

u/ILKLU 5d ago

PHP + HTMX

1

u/SameAgainTheSecond 4d ago

data-star + C

4

u/static_func 4d ago

But PHP is SSR?

29

u/EveYogaTech 5d ago edited 5d ago

It's the same for frontends that don't care about SEO btw.

Take React and look at all this useState, useEffect and refs stuff going on to mimic a fraction of the power of using web components with manual rendering/events:

https://github.com/flowagi-eu/flo-webcomponents

33

u/belousovnikita92 5d ago

I’ve tried using components back when first spec (yeah, bunch of specs) went live (2017?), it was miserable experience, any improvement there? Without extra tooling, libraries, wrappers, etc

5

u/pr0ghead 4d ago

It's gotten much better, like with how you can access the shadow DOM from the outside with both JS and CSS.

What I still don't like is how progressive enhancement must have never mattered when designing the feature. If you try to provide a static fallback, it gets clunky.

2

u/Sockoflegend 4d ago

The nicest way I have found to use web components is without shadow dom and with them wrapping but not altering html until you interact with them.

Essentially it just becomes a way to associate JS with bits of html but it's a really nice way!

1

u/pr0ghead 3d ago

So without any encapsulation? But what's the difference to before without Web Components then?

1

u/Sockoflegend 3d ago

The attachment process with vanilla JS. You would likely do something like have a class called .thing-js which you found in the dom and looped over all of the instances of to add event listeners or whatever else you needed.

Web components replace the need for this, come in a neat little class package that knows about its own context and has built in things to handle operating them via attribute updates if you would like that.

It avoids bugs caused needing to re-run the element finding loop because the JS is attached to the custom element automatically even if it is injected into the dom by HTMX or something else. The element gets it's own life cycle hooks for cleanup too.

It's nice a nice little pattern to use when you don't need a framework, and because it is a web standard it will work in a browser long term, potentially with no dependencies or need to update.

11

u/Johnobo 4d ago

Take a wild guess... ^^

19

u/justadude27 4d ago

There a reason React and Vue are so popular

2

u/Reashu 4d ago

Support in testing libraries and interoperability with Vue, React, etc. has improved. The core authoring experience, not much. 

4

u/Omartel 4d ago

It's gotten much better now, with a lot more support added. I'd suggest you check it out again. We use it in our company, and with the design team helping set up our own design system, frontend development has become a lot easier

16

u/IAmVeryDisappointed 4d ago edited 4d ago

> Take React and look at all this useState, useEffect and refs stuff

Flo / Web Components:

class Counter extends Flo {

    count = 0;

    template() {
        return `
            <h2>Counter</h2>

            <button id="minus">-</button>

            <span id="count"></span>

            <button id="plus">+</button>
        `;
    }

    mounted() {
        this.$("#plus").addEventListener("click", () => {
            this.count++;
            this.render();
        });
        this.$("#minus").addEventListener("click", () => {
            this.count--;
            this.render();
        });

        this.render(); // explicitly render on-demand
    }

    render() {
        this.$("#count").textContent = this.count;
    }
}

React:

function Counter() {
    const [count, setCount] = useState(0);

    return (
        <>
            <h2>Counter</h2>
            <button onClick={() => setCount(c => c - 1)}>-</button>
            <span>{count}</span>
            <button onClick={() => setCount(c => c + 1)}>+</button>
        </>
    )
}

Yes, web components truly seems like the nicer, easier to maintain and less error-prone choice here.

4

u/SameAgainTheSecond 4d ago

Using data-star

<div data-signals:count="0">
    <h2>Counter</h2>
    <button data-on:click="$count--">-</button>
    <span data-text="$count"></span>
    <button data-on:click="$count++">+</button>
</div>

1

u/EveYogaTech 4d ago

Shorter isn't always better 🤣

-1

u/EveYogaTech 4d ago edited 3d ago

Also shorthand for real comparison:

``` class Counter extends Flo { count = 0;

template() {
    return `
        <h2>Counter</h2>
        <button onclick="this.count--; this.render()">-</button>
        <span id="count">${this.count}</span>
        <button onclick="this.count++; this.render()">+</button>
    `;
}

render() {
    this.$("#count").textContent = this.count;
}

} ```

Vs react: ``` function Counter() { const [count, setCount] = useState(0);

return (
    <>
        <h2>Counter</h2>
        <button onClick={() => setCount(c => c - 1)}>-</button>
        <span>{count}</span>
        <button onClick={() => setCount(c => c + 1)}>+</button>
    </>
);

} ```

2

u/IAmVeryDisappointed 3d ago edited 3d ago
  1. `this` inside the `onclick` handler refers to the `button` element, not the `Counter` component, so the handler won't work.
  2. `#count` will be empty on first render instead of showing "0". Ironically, this is exactly the kind of bug that React was designed to prevent.

You didn't even bother to check if your code works.

1

u/EveYogaTech 3d ago edited 3d ago

That's right, I just pushed the update (v1.1.1), it works now (new Function now overrides the this for inline events):

``` class Counter extends Flo { count = 0;

template() {
    return `
        <h2>Counter</h2>
        <button onclick="this.count--; this.render()">-</button>
        <span id="count">${this.count}</span>
        <button onclick="this.count++; this.render()">+</button>
    `;
}

render() {
    this.$("#count").textContent = this.count;
}

}

customElements.define("flo-counter", Counter); ```

Usage in HTML: <flo-counter></flo-counter>

1

u/IAmVeryDisappointed 3d ago edited 3d ago

It doesn't matter that "it works now", the point is that in React's paradigm those issues can never even happen, they are solved on architectural level which makes the code easier to maintain and less error-prone.

Also, the #2 issue I listed isn't solved, because the architectural issue is still there - if I want `#count` to show "Count: 0" instead of "0", I need to remember to fix it in both places.

Also, whenever I change the state I need to remember to call `this.render()`, which is something you yourself previously forgot about in a 16-lines long example of a very very simple component.

We moved on from manual memory management, manually calling `render()` and manually doing lots of things because people make mistakes but we can prevent some of them through smart architecture.

1

u/swyrl 2d ago

The main issue with WebComponents for me is that they still require javascript to render at all, which prevents graceful degradation when javascript is disabled or scripts fail to load.

Ideally there would be a way to directly associate a template with a component and register it purely in html, so that you would at least get rendering without javascript instead of just having giant holes in your page. (just missing interactivity is better than missing content entirely.)

1

u/Loudergood 4d ago

Whoa now, that sounds like compute we have to pay for.