Running PHP apps in the browser with ServiceWorkers and Worker Threads
On a high level, WordPress Playground works in web browsers as follows:
- The
index.html
file on playground.wordpress.net loads theremote.html
file via an<iframe src="/remote.html">
. remote.html
starts a Worker Thread and a ServiceWorker and sends back the download progress information.- The Worker Thread starts PHP and populates the filesystem with a WordPress patched to run on SQLite.
- The ServiceWorker starts intercepting all HTTP requests and forwarding them to the Worker Thread.
remote.html
creates an<iframe src="/index.php">
, and the Service Worker forwards theindex.php
request to the Worker Thread where the WordPress homepage is rendered.
Visually, it looks like this:
High-level ideas
The @php-wasm/web
is built on top of the following ideas:
- Browser tab orchestrates everything – The browser tab is the main program. Closing or reloading it means destroying the entire execution environment.
- Iframe-based rendering – Every response produced by the PHP server must be rendered in an iframe to avoid reloading the browser tab when the user clicks on a link.
- PHP Worker Thread – The PHP server is slow and must run in a web worker, otherwise handling requests freezes the website UI.
- Service Worker routing – All HTTP requests originating in that iframe must be intercepted by a Service worker and passed on to the PHP worker thread for rendering.