Upgrade to Pro — share decks privately, control downloads, hide ads and more …

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.

Vitalii Bobrov

September 20, 2019
Tweet

More Decks by Vitalii Bobrov

Other Decks in Programming

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. WA S M U S E D F O R

    T H E S TAT E U P D AT E
  4. 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
  5. 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
  6. I T R E M I N D S S

    O M E T H I N G …
  7. HOW TO IMPLEMENT • Define a paint class in a

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

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

    return ['--custom-palette', 'color']; } paint(ctx, geom, props, args) {} } registerPaint('my-painter', Painter);
  10. 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);
  11. USE PAINT() FUNCTION IN CSS .paint-container { --custom-palette: #333; color:

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

    #fff; background: #000; background: paint(my-painter, 2, 25%); }
  13. BENEFITS • Possible to run in a separate thread •

    Draw whatever you want using 2D Canvas • Renders only when needed
  14. 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/
  15. 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
  16. J S O N D ATA F O R C

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

    C S S T O R E N D E R C S S
  18. 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 ?
  19. 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 ?
  20. REGISTER CUSTOM PROPERTY if ('registerProperty' in CSS) { CSS.registerProperty({ name:

    '--font-color', syntax: '<color>', inherits: false, initialValue: '#cccccc' }); }
  21. 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 ?
  22. REGISTER CUSTOM PROPERTY @property --font-color { syntax: '<color>'; initial-value: #cccccc;

    inherits: false; } https://github.com/vitaliy-bobrov/postcss-register-custom-props
  23. 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); };
  24. 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
  25. 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