Slide 1

Slide 1 text

Develop Faster With https://frankenphp.dev

Slide 2

Slide 2 text

➔ PHP API Platform creator, Symfony Core Team ➔ Go Mercure.rocks creator, Caddy maintainer, Go core contributor ➔ C PHP maintainer Kévin Dunglas: Polyglot Dev @[email protected] @dunglas.dev @dunglas

Slide 3

Slide 3 text

Web and Cloud Experts ➔ Development (Symfony, Laravel, API Platform, JS, Go, Rust...) ➔ Support & hosting (FrankenPHP) apps ➔ Consultancy & maintenance ➔ UX & UI design ➔ [email protected] 💌

Slide 4

Slide 4 text

Symfony's Performance Secret

Slide 5

Slide 5 text

Symfony’s Developer Experience ➔ Symfony is easy and pleasant to use ➔ It relies a lot on: ● conventions: automatic service registration, autowiring, autoconfiguration… ● User-friendly formats: attributes, YAML/PHP/XML config, Twig templates…

Slide 6

Slide 6 text

No content

Slide 7

Slide 7 text

The Cost of Developer Experience ➔ Parsing ➔ Compiling ➔ Dumping ➔ Using the reflection API ➔ … ➔ Many computations ➔ Potentially low

Slide 8

Slide 8 text

Alleviate The Cost ➔ Config: config files (YAML, XML…) are parsed, combined, converted in PHP and dumped ➔ DependencyInjection: the container is compiled and dumped for performance in production (uses Config under the hood) ➔ Routing (uses Config under the hood) ➔ Twig: templates are compiled in PHP files ➔ Cache: result of computations can be stored in cache

Slide 9

Slide 9 text

The var/cache directory

Slide 10

Slide 10 text

⚡ in Production: Symfony Apps Are Compiled ➔ The cache is populated 1 time, ideally at build time ● bin/console cache:warmup ➔ Then it is reused for each request

Slide 11

Slide 11 text

🐢 in Dev ➔ Each time a file (PHP, Twig, YAML…) is touched… ➔ … the cache must be re-populated ➔ Populating the cache means writing files on disk (slow) ➔ On large projects (ex: Sylius), this can be very slow and hurts the DX

Slide 12

Slide 12 text

Rebuild Only What’s Needed

Slide 13

Slide 13 text

FrankenPHP To The Rescue

Slide 14

Slide 14 text

FrankenPHP A modern app server for PHP apps: ➔ Replaces NGINX+FPM or Apache+mod_php ➔ Built for easy deployments: compatible with Docker, can embed your app in the binary! ➔ The fastest PHP engine ➔ 103 Early Hints support ➔ Built-in real-time support (Mercure) ➔ Compatible with all existing PHP apps: progressive enhancement

Slide 15

Slide 15 text

➔ Super simple to use: ● Standalone binary (that can contain your app) ● No external dependencies ● Batteries included ➔ Built on top of the Caddy web server ● All Caddy features and modules ● Benefits from Go features ● Extensible: in Go, in C, in PHP ➔ Designed for prod, CI and dev envs FrankenPHP: Modern PHP App Server

Slide 16

Slide 16 text

FrankenPHP: Features BROTLI, ZSTANDARD & GZIP COMPRESSION Modern compression formats are supported out-of-the-box. STRUCTURED LOGGING Bring a more defined format and details to your logging. PROMETHEUS METRICS & TRACING Built-in Prometheus support! HTTP/2 & HTTP/3 Native support for HTTPS, HTTP/2 and HTTP/3. HTTPS AUTOMATION Automatic HTTPS certificate generation, renewal and revocation. GRACEFUL RELOAD Deploy your apps with zero downtime thanks to graceful reloads.

Slide 17

Slide 17 text

➔ Compatible with existing PHP apps (including Symfony, Laravel and even WordPress)! 🐘 ➔ Static binary ✨ ➔ Single Docker image 🐳 ➔ Entirely configurable 💅 ● Caddyfile ● php.ini ➔ Free software (as in free speech ✊, and free beer 🍺) FrankenPHP: At a Glance

Slide 18

Slide 18 text

Getting Started With Static Binaries curl https://frankenphp.dev/install.sh | sh mv frankenphp /usr/local/bin/ frankenphp php-server -r public/

Slide 19

Slide 19 text

Getting Started With Homebrew brew install dunglas/frankenphp frankenphp php-server -r public/

Slide 20

Slide 20 text

Getting Started With Docker docker run -v $PWD:/app \ -p 80:80 -p 443:443 -p 443:443/udp \ dunglas/frankenphp

Slide 21

Slide 21 text

The Easiest Way For Symfony Users

Slide 22

Slide 22 text

FrankenPHP’s Worker Mode

Slide 23

Slide 23 text

FrankenPHP Superpower: The Worker Mode ➔ Boot your application once ➔ Keep it in memory ➔ Process incoming requests without having to boot your app again ➔ Relies on goroutines and channels ➔ Somewhat similar to RoadRunner ➔ Unlike RoadRunner ● runs in process: no network calls, no gRPC ● uses plain old superglobals: no PSR-7

Slide 24

Slide 24 text

The Runtime Component

Slide 25

Slide 25 text

FrankenPHP worker for Symfony # Install $ composer require \ php-runtime/frankenphp-symfony # Run $ frankenphp \ -r public/ -w public/index.php

Slide 26

Slide 26 text

Benchmarks

Slide 27

Slide 27 text

Worker mode: Benchmark (Laravel Octane) 🧪 # Concurrency 1 for 5 seconds… ./vendor/bin/pest stress http://127.0.0.1:8000 Swoole Medium Request Duration ........... 4.94 ms RoadRunner Medium Request Duration ....... 2.61 ms FrankenPHP Medium Request Duration ....... 0.88 ms # Concurrency 8 for 5 seconds… ./vendor/bin/pest stress http://127.0.0.1:8000 --concurrency=8 Swoole Medium Request Duration ........... 5.39 ms RoadRunner Medium Request Duration ....... 4.00 ms FrankenPHP Medium Request Duration ....... 1.59 ms Benchmark by Nuno Maduro (Laravel Core Team) using Pest’s stress testing plugin on a M1 pro.

Slide 28

Slide 28 text

https://sylius.com/blog/ecosystem/month-of-sylius-august-2024/#frankenphp

Slide 29

Slide 29 text

FrankenPHP In Dev?

Slide 30

Slide 30 text

We Have A Problem ➔ Worker scripts are started at the same time as the web server ➔ They run forever ➔ If a file change (PHP file, Twig template, config…) ● nothing happens ● the worker script keeps running ➔ Worker mode is useless in dev

Slide 31

Slide 31 text

New In FrankenPHP 1.4: Watchers frankenphp { worker { file ./public/worker.php watch } }

Slide 32

Slide 32 text

Watchers ➔ FrankenPHP will watch files or directory for changes ➔ When a watcher file changes, the worker script is automatically restarted ➔ By default, typical Symfony files are watched: ● PHP ● YAML ● Twig ● .env

Slide 33

Slide 33 text

Patterns Can Be Customized frankenphp { worker { file public/index.php watch /path/to/app watch /path/to/app/*.php watch /path/to/app/**/*.php watch /path/to/app/**/*.{php,twig} } }

Slide 34

Slide 34 text

Watchers Are Blazing Fast, even for thousands of files

Slide 35

Slide 35 text

Worker In Dev Is Useful ➔ To render most web pages, browsers send several HTTP requests in parallel ➔ If these requests are handled by PHP (ex: JS, Turbo, React…), you’ll benefit from worker mode even in dev: the app will be hot

Slide 36

Slide 36 text

FrankenPHP And Symfony Cache?

Slide 37

Slide 37 text

Watchers And Symfony Cache Using the worker mode has another benefit: ➔ Symfony cache is refreshed instantly, in the background, when you save a file in your editor ➔ This dramatically reduces the time before the page is available ➔ Before: save ➡ refresh ➡ cache is building… ➔ After: save ➡ cache is building… ➡ refresh

Slide 38

Slide 38 text

No content

Slide 39

Slide 39 text

Meet our team and get FrankenPHP swag at our booth! Thank you! frankenphp.dev @dunglas Want to know more about how Les-Tilleuls.coop can help? ➔ Symfony development ➔ Support & hosting FrankenPHP apps ➔ Consultancy & maintenance ➔ UX & UI design