Caleb Porzio

Livewire isn’t actually “live”

Aug 2021

Livewire is a fake. It pretends to be something it’s not.

When you use a Livewire component on a page in your app, it FEELS as if your browser has a LIVE connection to that component on the server. If a user clicks a button that changes a property in your component, everything updates as if there really is a “live” wire.

This is all a facade. In reality, there is no long-running server instance holding the state of your Livewire components. There is no direct connection to your browser either. There is only plain old AJAX requests to and from your application.

Because of this, each request made by Livewire from browser to server must include the last known, frozen “state” of the component. Behind the scenes, on the server, Livewire “hydrates” or un-freezes your PHP component and allows you to use it as if it’s been running on the server the entire time. Then after you’re done with it, Livewire will re-freeze or “dehydrate” your component into something it can send back to the browser for next time (JSON).

Note that when I say “state”, I mean the current values of the properties on your component. If we were talking about a counter component, the “state” would be the “count” property.

Here is an image taken directly from the Livewire documentation that should help you visualize this process:

Having a proper mental model when using Livewire is extremely helpful for debugging issues and even just understanding the constraints of the tool itself.

One constraint that was imposed on Livewire from the very beginning was: public properties can only be JSON-safe types (arrays, strings, integers, booleans, and null).

This meant that you couldn’t just set a property like $items to a Laravel Collection instance. That property had to be a plain array.

You might notice that that is no longer the case. Livewire now supports all sorts of non-JSON types: eloquent models, DateTime objects, Collection objects, etc…

It does this by reducing those properties down to plain JSON when the component is “frozen” and then re-instantiating the object when the component is “un-frozen”.

This all happens behind the scenes and further keeps up the facade that Livewire is actually “live”.

The best way to understand this functionality is to open up your browser’s devtools while using Livewire and inspect the XHR (ajax) request/response payloads.

All the information that Livewire needs to keep up this dog and pony show can be found there in plain text.

Before we sign off, you might ask yourself: “Why not actually have an actual “live” wire to a backend PHP instance (using something like Swoole and Websockets)?”

There are two answers:

First: PHP is maturing in the “real-time” space, but still, most projects don’t have that kind of infrastructure set up to run their apps. It’s important to me that Livewire has a low barrier of entry and using web sockets and the like raise that barrier significantly.

Second: those “real-time” paradigms introduce an entirely new set of tradeoffs like “what happens when a user loses connection?”, or “what happens if the server runs out of concurrent connection capacity?”, etc… These are all things Livewire doesn’t have to be concerned with at all. It’s just as simple and reliable (in terms of infrastructure) as any other AJAX request you make to your server.

Hopefully this deeper knowledge helps you on your journey and gives you a little bit of insight into what’s happening behind the scenes to make Livewire feel so magical.

TTFN, Caleb


My Newsletter

I send out an email every so often about cool stuff I'm working on or launching. If you dig, go ahead and sign up!