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

No me robes el Scroll!

No me robes el Scroll!

Viste cuando scrolleas y anda todo re lento? Bueno, muchas veces por ser cool y hacer un montón de cosas en el scroll penalizamos al usuario y su experiencia sin darnos cuenta. Por eso, les quiero compartir una técnica para evitar esto y tener UIs mucho más performantes.

Guille Paz

July 14, 2016
Tweet

More Decks by Guille Paz

Other Decks in Technology

Transcript

  1. No me robes el Scroll
    Es lo único que me queda!

    View Slide

  2. View Slide

  3. Scroll Hijacking

    View Slide

  4. Scroll Jank

    View Slide

  5. window.onscroll=

    View Slide

  6. window.onscroll=

    View Slide

  7. ● Headers Fixed
    ● Parallax Scrolling
    ● History API
    ● Custom Scrolls
    ● Position Fixed
    ● Hover on Scroll (Chrome NO!)
    ● Juan Vanni <3

    View Slide

  8. Scrolling Performance

    View Slide

  9. ● Expensive Styles (box-shadow, position:fixed)
    ● Reflows and repaints (offsetTop)

    View Slide

  10. “It’s a very, very, bad idea to
    attach handlers to
    the window scroll event.”
    by John Resig

    View Slide

  11. “Avoid JS handlers for
    scroll generally, because there’s
    a ton of tax on them”
    by Paul Irish

    View Slide

  12. Decouple Scroll Events

    View Slide

  13. requestAnimationFrame()
    To the rescue!

    View Slide

  14. function decouple(node, fn) {
    var eve, tracking = false;
    function captureScroll(e) {
    eve = e;
    track();
    }
    function track() {
    if (!tracking) {
    requestAnimationFrame(update);
    tracking = true;
    }
    }
    function update() {
    fn.call(node, eve);
    tracking = false;
    }
    node.addEventListener('scroll', captureScroll, false);
    }

    View Slide

  15. function decouple(node, fn) {
    var eve, tracking = false;
    function captureScroll(e) {
    eve = e;
    track();
    }
    function track() {
    if (!tracking) {
    requestAnimationFrame(update);
    tracking = true;
    }
    }
    function update() {
    fn.call(node, eve);
    tracking = false;
    }
    node.addEventListener('scroll', captureScroll, false);
    }

    View Slide

  16. function decouple(node, fn) {
    var eve, tracking = false;
    function captureScroll(e) {
    eve = e;
    track();
    }
    function track() {
    if (!tracking) {
    requestAnimationFrame(update);
    tracking = true;
    }
    }
    function update() {
    fn.call(node, eve);
    tracking = false;

    View Slide

  17. function decouple(node, fn) {
    var eve, tracking = false;
    function captureScroll(e) {
    eve = e;
    track();
    }
    function track() {
    if (!tracking) {
    requestAnimationFrame(update);
    tracking = true;
    }
    }
    function update() {
    fn.call(node, eve);

    View Slide

  18. function decouple(node, fn) {
    var eve, tracking = false;
    function captureScroll(e) {
    eve = e;
    track();
    }
    function track() {
    if (!tracking) {
    requestAnimationFrame(update);
    tracking = true;
    }
    }
    function update() {
    fn.call(node, eve);
    tracking = false;
    }

    View Slide

  19. function decouple(node, fn) {
    var eve, tracking = false;
    function captureScroll(e) {
    eve = e;
    track();
    }
    function track() {
    if (!tracking) {
    requestAnimationFrame(update);
    tracking = true;
    }
    }
    function update() {
    fn.call(node, eve);
    tracking = false;
    }
    node.addEventListener('scroll', captureScroll, false);
    }
    function foo(eve) {
    console.log(eve);
    console.log(this.scrollTop);
    }
    var nodeBox = $$.querySelector('#box');
    decouple(nodeBox, foo);

    View Slide

  20. function decouple(node, fn) {
    var eve, tracking = false;
    function captureScroll(e) {
    eve = e;
    track();
    }
    function track() {
    if (!tracking) {
    requestAnimationFrame(update);
    tracking = true;
    }
    }
    function update() {
    fn.call(node, eve);
    tracking = false;
    }
    node.addEventListener('scroll', captureScroll, false);
    }

    View Slide

  21. Decouple Scroll Events

    View Slide

  22. DOM
    Decouple Scroll Events

    View Slide

  23. DOM Events:
    ● Scroll
    ● Resize
    ● Mouse Move
    ● Touch Move

    View Slide

  24. npm install decouple
    https://github.com/pazguille/decouple

    View Slide

  25. View Slide

  26. jank-free properties!
    transforms & opacity

    View Slide

  27. CSS will-change
    To the rescue!

    View Slide

  28. Passive Event Listeners
    To the rescue!

    View Slide

  29. Gracias!

    View Slide