Estratégias de Manipulação de DOM

Estratégias de Manipulação de DOM

React, Angular 2, Ember 2... O que esses frameworks têm em comum? Todos estão utilizando novas técnicas de manipulação do DOM da forma mais performática possível. Vamos fazer um overview dos algoritmos usados em cada um desses frameworks e conhecer o que há de novo e mais veloz. O objetivo da palestra é demonstrar como cada um dos frameworks fazem renderização de HTML. Alguns tópicos como: - Templates de HTML - HTML no JS: prós e contras; - Algoritmos de renderização; - Virtual DOM; - Formas de atualização do DOM; - Diff; - Patch; - Que tipo de renderização cada framework mais atual utiliza (React, Angular 2, Ember 2, etc.);

Bfcf5c88d40733a45ce754e6ce225a8b?s=128

Eduardo Matos

July 05, 2016
Tweet

Transcript

  1. ESTRATÉGIAS DE MANIPULAÇÃO DO DOM

  2. @eduardojmatos eduardomatos.me OI, EU SOU O EDU

  3. a maior plataforma de contratação de serviços do Brasil

  4. O QUE É O DOM? Document Object Model (DOM) Uma

    API para HTML e XML que define uma estrutura lógica de documentos e a forma que ele são acessados
  5. // armazenando o DOM da table var table = document.querySelector('table');

    // acesando o <tbody> da tabela var tbody = table.firstChild;
  6. None
  7. None
  8. console.log(typeof document.body) // "object" LOGO…

  9. None
  10. MÓDULOS DO DOM • Core module; • XML module; •

    Events module; • Mouse Events module; • …
  11. None
  12. CORE var button = document.createElement('button'); button.setAttribute('type', 'button'); button.setAttribute('id', 'colossus'); document.body.appendChild(button);

    var theButton = document.getElementById('colossus');
  13. CORE var button2 = document.createElement('button'); button2.setAttribute('type', 'button'); button2.setAttribute('id', 'cyclope'); document.body.replaceChild(button2,

    button); console.log(document.getElementById('colossus')); // null console.log(document.getElementById('cyclope')); // <button type="submit" id="cyclope"></button>
  14. EVENTS var button = document.querySelector('#cyclope'); button.addEventListener('click', function(event) { console.log('Cyclope is

    clicked!'); });
  15. BLZ, PRA MANIPULAR ENTÃO? - API um pouco complexa; -

    Criar elementos consumindo muitas linhas de código; - Renderizar novamente, de forma dinâmica, também consumia muito tempo/linhas;
  16. None
  17. AÍ SIM! document.getElement('button.btn'); // ou $$('button.btn');

  18. AÍ SIM! var button = new Element('button', { 'class': 'btn',

    id: 'wolverine', type: 'button' });
  19. MAS PODIA MELHORAR +

  20. $('#wolverine').addClass('btn--success'); $('#wolverine').attr('role', 'button'); $('#wolverine').text('Vai Wolverine!'); $('#wolverine').click(function(event) { console.log('Opa! Clicou hein!');

    }); $("body").append("<button type=\"submit\">Vai filhão!</button>");
  21. E ASSIM SURGIU "TEMPLATES"… var message = "É. Não deu

    certo, que pena :("; var template = "<div class=\"messages\">" + message + "</div>"; $('body').append(template);
  22. var message = "É. Não deu certo, que pena :(";


    var template = "<div class=\"messages\">\ MESSAGE_FIELD</div>"; $('body').append(template.replace(/MESSAGE_FIELD/g, message));
  23. MAS… NÃO ESCALA(VA)! • Templates muito grandes gerando uma baita

    manutenção; • Iterar listas com trechos de markup; • Problemas de XSS; • Performance baixa no content append; • Atualização gerando render novamente; • SEO*; • JS com HTML com String. Urgh;
  24. JS COM HTML STRING. URGH • Mesmos problemas de manutenção;

    • Mistura de markup com código; • HTML menos independente;
  25. CHEGAM OS TEMPLATE ENGINES

  26. O(S) PROBLEMA(S) • Alguns frameworks começam a usar as template

    engines (ex: Backbone e o _.template do Underscore.js); • Começa a ganhar força o conceito de Data Model no browser;
  27. O(S) PROBLEMA(S) • Atualização entre state do model e UI

    começa a criar problemas de performance; • A detecção dessas mudanças no model e reflexão na UI também é algo que cada framework tem tentado resolver de sua forma
  28. SPAS Alguns frameworks implementam renderização de DOM de forma diferente

  29. BACKBONE.JS • Usa apenas o append com o _.template do

    Underscore.js • Toda a árvore é atualizada, não importa se a mudança ocorreu apenas em um childrenNode; • Usa eventos do model pra avisar das alterações.
  30. ANGULARJS • Dirty checking: o Angular cria um watcher para

    cada atributo do model. • Parece ruim, mas o update se torna muito mais rápido; • Problemas acontecem em interfaces com muitos models;
  31. EMBERJS • Assim como o Backbone, manda eventos do model

    quando as alterações ocorrem; • A diferença é que intercepta essas mudanças com um bind de UI; • O problema é que é preciso usar os métodos da API do Ember pra isso ocorrer (ex: post.set(‘title’, ‘JavaScript Rocks’));
  32. GLIMMER • Nova engine do Ember que tenta usar os

    benefícios do Virtual DOM enquanto mantém compatibilidade com API; • Os nodes são armazenados em filas de valores
  33. None
  34. REACT • Virtual DOM: uma cópia (não full, mas mais

    leve) do seu DOM que só renderiza o que for necessário; • Você não fica “escutando” mudanças, só faz o “re-render” novamente, sempre; • Quem se encarrega de aplicar os diffs é o Virtual DOM;
  35. VIRTUAL DOM

  36. renderA: <div><span key="first">first</span></div> renderB: <div><span key="second">second</span><span key="first">first</span></div> => [insertNode <span>second</span>]

  37. OM • Uma interface de ClojureScript para o React; •

    Immutable data structures: você não altera apenas um atributo, mas produz uma cópia do objeto; • A performance é maior, mas não é o principal ganho;
  38. None
  39. VOLTANDO AO DOM • Outras libs que fazem apenas manipulação

    de DOM surgiram, como: • Incremental DOM; • virtual-dom; • inferno;
  40. INCREMENTAL DOM • Uma lib responsável por aplicar update no

    DOM de forma performática; • Faz diff incremental (um node por vez); • Foco na performance de alocação de memória; • É uma lib não acoplada a algum framework. elementOpen('ul'); items.forEach(function(item) { elementOpen('li', item.id); text(item.text); elementClose('li'); }); elementClose('ul');
  41. BENCHMARKS

  42. BENCHMARKS

  43. BENCHMARKS

  44. None
  45. RESUMINDO • Detecção e realização de mudanças é um grande

    problema ao usar o DOM. Use com cuidado; • Cada estratégia tem seus benefícios. O correto é avaliar se a lib ou framework que você usa atendem as demandas do projeto; • Ou seja, não use pelo hype; • Mas… Teste as novidades. Não seja ultra conservador! • Abra a mente pra novos conceitos (JSX).
  46. FONTES • http://teropa.info/blog/2015/03/02/change-and-its-detection-in- javascript-frameworks.html • https://auth0.com/blog/2015/11/20/face-off-virtual-dom-vs-incremental- dom-vs-glimmer/ • https://auth0.com/blog/2016/01/11/updated-and-improved-more- benchmarks-virtual-dom-vs-angular-12-vs-mithril-js-vs-the-rest/

    • http://reactkungfu.com/2015/10/the-difference-between-virtual-dom- and-dom/ • https://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/ introduction.html • https://medium.com/google-developers/introducing-incremental-dom- e98f79ce2c5f • https://github.com/auth0-blog/blog-dombench/tree/dombench2
  47. DOIS RECADINHOS =D • Para as meninas: FrontinVale está com

    call4paperz aberto (50% dos palestrantes serão mulheres)! • Fórum FrontendBR: https://frontendbr.github.io
  48. eduardoj.matos@gmail.com @eduardojmatos http://eduardomatos.me OBRIGADO ;) GetNinjas contrata front-end: https://getninjas.workable.com/