WebAssembly-driven CSS

WebAssembly-driven CSS

CSS considered as a non-serious language in the tech community. I’m going to show that to make an impressive and performant design you might need to use WebAssembly and Houdini APIs. Houdini provides us a view layer (Paint Worklet) and props for render (Properties and Values API). WebAssembly is a performant state calculator. JavaScript is an orchestrator that requests a new state and handles properties updates. With such MVC-like architecture, you will be able to create rich off-thread visual experiences that could be easily plugged-in in different projects.

4f0880beebecf17d29eb709246055e14?s=128

Vitalii Bobrov

September 20, 2019
Tweet

Transcript

  1. CSS W E B A S S E M B

    LY- D R I V E N
  2. VITALII BOBROV • Lead FE Engineer @ EPAM Poland •

    Perf and CSS fan • @AngularWroclaw organizer @bobrov1989 https://bobrov.dev
  3. WebAssembly-Driven W H AT D O E S I T

    M E A N ?
  4. https://bobrov.dev/css-paint-demos/game-of-life/

  5. WA S M U S E D F O R

    T H E S TAT E U P D AT E
  6. None
  7. A N E W F I E L D F

    O R E X P E R I M E N T S I S O P E N
  8. CONCEPT OVERVIEW Paint API Worklet V I E W

  9. CONCEPT OVERVIEW Main-Thread JavaScript Paint API Worklet properties V I

    E W C O N TA I N E R
  10. CONCEPT OVERVIEW Main-Thread JavaScript Paint API Worklet WebAssembly Module properties

    update V I E W C O N TA I N E R S TAT E M A N A G E R
  11. CONCEPT OVERVIEW Main-Thread JavaScript Paint API Worklet WebAssembly Module properties

    state update V I E W C O N TA I N E R S TAT E M A N A G E R
  12. I T R E M I N D S S

    O M E T H I N G …
  13. PAINT API H O U D I N I

  14. CSS PROPS ACCEPTING IMAGES • background-image • border-image • list

    style image • custom properties <image>
  15. HOW TO IMPLEMENT • Define a paint class in a

    separate file • Load worklet module • Use paint() CSS function as a value for image
  16. PAINT WORKLET CLASS class Painter { paint(ctx, geom, props, args)

    {} } registerPaint('my-painter', Painter);
  17. PAINT WORKLET CLASS class Painter { static get inputProperties() {

    return ['--custom-palette', 'color']; } paint(ctx, geom, props, args) {} } registerPaint('my-painter', Painter);
  18. PAINT WORKLET CLASS class Painter { static get inputProperties() {

    return ['--custom-palette', 'color']; } static get inputArguments() { return ['<number>', '<percentage>']; } paint(ctx, geom, props, args) {} } registerPaint('my-painter', Painter);
  19. LOAD WORKLET MODULE if ('paintWorklet' in CSS) { CSS.paintWorklet.addModule('paint.js'); }

    else { // Optionally provide a fallback. }
  20. USE PAINT() FUNCTION IN CSS .paint-container { background: #000; background:

    paint(my-painter); }
  21. USE PAINT() FUNCTION IN CSS .paint-container { --custom-palette: #333; color:

    #fff; background: #000; background: paint(my-painter); }
  22. USE PAINT() FUNCTION IN CSS .paint-container { --custom-palette: #333; color:

    #fff; background: #000; background: paint(my-painter, 2, 25%); }
  23. https://bobrov.dev/css-paint-demos/star-rating/

  24. https://bobrov.dev/css-paint-demos/qr-code/

  25. BENEFITS • Possible to run in a separate thread •

    Draw whatever you want using 2D Canvas • Renders only when needed
  26. MATERIAL BACKGROUND C S S PA I N T I

    M A G E VS https://vitaliy-bobrov.github.io/css-paint-demos/md-bg/
  27. MATERIAL BACKGROUND C S S PA I N T I

    M A G E VS https://vitaliy-bobrov.github.io/css-paint-demos/md-bg/ 813 B 2.39 KB worklet file only few bytes of CSS + init JS compressed JPEG cropped for mobile
  28. JS IN CSS

  29. https://bobrov.dev/css-paint-demos/bar-js-in-css/

  30. J S O N D ATA F O R C

    H A R T I N C S S
  31. J AVA S C R I P T I N

    C S S T O R E N D E R C S S
  32. I S C S S A P R O G

    R A M M I N G L A N G U A G E T H E N ?
  33. CUSTOM PROPERTIES & VALUES API H O U D I

    N I
  34. CUSTOM PROPERTY .parent { --font-color: #fff; } .child { color:

    var(--font-color); }
  35. CUSTOM PROPERTY .parent { --font-color: #fff; } .child { --font-color:

    #000; color: var(--font-color); }
  36. CUSTOM PROPERTY .parent { --font-color: #fff; } .child { --font-color:

    #000; color: var(--font-color, #333); }
  37. H O W T O A N I M AT

    E A S T R I N G T O A N O T H E R S T R I N G ?
  38. CSS TYPES

  39. REGISTER CUSTOM PROPERTY if ('registerProperty' in CSS) { CSS.registerProperty({ name:

    '--font-color', syntax: '<color>', inherits: false, initialValue: '#cccccc' }); }
  40. B U T S H U N T I T

    B E D E C L A R E D I N C S S ?
  41. REGISTER CUSTOM PROPERTY @property --font-color { syntax: '<color>'; initial-value: #cccccc;

    inherits: false; } https://github.com/vitaliy-bobrov/postcss-register-custom-props
  42. https://css-houdini.rocks/animating-gradient

  43. UPDATE & RENDER REQUEST J AVA S C R I

    P T
  44. UPDATE CUSTOM PROPERTY element.style .setProperty(‘--font-color', '#fff');

  45. LOAD WASM & REQUEST A NEW STATE import { Universe

    } from 'wasm-game-of-life'; const renderLoop = (now) => { universe.tick(); const cellsPtr = universe.cells(); const cells = new Uint8Array( memory.buffer, cellsPtr, width * height ); requestAnimationFrame(renderLoop); };
  46. STATE MANAGEMENT W E B A S S E M

    B LY
  47. WASM - BINARY INSTRUCTION FORMAT FOR A STACK-BASED VM

  48. AVAILABLE OPTIONS

  49. ONLY NUMBERS

  50. LINEAR MEMORY

  51. None
  52. CONCEPT RECAP Main-Thread JavaScript Paint API Worklet WebAssembly Module properties

    state update V I E W C O N TA I N E R S TAT E M A N A G E R
  53. THANK YOU U S E WA S M P O

    W E R F O R C S S A R T @bobrov1989 https://bobrov.dev Illustrations by cdd20 https://pixabay.com/users/cdd20-1193381