Houdini – Demystifying CSS

Avez-vous déjà pensé à la quantité de travail que le CSS effectue ? Vous changez de et tout à coup, l'ensemble de votre site Web apparaîtra dans une mise en page différente. Il est C'est une sorte de magie. Jusqu'à présent, la communauté des développeurs Web n'a été que d'observer et d'observer la magie. Et si nous voulons trouver notre propre magie ? Et si nous voulions devenir les magiciens ?

Entrez Houdini !

Le groupe de travail Houdini est composé d'ingénieurs de Mozilla, Apple, Opera, Microsoft, HP, Intel et Google collaborent pour présenter certaines parties pour les développeurs Web. Le groupe de travail travaille sur une collection de dans le but de les faire accepter par le W3C et de devenir de véritables sites Web de conformité. Elle s'est fixé quelques objectifs de haut niveau, les a transformés en de spécifications, ce qui a donné naissance à un ensemble de projets aux brouillons de spécifications de niveau inférieur.

La collection de ces brouillons est généralement ce que l'on veut dire quand quelqu'un parle de "Houdini". Au moment de la rédaction de ce document, la liste des brouillons est incomplets et certains des brouillons sont de simples espaces réservés.

Spécifications

Worklets (spécifications)

Les Worklets en eux-mêmes ne sont pas vraiment utiles. Il s’agit d’un concept introduit rendre possible la plupart des brouillons ultérieurs. Si vous pensiez aux Web Workers lorsque vous lire « worklet », vous n’avez pas tort. Ils présentent de nombreux chevauchements conceptuels. Alors pourquoi une nouvelle chose alors que nous avons déjà des nœuds de calcul.

L'objectif d'Houdini est d'exposer de nouvelles API pour permettre aux développeurs Web d'associer leur propre code au moteur CSS et au les systèmes environnants. Il n'est probablement pas irréaliste de supposer que certains de ces fragments de code doivent être exécutés chaque. unique. cadre. Certains d'entre eux doivent par définition. Mention de la spécification Web Worker:

<ph type="x-smartling-placeholder">

Par conséquent, les travailleurs Web ne sont pas viables pour atteindre les objectifs de Houdini. C'est pourquoi les classeurs ont été inventés. Les Worklets utilisent les classes ES2015 pour définir un ensemble de méthodes, dont les signatures sont prédéfinies le type de Worklet. Ils sont légers et de courte durée.

API CSS Paint (spécification)

L'API Paint est activée par défaut dans Chrome 65. Consultez les introduction détaillée.

Worklet de compositeur

L'API décrite ici est obsolète. Le Worklet de compositeur a a été repensée et est désormais proposée sous le nom de "Worklet d'animation". Pour en savoir plus, consultez le l'itération actuelle de l'API.

Même si la spécification du Worklet du compositeur a été transférée vers WICG et car c'est celle qui me passionne le plus. Un peu sur la carte graphique de votre ordinateur par le CSS de votre ordinateur, bien que cela dépende à la fois de votre carte graphique et de votre périphérique en général.

Un navigateur utilise généralement l'arborescence DOM et, en fonction de critères spécifiques, décide d'attribuer à certaines branches et sous-arborescences leur propre couche. Ces sous-arbres se peignent dessus (peut-être en utilisant un travaillet de peinture dans à venir). Pour finir, tous ces calques individuels, maintenant peints, sont empilés et positionnées les unes sur les autres, dans le respect des z-indices, des transformations 3D et pour obtenir l'image finale visible à l'écran. Ce processus est appelée compositing, qui est exécutée par le compositeur.

L'avantage du processus de composition est qu'il n'est pas nécessaire les éléments se repeignent lorsque la page défile un tout petit peu. Au lieu de cela, vous vous pouvez réutiliser les calques du cadre précédent et réexécuter le compositeur avec la position de défilement mise à jour. Cela accélère les choses. Cela nous aide à atteindre 60 ips.

Worklet de compositeur.

Comme son nom l'indique, le travaillet du compositeur vous permet de vous rattacher au compositeur et influencent la façon dont le calque d'un élément, qui a déjà été peint, est positionnée et superposée aux autres couches.

Pour obtenir un peu plus vous pouvez indiquer au navigateur de se connecter à la composition pour un nœud DOM donné et peut demander l'accès à certains attributs tels que position de défilement, transform ou opacity. Cela force la mise en œuvre de cet élément propre couche et sur chaque image, votre code est appelé. Vous pouvez déplacer votre calque en manipulant les couches, qui transforment et modifient leurs attributs (comme opacity). pour faire des choses fantaisistes à 60 ips.

Voici une implémentation complète du défilement parallaxe à l'aide du compositeur Worklet de VM.

// main.js
window.compositorWorklet.import('worklet.js')
    .then(function() {
    var animator = new CompositorAnimator('parallax');
    animator.postMessage([
        new CompositorProxy($('.scroller'), ['scrollTop']),
        new CompositorProxy($('.parallax'), ['transform']),
    ]);
    });

// worklet.js
registerCompositorAnimator('parallax', class {
    tick(timestamp) {
    var t = self.parallax.transform;
    t.m42 = -0.1 * self.scroller.scrollTop;
    self.parallax.transform = t;
    }

    onmessage(e) {
    self.scroller = e.data[0];
    self.parallax = e.data[1];
    };
});

Robert Flack a écrit un polyfill pour le de compositeur pour vous permettre de l'essayer. Bien évidemment, plus d'impact sur les performances.

Worklet de mise en page (spec)

La première ébauche de spécifications réelles a été proposée. Implémentation est un bon moment.

Là encore, la spécification correspondante est pratiquement vide, Intrigant: créez votre propre mise en page ! Le Worklet de mise en page est censé vous permettre d'effectuer la commande display: layout('myLayout') et d'exécuter le code JavaScript pour organiser les éléments enfants dans la zone du nœud.

Bien entendu, l'exécution d'une implémentation JavaScript complète de la mise en page flex-box du CSS est plus lente que l'exécution d'une implémentation native équivalente, mais elle permet Imaginez un scénario dans lequel le fait de perdre du poids peut générer un gain de performances. Imaginez un site Web uniquement constitué de rien d'autre que des tuiles, comme Windows 10 ou un modèle de type maçonnerie mise en page. Les positionnements absolus et fixes ne sont pas utilisés, de même que les positions z-index et non plus. les éléments se chevauchent ou présentent n'importe quel type de bordure ou de dépassement. La possibilité de passer toutes ces vérifications sur la remise en page pourraient améliorer les performances.

registerLayout('random-layout', class {
    static get inputProperties() {
        return [];
    }
    static get childrenInputProperties() {
        return [];
    }
    layout(children, constraintSpace, styleMap) {
        const width = constraintSpace.width;
        const height = constraintSpace.height;
        for (let child of children) {
            const x = Math.random()*width;
            const y = Math.random()*height;
            const constraintSubSpace = new ConstraintSpace();
            constraintSubSpace.width = width-x;
            constraintSubSpace.height = height-y;
            const childFragment = child.doLayout(constraintSubSpace);
            childFragment.x = x;
            childFragment.y = y;
        }

        return {
            minContent: 0,
            maxContent: 0,
            width: width,
            height: height,
            fragments: [],
            unPositionedChildren: [],
            breakToken: null
        };
    }
});

Code CSSOM saisi (spec)

<ph type="x-smartling-placeholder">

Un CSSOM typé (CSS Object Model ou Cascading Style Sheets Object Model) permet de traiter un problème que nous avons probablement rencontré et que nous venons d’apprendre à simplement supporter. Prenons l'exemple d'une ligne de code JavaScript:

    $('#someDiv').style.height = getRandomInt() + 'px';

Nous faisons des calculs, en convertissant un nombre en chaîne pour ajouter une unité juste pour avoir le navigateur analyse cette chaîne et la reconvertit en nombre pour le moteur CSS. Ce comportement est encore plus affaibli lorsque vous manipulez des transformations avec JavaScript. Ce n'est plus le cas ! Le CSS va bientôt commencer à saisir du texte.

Ce brouillon est l'un des plus matures, et un polyfill est en cours de traitement. (Clause de non-responsabilité: l'utilisation du polyfill d'encore plus de frais de calcul. L'objectif est de montrer à quel point API.)

Au lieu de chaînes, vous travaillerez sur le StylePropertyMap d'un élément, où Chaque attribut CSS possède sa propre clé et le type de valeur correspondant. Attributs comme width, ont LengthValue comme type de valeur. Un LengthValue est un dictionnaire de toutes les unités CSS, comme em, rem, px, percent, etc. Paramètre height: calc(5px + 5%) génère une LengthValue{px: 5, percent: 5}. Un peu Les propriétés comme box-sizing n'acceptent que certains mots clés et ont donc un Type de valeur KeywordValue. La validité de ces attributs peut alors être vérifiée lors de l'exécution.

<div style="width: 200px;" id="div1"></div>
<div style="width: 300px;" id="div2"></div>
<div id="div3"></div>
<div style="margin-left: calc(5em + 50%);" id="div4"></div>
var w1 = $('#div1').styleMap.get('width');
var w2 = $('#div2').styleMap.get('width');
$('#div3').styleMap.set('background-size',
    [new SimpleLength(200, 'px'), w1.add(w2)])
$('#div4')).styleMap.get('margin-left')
    // => {em: 5, percent: 50}

Propriétés et valeurs

(spécification)

Connaissez-vous les propriétés personnalisées CSS (ou leur alias non officiel "Variables CSS") ? C'est eux, mais avec des types ! Jusqu'à présent, les variables ne pouvaient contenir que des valeurs de chaîne et a utilisé une approche simple de recherche et de remplacement. Ce brouillon vous permettrait de ne pas spécifiez uniquement un type pour vos variables, mais définissez également une valeur par défaut et influencer le comportement d'héritage à l'aide d'une API JavaScript. Techniquement, cela permet également aux propriétés personnalisées de s'animer avec des transitions CSS standards. et les animations, qui est également pris en compte.

["--scale-x", "--scale-y"].forEach(function(name) {
document.registerProperty({
    name: name,
    syntax: "<number>",
    inherits: false,
    initialValue: "1"
    });
});

Métriques de police

Les métriques de police correspondent exactement à ce qu'elles semblent être. Qu'est-ce que le cadre de délimitation (ou la cadres de délimitation) lorsque j'affiche la chaîne X avec la police Y de taille Z ? Que se passe-t-il si je vais utiliser Annotations Ruby ? Elle a été très demandée, et Houdini devrait enfin réaliser ces vœux.

Et ce n'est pas tout !

La liste des versions préliminaires d'Houdini présente encore plus de spécifications, incertain et ce ne sont pas beaucoup plus que des espaces réservés à des idées. Exemples : comportements de dépassement personnalisés, API d'extension de syntaxe CSS, extensions du comportement de défilement natif et des choses tout aussi ambitieuses, qui permettent des choses sur la plateforme Web qui n'étaient pas possibles auparavant.

Démonstrations

J'ai partagé le code de la démonstration en Open Source. (démonstration en direct avec polyfill).