Loading...

Follow Swizec Teller - A geek with a hat on Feedspot

Continue with Google
Continue with Facebook
or

Valid

When was the last time you had to make sure your app works on weird browsers like Microsoft Edge?

Me, I had to do it earlier this week. My experience building websites for a web agency back in high school meant I knew what I was getting into.

Client: Hey can you make it work on Edge?

and here I was thinking I could go to bed early tonight pic.twitter.com/oBqRKe6VYz

— Swizec Teller (@Swizec) March 19, 2019


Microsoft Edge did not disappoint.

Array.flat() doesn’t work on Edge. On every other browser it flattens nested arrays. On Edge it blows up and says the method doesn’t exist.

CanIuse for Array.flat

Okay not every browser. Only the ones that people use.

You can solve that with a polyfill right? An npm package that loads itself up and makes Array.flat work.

Yep, makes the error go away. Doesn’t behave the way it does on other browsers.

So I had to replace every .flat() with my own hack like this: .reduce((arr, vals) => [...arr, ...vals], []). Sigh

In this project I was also using chroma-js to manipulate colors. Convenient way to take a color and give it a little alpha channel with chroma(color).alpha(0.5).

Except on Edge this created invalid hex values. Colors no work at all.

Had to hack it together like this `rgba(${chroma(color).alpha(0.5).rgba().join(',')})

You thought that was bad? It gets even better!

Oh also on Edge node.getBoundingClientRect() doesn't return a DOMRect. Oh no, it returns a ClientRect.

Unlike DOMRect, ClientRect (which exists only on Edge) doesn't have x and y coordinates. Only top and left

— Swizec Teller (@Swizec) March 19, 2019

.getBoundingClientRect() doesn’t work on Edge. Well it does but it returns a ClientRect instead of a DOMRect. They work the same except when they don’t.

For example DOMRect has x and y coordinates. ClientRect only has top and left. Oh and ClientRect only exists on Edge. Of course.

This meant I had to fix my useDimensions library. Project relies on it a lot to measure stuff and build responsive data visualizations.

Oh and flexbox doesn’t work correctly. Instead of spacing evenly it bunches everything on the left. Of course.


The hero in this story is BrowserStack

Despite all this pain, there is a silver lining BrowserStack made testing on Microsoft Edge absolutely painless.

Well the testing itself was painful and the results made me cry but I could test.

I’m a Mac kind of guy you see. I don’t have Edge. I don’t have a Windows machine. I have zero interest in VirtualBox and futzing around with images and installing Windows on a partition and whatever else it used to take to test on weird browsers.

With BrowserStack I was able to run Edge in a Chrome tab. That’s right. A Chrome tab emulated an entire operating system running a full screen browser.

Edge probably runs on their servers and streams an image to the tab. Still, feels like magic.

BrowserStack open screen

BrowserStack really does support all browsers

You can use it for free for 15 minutes I think. I needed more so I ponied up a whopping $19 for a freelancer plan. That gave me 100 minutes.


You can even run things from localhost. No idea how they made that work. Type http://localhost:3000 into the URL bar and it actually goes to your localhost.

Just don’t type localhost:3000 because Edge doesn’t know how to deal with that and says it can’t reach the URL.

And here’s proof. Edge running inside Chrome showing my homepage.


Amazing.

Lucky for us Microsoft is replacing the Edge browser engine with Chrome some time soon. Maybe then we won’t need this anymore

Cheers,
~Swizec

The post BrowserStack – a less painful way to test weird browsers appeared first on A geek with a hat.

Read Full Article
  • Show original
  • .
  • Share
  • .
  • Favorite
  • .
  • Email
  • .
  • Add Tags 

The other day I was dealing with some laggy UI on a project and discovered React.memo as a way of fixing it. I don’t know how long React.memo has been a thing but it’s new to me and it’s amazing.

And when I say laggy UI, I mean really laggy UI.

Here’s a gif of me typing full speed at 120wpm into a form.


Yeah, real bad.

After a few small tweaks tho …


Let’s start with how #1 happened, then what you might do to get to #2. .

PS: this article is heavy in gifs, please be patient

How to make a slow UI

There’s a few key components to a slow UI and they all have to do with doing too much on too many state updates. I can’t share the exact codebase so here’s a rough analog I built in CodeSandbox.

In the original code my state structure follows the unidirectional dataflow principle. State for all components lives in App and flows down via props.

The state object is deep and convoluted so for ease of use, onChange callbacks are colocated with state.

Many components rely on this state which means that each keystroke re-renders the whole UI.

  • a bunch of tags
  • a big dataviz
  • many tooltips
  • a few things I can’t remember

The underlying reason why each keystroke leads to a full re-render is that I’m treating state as immutable. Every keystroke creates a new copy of the entire state tree.

JavaScript compares objects by reference.

{foo: 'bar'} === {foo: 'bar'} // false

Great for making sure your whole UI is always up to date. Bad for performance.

React time slicing

First avenue of attack is to debounce user input. Update your UI asynchronously on each keystroke instead of forcing your user to wait.

Two ways you can approach this:

1) Turn your <input> into a component, use local state to drive its value, call the global onChange callback every few milliseconds. This works but increases complexity.

2) Use React time slicing and make this.setState itself asynchronous. Can’t remember which version of React this came with, maybe 16.4 … it works real good.

onChange: value => {
  let { values } = this.state;
  values = [...values];
  values.push(value);
  values[0] = value;
  
  this.setState({ values });
}

onChange: value => {
  let { values } = this.state;
  values = [...values];
  values.push(value);
  values[0] = value;

  window.requestIdleCallback(() => this.setState({ values }));
}

Instead of immediately updating our state, we wait for a browser idle callback. Basically saying "Yo browser, do this when you got some time will ya?"

The result is a faster app with a somewhat cumbersome typing experience.

React.memo

Your best bet isn’t to make updates asynchronous, it’s to avoid them completely.

In ye olden days you’d do that with shouldComponentUpdate. It’s 2019 now and we don’t do that anymore. We’ve got something much better React.memo.

React.memo takes a functional React component and memoizes it. First param says what to memoize, second param says when to bust the cache.

It’s a lot like useEffect but for entire components. You tell React exactly when you’d like to re-render.

Like this

export const MemoRecursive = React.memo(
  ({ values }) => {
    // render values
  },
  (prevProps, nextProps) =>
    JSON.stringify(prevProps) === JSON.stringify(nextProps)
);

First argument is a functional component. When rendering, React.memo calls your comparison function, the second argument, and if that returns true, it updates your component.

I’m using JSON.stringify as a dirty deep equals. You might want to use one of the many fast deep equals libraries out there. Or maybe there’s a specific prop value you can check.

The result is an app with smooth UI

Using recursion was a bad example it turns out. Props are never the same so memoization can’t kick in. Oops.

Tried fixing it by building the array head-first instead of tail-first. Didn’t quite work.

In the real-world, though, React.memo made a huge difference! Compare these outputs from the Chrome Profiler. I was typing this is a test into my input box both times.



Took 4 seconds to type and render without these optimizations. 1 second with.

In other news

In other news, my two Reactathon workshops are almost fully sold out. You should consider joining, if you’re in town. Great conference too. I’ll be there hanging out all weekend

React for DataViz workshop
Build a modern app workshop

Next two weeks are going to be intense with prep for those workshops. But it’s okay, I’m running a marathon on Sunday to give myself a break.

Enjoy your week

Cheers,
~Swizec

The post Fixing laggy UI with React.memo appeared first on A geek with a hat.

Read Full Article
  • Show original
  • .
  • Share
  • .
  • Favorite
  • .
  • Email
  • .
  • Add Tags 

Yes it’s new, I just open sourced it

The other day I wanted to measure some DOM nodes. This is useful when you have to align items, or respond to browser width, or … lots of reasons okay.

I had to align a curvy line with elements that aren’t under my control. This little stepper component uses flexbox to evenly space circles, CSS layouting aligns the title, and you see where this is going.

Doesn't look like much but it's handy for data visualization. Especially when you want to align things with other things.

I used a few of those snippets to position a curved line on this stepper pic.twitter.com/W9RLizRLPG

— Swizec Teller (@Swizec) March 12, 2019

SVG in the background detects position of itself, positions of the title and circle, and uses those to define the start and end line of my curve.

Many ways you can do this.

@lavrton linked to a list of existing NPM packages that sort of do it. @mcalus shared how he uses react-sizeme to get it done.

All great, but I wanted something even simpler. I also didn’t know about them and kind of just wanted to make my own.

Here’s an approach I found works great

Last night I figured out how to measure DOM dimensions with React Hooks. I'm sure it's been covered before but I had fun finding out. #200wordsTIL pic.twitter.com/TmFWZ9Chk0

— Swizec Teller (@Swizec) March 12, 2019

useDimensions hook

This seemed like a neat approach so I turned it into an open source React Hook. You might enjoy it.

useDimensions source

Yep that’s it. It really is that simple.

GitHub link

  • useRef creates a React.ref, lets you access the DOM
  • useState gives you place to store/read the result
  • useLayoutEffect runs before browser paint but after all is known
  • getClientBoundingRect() measures a DOM node. Width, height, x, y, etc
  • toJSON turns a DOMRect object into a plain object so you can destructure

Here’s how to use it in your project

First, add useDimensions to your project

$ yarn add react-use-dimensions
or
$ npm install --save react-use-dimensions

Using it in a component looks like this

import React from 'react';
import useDimensions from 'react-use-dimensions';

const MyComponent = () => {
    const [ref, { x, y, width }] = useDimensions();
    
    return (
        <div ref={ref}>
            This is the element you'll measure
        </div>
    )
}

useDimensions returns a 2-element array. First the ref, second the dimensions.

This is so multiple useDimensions hooks in the same component don’t step on each others’ toes. Create as many refs and measurement objects as you’d like.

const MyComponent = () => {
    const [stepRef, stepSize] = useDimensions();
    const [titleRef, titleSize] = useDimensions();
    
    console.log("Step is at X: ", stepSize.x);
    console.log("Title is", titleSize.width, "wide");
    
    return (
        <div>
            <div ref={stepRef}>This is a step</div>
            <h1 ref={titleRef}>The title</h1>
        </div>
    )
}

MIT License of course.

Consider retweeting if you think it’s neat

useDimensions is now an open source react hook

GitHub –> https://t.co/CNPj4RVfOw
short blog –> https://t.co/S5Wp6PJX95

Simple and works great pic.twitter.com/8ZWYUCUhIe

— Swizec Teller (@Swizec) March 13, 2019

Enjoy
~Swizec

The post useDimensions – a React Hook to measure DOM nodes appeared first on A geek with a hat.

Read Full Article
  • Show original
  • .
  • Share
  • .
  • Favorite
  • .
  • Email
  • .
  • Add Tags 

I could never understand why people keep asking me this one stupid question. A question with an answer so obvious it made no sense why everyone kept asking. EVERYONE.

“Hey Swiz, how do I structure my project?”

“Hey Swiz, where do I put this code?”

“Hey Swiz, do I use folders or not?”

“Hey Swiz, how many components in a file?”

“Hey Swiz, where do I put my styled components?”

It. Doesn’t. Matter. Put your stuff wherever! When it feels untidy, tidy it up.

I keep structure flat for small projects. When projects get big I group things in folders. Stuff that works together goes together.

But I get it now, I get it

But I get it now. I understand why everyone asks this.

Last week I inherited a Kotlin project at dayjob.exe. I knew it was coming, I just didn’t prepare

Kotlin, by the way, is a programming language that compiles to Java bytecode. Runs on the JVM. Often used for Android development, we’re trying it for AWS Lambdas.

Got tired of Ruby and its loose approach to types, don’t want to write raw Java because it’s meh, consider Scala to be too much of a mess. That leaves Kotlin.

NodeJS with JavaScript or TypeScript got disqualified I’m not sure why. Python too.

¯\_(ツ)_/¯

The time has come for me to learn Kotlin. Because reasons

First surprise: It takes 700MB of space just to install the language. No IDE or anything.

node_modules ain’t got nothing on this

— Swizec Teller (@Swizec) March 5, 2019

So here I am trying to learn Kotlin

So here I am trying to learn Kotlin and … ho boy it’s been rough. Took me two days just to get my code to run locally.

Being in a Lambda environment doesn’t help.

You install Kotlin and set up VSCode with Kotlin support. I tried IntelliJ’s IDEA environment. Hated how it looks, hated how clunky it felt, didn’t wanna use it.

I’m told using VSCode will punish me in the future. It’s already missing the jump-to-definition stuff it can do in JavaScript and even Ruby.

Statically typed languages like Kotlin and Java are supposed to make that feature easier to implement … ¯\_(ツ)_/¯

Syntax highlighting doesn’t work great either. Oh well.

Ok so I get that set up and after a painful run at installing Java I can run small examples right in my editor. Wonderful!

O oh … pic.twitter.com/nXGppnelUK

— Swizec Teller (@Swizec) March 5, 2019

Ah yes. The popup modal links you to the wrong thing, you need JDK, not JRE, whatever that is. How absolutely obvious why didn’t I think of that

Thanks StackOverflowhttps://t.co/yZ4Q1XSP2m

— Swizec Teller (@Swizec) March 5, 2019

How was I supposed to know the popup gives you the wrong thing?

Blogs and articles about Kotlin don’t tell you this because they all assume you’re coming from a Java background and have everything running. Not me

And then it gets worse

Then my instructions, from the lady who started this project, say that I have to run ./gradlew. Gradle is some sort of better compiler for Kotlin. Using kotlinc directly is too hard?

Gradle itself also isn’t good enough so everyone uses gradle wrapper called gradlew.

It’s a bit like having npm. You specify dependencies and stuff in a build.gradle, which is written in Groovy, and when you run ./gradlew it installs dependencies then compiles your code.

Oh except running gradlew doesn’t work because it needs a .jar file that is supposed to be part of your repository. But .jar files are in .gitignore because obviously you don’t want compiled files in your git.

Jar files are the compiled result of Java programs. It’s like a package with compiled code and some other stuff.

I forget what I had to run, but I had to compile my compile tool before I could compile my code.

And then I learned about something called SAM – Serverless Application Model. It’s an Amazon tool that lets you run cloud functions locally.

Except it didn’t work.

Complained about Docker. Don’t need to set up Docker, just have it on my computer. SAM uses that to simulate lambdas … I think.

Then SAM complained about my AWS configuration. Not that it told me this, Twitter told me this after seeing my error screenshot.

AWS uses local config files in ~/.aws to get your AWS credentials and stuff. I set those up as per my predecessor’s instructions. Didn’t work.

Googled around and I needed some sort of awscli that has a configure command. Used two different ways to install, both succeeded, neither worked.

Trying to install the aws cli so I can properly configure stuff. Thanks @NejcRavnik for the idea

Tried 2 ways to install: running a bash command and with pip3

Both succeed.
Neither installs aws-cli. It’s literally not in the only Python path I have on my computer pic.twitter.com/m7QC2vrLON

— Swizec Teller (@Swizec) March 7, 2019

Rebooting my computer made it work. No idea why. Yes I tried restarting terminal to pick up new binaries.

By now it’s been two days and learning Kotlin feels a lot like running through a brick wall.

But I could run my code locally

IT LIVES pic.twitter.com/xFa2ZWjPJs

— Swizec Teller (@Swizec) March 7, 2019

And then … I didn’t know where to put my code

I could run my code, I could deploy my code, I couldn’t run my code in production because some Lambda wasn’t giving permissions to another Lambda and it breaks.

So I figured I’d start with unit tests.

My predecessor didn’t set that up and you want your backend code thoroughly tested. Manual QA only goes so far.

I searched the internets. My results were bad.

Training Google to give good results is a big part of learning a new language or technology. Takes a while. Takes a while to learn what to search for too. All the key phrases, technology names, the good websites …

Learning completely new tech is an eye opening experience.

I know everything about Kotlin unit testing. I know what the good libraries are, I know how to write tests in the one I picked, I even know how to configure them.

But I don’t know where to put files or how to run them.

— Swizec Teller (@Swizec) March 9, 2019

After much reading and investigating I learned of a thing called KotlinTest. It’s a powerful framework for testing Kotlin that supports many different styles.

One of them looks like Ruby RSpec tests I’m used to.

KotlinTest it is!

Okay … where do I put these files? How do I run them?

Every guide and blog assumed I already know this. Oh you’re trying to test your Kotlin code? Obviously you know how to write a valid Kotlin file, where to put it, which imports to use, and how to run it.

Yeah no I had no idea.

This was an example in docs:

class MyTests : StringSpec({
  "length should return size of string" {
    "hello".length shouldBe 5
  }
  "startsWith should test for a prefix" {
    "world" should startWith("wor")
  }
})

The file you actually need to write looks like this:

package your.stuff

import io.kotlintest.specs.StringSpec
import io.kotlintest.shouldBe

class MyTests : StringSpec({
  "length should return size of string" {
    "hello".length shouldBe 5
  }
  "startsWith should test for a prefix" {
    "world" should startWith("wor")
  }
})

Banged my head against that wall for an hour. Such a small thing, so hard to figure out on your own.

Like, I resorted to reading KotlinTest source files to figure this out that’s how bad all the guides are.

And I still didn’t know where to put it or how to run it.

Figured that out after many more frustrating hours of banging my head through this damn brick wall. You put files in src/test/your/stuff/test.kt and run them with ./gradlew test.

After you set up a new test {} area in build.gradle of course. Super obvious.

At least the guides told me how to configure Gradle …

So yeah I get it now, I understand why video courses are so popular (you can see what’s happening and where things go), I see why people ask seemingly obvious questions.

Learning very new stuff is hard. Everyone assumes you have background knowledge that you don’t have. sigh

Sorry if I ever do that. Please call me out on it.

Cheers,
~Swizec

PS: yes it’s a balance. Otherwise you might as well explain how 1+1 works in every article …

The post Learning a new field is super hard, I get it now 😅 appeared first on A geek with a hat.

Read Full Article
  • Show original
  • .
  • Share
  • .
  • Favorite
  • .
  • Email
  • .
  • Add Tags 

Ah the infamous TODOapp. Remember those?

Feels like TODOapps were everywhere a few years ago.

“Look at me! I built a TODOapp with React”

“Mine’s in Vue!”

“Mine’s Angular”

“Hey over here, this TODOapp uses styled components and GraphQL”

Who cares. How many TODOapps do you need, sheesh

The TODOapp and the counter component star in every tutorial for a new framework or language. Quick to understand, a little complex but not too much, absolutely boring to build and look at.

Don’t you want something better to do?

Why not learn modern React by building apps you can show off?

Something you can show your friends and they’ll say “Wow that’s cool”, show your spouse and they’ll go “That’s nice honey”, or your mum and she’ll say “Holy shitballs that’s the most amazingest thing I have ever seen did you eat your veggies!?”

Veggies are important.

Don’t you want to build something you’re gonna have fun building? Something that makes you proud and looks good on your portfolio.

Yeah me too

Here’s how I learned React

Straight to the HackerNews front page it went. 21,259 people saw my very first React app on its first day. 71,894 in total. That’s a new screenshot from localhost, I need to update production

You build this in React for Data Visualization. Yours is gonna use modern React patterns and a special chapter shows you how to refactor with React Hooks. Those came out just last month.

My next app was about learning Flux.

This was before Redux. First time people started talking about the “unidirectional dataflow” and how it revolutionizes the way we think about web apps.

So I built a space invaders game.

That’s when I realized building a data visualization is just like a video game. Everything you build with React is like a video game.

You have your game engine, that’s React, it handles renders and rerenders, figures out what changes from one paint to another, etc. You never have to worry about any of that.Build your components, take care of your business logic, and React figures out how to translate your imagination to your DOM.

React Space Invaders was good enough for a talk at a huge conference in San Francisco. My room was packed full. No pressure

HTML5DevConf: Swizec Teller, swizec: Reusable data visualization with React and d3.js - YouTube

This one doesn’t feature in React for Data Visualization but the lessons I learned are all there: A whole chapter on the game loop approach to fine-tuned animation.

Then someone asked me “What if we have tens of thousands of datapoints to display?”

And I decided to find out. Why not learn Redux while we’re at it. The result was a semi-famous React particle generator that animates 20,000 data points even on your phone.

Fun to build and that series of blog posts got thousands of readers. Even got me a spot on a web animation panel at ForwardJS that year.

I bombed the panel but I was there. That looked great on my visa application.

Here’s another popular one: The dancing pythagorean fractal tree. Started as an experiment in recursion with React components, turned into a stress test, then a comparison of web frameworks.

@_developit, creator of Preact, and @youyuxi, creator of Vue, liked it so much they built their own versions to test Preact and Vue. The experiment features in React for Data Visualization so you can compare and see which framework fits your style.

D3 doesn’t discriminate. Same approach works with all modern component-based frameworks. I just happen to like React

Here’s another fun one

Did you know more Americans move to Mexico every decade than the other way around? UN data says so.

I don’t know what I tried to learn there but it looks cool. Colors for intensity of immigration, arcs with flying circles show density, searchable dropdown helps you explore the map.

Makes people go wow at the dinner table

Ready to make your dinner table go wow? Consider joining React for Data Visualization

reactfordataviz.com

Prices go up this Friday.

Cheers,
~Swizec

PS: I’m adding a bunch of bonus material this weekend. Plus a gift for students who buy this week

The post Why dataviz does better for your career than TODOapps appeared first on A geek with a hat.

Read Full Article
  • Show original
  • .
  • Share
  • .
  • Favorite
  • .
  • Email
  • .
  • Add Tags 

Separate tags by commas
To access this feature, please upgrade your account.
Start your free month
Free Preview