Patryk Smakosz

Prepared for ALTEN Switzerland, October 2026

Scroll and motion, built to be fast

Senior frontend and creative developer. Three pieces of work, my Vue and Nuxt projects, then how this page itself is put together.

Marketing site for a SaaS product company

Performance rescue

  1. The problem

    On mobile the largest paint landed at 21 seconds and the page weighed 21 MB. PageSpeed moved between 40 and 55.

  2. What I found

    The headline reveal used gsap.from(), which writes opacity 0 the moment the timeline is built, inside an overflow mask. Chrome drops a paint candidate that loads hidden, so the real one never counted. That was my own animation code. The hero video was 14 MB of HEVC that Chrome cannot decode.

  3. What I changed

    The headline paints on first load and reveals with a transform only. The video became H.264 with a fast start. Fonts became subset WOFF2, images WebP, and reCAPTCHA waits for the first form focus.

Largest contentful paint, mobile

3.0s

Down from 21.1 s

Page weight

5.8MB

Down from 21.2 MB

Total blocking time

95ms

Down from 310 ms

Role
Front-end developer
Stack
WordPress, GSAP, Three.js, Custom animated preloader
Note
PageSpeed Insights, live site, August 2026.
View live site

Site for an architecture and workplace-design consultancy

Polish plus speed

  1. The problem

    Page transitions, scroll-driven animation, smooth scroll and a physics interaction, on a site its owners edit themselves. That mix usually comes out fragile or slow.

  2. What I decided

    A custom theme with no page builder. Flexible content fields in place of the block editor, so the motion survives a site that keeps being edited.

  3. What is still open

    Mobile scores 84, not 99. The headroom left is plain work: minification, about 42 KiB of unused CSS, about 46 KiB of unused JavaScript and one redirect chain.

PageSpeed, desktop

99/ 100

Largest contentful paint, desktop

0.4s

Layout shift, mobile

0

Role
Front-end developer
Stack
WordPress, Vite + Sass, GSAP + ScrollTrigger, Lenis, Barba.js, Matter.js
Note
PageSpeed Insights, live site, August 2026. All motion switched on.
View live site

A halftone shader lab, my own project

Raw WebGL

  1. The idea

    Dot-field shaders on one full-screen canvas, with a panel to switch variants and tune them live. One variant raymarches a small 3D scene and draws it as halftone.

  2. The contract

    Every variant defines three things: how bright a dot is, where it moves, and how many neighbour cells a pixel has to search. Adding a variant is one entry. The search cost is visible in the code, not hidden.

  3. What I have not done

    The 3D scene is built from primitives, not a real model. Performance on high-density screens is capped, not profiled.

Dependencies

0

Shader variants

6

Device pixel ratio cap

2x

Role
Everything
Stack
WebGL, GLSL, No build step
Note
Open it on a desktop and try variants 1 to 3 first.
Open the live lab

Vue and Nuxt work

The framework I work in every day. One client site and three projects of my own.

  • Releasd

    Marketing site for a PR reporting SaaS

    It started as maintenance of a Nuxt 2 site and became a full rebuild. Client since September 2025, still running.

    Nuxt 4, Nuxt UI 4, Nuxt Content, TypeScript

  • Nuxt GSAP portfolio template

    Open source template

    Smooth scroll, page transitions driven by directives, an orchestrated entrance animation and a theme switch that morphs colour with GSAP.

    Nuxt 4, GSAP, ScrollSmoother, TypeScript

  • Quorum

    Group scheduling with no database server

    Browsers sync with each other directly, and every write is signed with a per-device key. Unit tests plus Playwright runs that prove two browsers converge.

    Nuxt 4, RxDB, WebRTC, Playwright

  • Pushup tracker

    Peer-to-peer workout tracker

    Offline first. Devices sync without a server in between, and the counter is an SVG animated with GSAP.

    Nuxt 3, RxDB, WebRTC, GSAP

How this page is built

I have not shipped Angular in production. My daily stack is Vue and Nuxt with TypeScript. So I built this page in Angular 22.2.1 to show how my motion work sits in it.

Signals, no zone.js
The app is zoneless. State is signals, so a requestAnimationFrame loop or a scroll event never triggers change detection.
Reduced motion as one signal
A single service turns the OS setting into a signal. Every animated component reads it and reacts while the page is open.
afterRenderEffect for scroll motion
Each case study builds its ScrollTrigger timeline after render. The effect cleanup reverts it before a rebuild and on destroy.
afterNextRender and DestroyRef for WebGL
The canvas scene starts once in the browser and is disposed with its WebGL context when the component goes away.
@defer for the 3D scene
Three.js is a separate chunk that loads when the browser is idle. With no GPU, or under 30 fps, it steps aside for a still CSS pattern.
Prerendered, no server
The HTML is built ahead of time and hydrated. Without JavaScript, every word on this page is still here.
Tested
Unit tests cover the motion service and prove a case study leaves no ScrollTrigger behind.