You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
PHP: Replace Worker Threads with Web Workers (breaking) (#471)
Iframe worker threads were introduced as a workaround for limitations in
web browsers. Namely:
* Chrome crashed when using WASM in web workers
* Firefox didn't support ESM workers at all
Both problems are now solved:
* WordPress/wordpress-playground#1
* mdn/content#26774
There are no more reasons to keep maintaining the iframe worker thread
backend. Let's remove it and lean fully on web workers.
This commit changes the signature of `spawnPHPWorkerThread` from
`spawnPHPWorkerThread(workerUrl, workerType, options)` to
`spawnPHPWorkerThread(workerUrl, options)` and is therefore breaking.
Copy file name to clipboardExpand all lines: packages/docs/site/docs/11-architecture/08-browser-concepts.md
+1-1Lines changed: 1 addition & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -18,5 +18,5 @@ The [`@php-wasm/web`](https://github.com/WordPress/wordpress-playground/blob/tru
18
18
19
19
-[**Browser tab orchestrates everything**](./09-browser-tab-orchestrates-execution.md) – The browser tab is the main program. Closing or reloading it means destroying the entire execution environment.
20
20
-[**Iframe-based rendering**](./10-browser-iframe-rendering.md) – 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.
21
-
-[**PHP Worker Thread**](./11-browser-php-worker-threads.md) – The PHP server is slow and must run in a worker thread, otherwise handling requests freezes the website UI.
21
+
-[**PHP Worker Thread**](./11-browser-php-worker-threads.md) – The PHP server is slow and must run in a web worker, otherwise handling requests freezes the website UI.
22
22
-[**Service Worker routing**](./12-browser-service-workers.md) – All HTTP requests originating in that iframe must be intercepted by a Service worker and passed on to the PHP worker thread for rendering.
PHP is always ran in a separate thread we'll call a "Worker Thread." This happens to ensure the PHP runtime doesn't slow down the website.
3
+
PHP is always ran in a [web worker](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API)to ensure the PHP runtime doesn't slow down the user interface of the main website.
4
4
5
5
Imagine the following code:
6
6
@@ -11,81 +11,22 @@ Imagine the following code:
11
11
12
12
As soon as you click that button the browser will freeze and you won't be able to type in the input. That's just how browsers work. Whether it's a for loop or a PHP server, running intensive tasks slows down the user interface.
13
13
14
-
### Initiating the worker thread
14
+
### Initiating web workers
15
15
16
-
Worker threads are separate programs that can process heavy tasks outside of the main application. They must be initiated by the main JavaScript program living in the browser tab. Here's how:
16
+
Web workers are separate programs that can process heavy tasks outside of the main application. They must be initiated by the main JavaScript program living in the browser tab. Here's how:
17
17
18
18
```ts
19
19
const phpClient =consumeAPI<PHPClient>(
20
20
spawnPHPWorkerThread(
21
-
'/worker-thread.js', // Valid Worker script URL
22
-
recommendedWorkerBackend// "webworker" or "iframe", see the docstring
21
+
'/worker-thread.js'// Valid Worker script URL
23
22
)
24
23
);
25
24
awaitphpClient.isReady();
26
25
awaitphpClient.run({ code: `<?php echo "Hello from the thread!";` });
27
26
```
28
27
29
-
Worker threads can use any multiprocessing technique like an iframe, WebWorker, or a SharedWorker (not implemented). See the next sections to learn more about the supported backends.
28
+
### Controlling web workers
30
29
31
-
### Controlling the worker thread
30
+
Exchanging messages is the only way to control web workers. The main application has no access to functions or variables inside of a web workeer. It can only send and receive messages using `worker.postMessage` and `worker.onmessage = function(msg) { }`.
32
31
33
-
The main application controls the worker thread by sending and receiving messages. This is implemented via a backend-specific flavor of `postMessage` and `addEventListener('message', fn)`.
34
-
35
-
Exchanging messages is the only way to control the worker threads. Remember – it is separate programs. The main app cannot access any functions or variables defined inside of the worker thread.
36
-
37
-
Conveniently, [consumeAPI](/api/web/function/consumeAPI) returns an easy-to-use API object that exposes specific worker thread features and handles the message exchange internally.
38
-
39
-
### Worker thread backends
40
-
41
-
Worker threads can use any multiprocessing technique like an iframe, WebWorker, or a SharedWorker. This package provides two backends out of the box:
42
-
43
-
#### `webworker`
44
-
45
-
Spins a new `Worker` instance with the given Worker Thread script. This is the classic solution for multiprocessing in the browser and it almost became the only, non-configurable backend. The `iframe` backend is handy to work around webworkers limitations in the browsers. For example, [Firefox does not support module workers](https://github.com/mdn/content/issues/24402) and [WASM used to crash webworkers in Chrome](https://github.com/WordPress/wordpress-playground/issues/1).
Loads the PHPRequestHandler in a new iframe to avoid crashes in browsers based on Google Chrome.
56
-
57
-
The browser will **typically** run an iframe in a separate thread in one of the two cases:
58
-
59
-
1. The `iframe-worker.html` is served with the `Origin-Agent-Cluster: ?1` header. If you're running the Apache webserver, this package ships a `.htaccess` that will add the header for you.
60
-
2. The `iframe-worker.html` is served from a different origin. For convenience, you could point a second domain name to the same server and directory and use it just for the `iframe-worker.html`.
61
-
62
-
Pick your favorite option and make sure to use it for serving the `iframe-worker.html`.
**/iframe-worker.html** (Also provided in `@php-wasm/web` package):
73
-
74
-
```js
75
-
<!DOCTYPE html>
76
-
<html>
77
-
<head></head>
78
-
<body style="padding: 0; margin: 0">
79
-
<script>
80
-
constscript=document.createElement('script');
81
-
script.type='module';
82
-
script.src=getEscapeScriptName();
83
-
document.body.appendChild(script);
84
-
85
-
functiongetEscapeScriptName() {
86
-
// Grab ?script= query parameter and securely escape it
87
-
}
88
-
</script>
89
-
</body>
90
-
</html>
91
-
```
32
+
This can be tedious, which is why Playground provides a convenient [consumeAPI](/api/web/function/consumeAPI) function that abstracts the message exchange and exposes specific functions from the web worker. This is why we can call `phpClient.run` in the example above.
0 commit comments