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 full-size slide

  2. Scroll Hijacking

    View full-size slide

  3. window.onscroll=

    View full-size slide

  4. window.onscroll=

    View full-size slide

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

    View full-size slide

  6. Scrolling Performance

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  10. Decouple Scroll Events

    View full-size slide

  11. requestAnimationFrame()
    To the rescue!

    View full-size slide

  12. 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 full-size slide

  13. 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 full-size 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;

    View full-size 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);

    View full-size 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 full-size 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);
    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 full-size 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;
    }
    node.addEventListener('scroll', captureScroll, false);
    }

    View full-size slide

  19. Decouple Scroll Events

    View full-size slide

  20. DOM
    Decouple Scroll Events

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  23. jank-free properties!
    transforms & opacity

    View full-size slide

  24. CSS will-change
    To the rescue!

    View full-size slide

  25. Passive Event Listeners
    To the rescue!

    View full-size slide