Swizec Teller - a geek with a hatswizec.com

    Trying the new ResizeObserver and IntersectionObserver APIs

    You might remember the useDimensions React Hook I opensourced a few weeks ago. 246 stars, 2 issues, and 1 merged PR make it the most useful library I ever released 💪 Some 10 days ago I made it update measurements live. Needed to make this working for a client project 👇 Scrollable overlay highlight
    Scrollable overlay highlight
    It's not perfect, but that highlight is a hole punched through a darkened canvas. It uses useDimensions for positioning and needs to update when you scroll. Works good enough. Built with hooks, live updating looks like this: techletter app screenshot 1554309442351

    We use a useLayoutEffect to run our code synchronously on DOM updates. Inside, we check that the node exists, then create a debounced measure() function. Measure runs on requestAnimationFrame so we don't kill the browser even if the code falls into an infinite loop. You might get small subpixel resizes forever because of layouting edge cases. I've seen it happen. It's bad. getDimensionObject gets measurements, setDimensions is the state setter from a useState hook. You can see full code here. Window resize and scroll listeners will re-run our measure() function when things change. Scrolling will change its position, resizing might change its dimensions. There's a problem here 👉 if the container resizes and the window doesn't, we'll have stale dimensions. When you use JavaScript or CSS to resize an element in response to user events, for example. No bueno.

    IntersectionObserver to the rescue!

    Last night I decided to fix that with the new IntersectionObserver API

    https://www.youtube.com/watch?v=uSmd6VMEMTo
    https://www.youtube.com/watch?v=uSmd6VMEMTo
    After some research I realized I was wrong. IntersectionObserver doesn't do what I thought it does, but it's super neat anyway. You want to use the IntersectionObserver API when you have two DOM nodes and you want to know when their intersection changes. It's all in the name right? A common use-case is something like my react-lazyload-fadein library where you want to lazy load images juuuuust before they become visible. You could create a new intersection observer between the document and your placeholder node and wait for notifications. Super neat, not what's going to fix our resize edge case.
    https://twitter.com/Swizec/status/1113313756325355520
    https://twitter.com/Swizec/status/1113313756325355520

    ResizeObserver, that's the thing 👌

    ResizeObserver is an even newer API. Mozilla calls it "experimental". Support is lacking, but there are polyfills you can use. I used this one The idea here is that you can create a new observer object, give it a DOM node to observe and it's going to call your function when something changes. You can give it multiple nodes too. Something like this 👇 techletter app screenshot 1554309485677

    Create a new ResizeObserver in an effect post initial mount. Give it a method that runs when the observer fires, make it observe your React element, return the disconnect function to clean up on unmount. Perfect. Much cleaner than the hacky solution 👌 Except it doesn't work. You can see it in the stream around the 29 minute mark. ResizeObserver was going crazy and firing as fast as we could read. Remember when I said you can run into subtle layouting edge cases where things are unstable and resize very often? That. So we gave up, reverted back to window.addEventListener, and left the edge case alone. Pretend like none of this ever happened. But it was fun to experiment :)

    Cheers,
    ~Swizec

    Did you enjoy this article?

    Published on April 3rd, 2019 in Front End, Livecoding, Technical

    Learned something new?
    Want to become an expert?

    Here's how it works 👇

    Leave your email and I'll send you thoughtfully written emails every week about React, JavaScript, and your career. Lessons learned over 20 years in the industry working with companies ranging from tiny startups to Fortune5 behemoths.

    Join Swizec's Newsletter

    And get thoughtful letters 💌 on mindsets, tactics, and technical skills for your career. Real lessons from building production software. No bullshit.

    "Man, love your simple writing! Yours is the only newsletter I open and only blog that I give a fuck to read & scroll till the end. And wow always take away lessons with me. Inspiring! And very relatable. 👌"

    ~ Ashish Kumar

    Join 15,161+ engineers just like you already growing their careers with my emails, workshops, books, and courses.

    ⭐️⭐️⭐️⭐️✨
    4.5 stars average rating

    Have a burning question that you think I can answer? Hit me up on twitter and I'll do my best.

    Who am I and who do I help? I'm Swizec Teller and I turn coders into engineers with "Raw and honest from the heart!" writing. No bullshit. Real insights into the career and skills of a modern software engineer.

    Curious about Serverless and the modern backend? Check out Serverless Handbook, for frontend engineers 👉 ServerlessHandbook.dev

    Want to Stop copy pasting D3 examples and create data visualizations of your own? Learn how to build scalable dataviz React components your whole team can understand with React for Data Visualization

    Want to become a true senior engineer? Getting the title's easy. Just stick around. Being a true senior takes a new way of thinking. The Senior Mindset Series can help 👉 SeniorMindset.com. It's my most loved series of essays.

    Want to get my best emails on JavaScript, React, Serverless, Fullstack Web, or Indie Hacking? Check out swizec.com/collections

    Want to brush up on modern JavaScript syntax? Check out my interactive cheatsheet: es6cheatsheet.com

    Did someone amazing share this letter with you? Wonderful! You can sign up for my weekly letters for software engineers on their path to greatness, here: swizec.com/blog

    Want to brush up on your modern JavaScript syntax? Check out my interactive cheatsheet: es6cheatsheet.com

    By the way, just in case no one has told you it yet today: I love and appreciate you for who you are ❤️

    Created by Swizec with ❤️