SSR Web Components
EVERYWHERE

with WASM

Simon MacDonald

@macdonst@mastodon.online

👩🏽‍💻❤️🧱

Web Components

  • Custom Elements
  • Shadow DOM
  • HTML Templates

Custom Elements

Shadow DOM

Slots and Templates

Full Example

Browser Native Technology

JavaScript Limitations

 

class MyCustomElement extends HTMLElement { … }

customElements.define("my-custom-element", MyCustomElement);

Server
Side
Rendering

+

+

=

Web Assembly

  • Is a binary machine code language
  • You don't write web assembly
  • Compile other languages into .wasm
  • Run anywhere!

WASM Example

function helloWorld() {
  console.log("Hello World from WebAssembly!")
}

exports { helloWorld }

helloWorld.js

WASM Example

function helloWorld() {
  console.log("Hello World from WebAssembly!")
}

exports { helloWorld }

helloWorld.js

(module
    ;; Imports from JavaScript namespace
    (import  "console"  "log" (func  $log (param  i32  i32))) ;; Import log function
    (import  "js"  "mem" (memory  1)) ;; Import 1 page of memory (54kb)
    
    ;; Data section of our module
    (data (i32.const 0) "Hello World from WebAssembly!")
    
    ;; Function declaration: Exported as helloWorld(), no arguments
    (func (export  "helloWorld")
        i32.const 0  ;; pass offset 0 to log
        i32.const 29  ;; pass length 29 to log (strlen of sample text)
        call  $log
        )
)

helloWorld.wat

WASM Example

wasmtime run helloWorld.wasm

Hello World from WebAssembly!

Compile to WASM

javy compile helloWorld.js -o helloWorld.wasm

Test using wasmtime

WASM Example

Running WASM on a webpage

<script>
const memory = new WebAssembly.Memory({initial:1});

function  consoleLogString(offset, length) {
  const bytes = new Uint8Array(memory.buffer, offset, length);
  const string = new TextDecoder('utf8').decode(bytes);
  console.log(string);
};

const importObject = {
  console: {
    log:  consoleLogString
  },
  js : {
    mem:  memory
  }
};

WebAssembly.instantiateStreaming(fetch('helloworld.wasm'), importObject)
  .then(obj  => {
    obj.instance.exports.helloWorld();
  }
);    
</script>

Extism Example

extism gen plugin -l JavaScript -o plugin
cd plugin
npm install
// write some code

Install Extism

curl -O https://raw.githubusercontent.com/extism/js-pdk/main/install.sh
sh install.sh

Create an Extism plugin

Build & Test Extism plugin

npm run build
extism call ./dist/plugin.wasm count_vowels --input "Hello, World!" --wasi
// => '{"count":3,"total":3,"vowels":"aeiouAEIOU"}'

Extism Example

const createPlugin = require("@extism/extism")

const plugin = await createPlugin(
  'https://github.com/extism/plugins/releases/latest/download/count_vowels.wasm',
  { useWasi: true }
);

let out = await plugin.call("count_vowels", "Hello, World!");
console.log(out.text())
// => '{"count":3,"total":3,"vowels":"aeiouAEIOU"}'

+

+

=

Any

Runtime

+

+

+

=

<?php
require "../../../vendor/autoload.php";

use Enhance\EnhanceWASM;
use Enhance\Elements;

$elementPath = "../resources";
$elements = new Elements($elementPath, ["wasm" => true]);
$enhance = new EnhanceWASM(["elements" => $elements->wasmElements]);

$input = [
    "markup" => "<my-header>Hello World</my-header>",
    "initialState" => [],
];

$output = $enhance->ssr($input);

$htmlDocument = $output->document;

echo $htmlDocument . "\n";

Extism Example

Demo

Some Problems

  • Extism is a shared library
  • Installation of the shared library requires sudo/root access
  • Needs "ffi.enable=true"

Thanks!

😅

+

+

=

Enhance WP Plugin

server side render any enhance custom elements in the wordpress site. These can be added in PHP templates, raw HTML blocks in the editor, or as predefined blocks.

Enhance Blocks Plugin

demonstrates wrapping an Enhance component for use in the block editor. This works with the SSR plugin. These blocks are stored in the WP database as HTML (i.e. Hi) and then the SSR plugin will render them wherever they are used.

Demo 2

Get Involved

Enhance is an open source initiative, and we’re looking for collaborators to join us on our mission of making server side rendered web components accessible to all web developers.

Whatever your choice of programming language or framework may be, we’d love assistance with optimizing our existing implementations, creating new adapters, improving example applications, reviewing pull requests, and everything in between!

If you’re enthusiastic about getting involved, let’s start talking!

https://enhance.dev/

Key Takeaways

  • Web Components are awesome
  • WASM is great for bringing native like performance to the web
  • Never write WASM by hand
  • Use WASM to support cross platform SDK's

Thanks,

For real this time!