I'm procrastinating instead of working on a conference talk, so I decided to implement this component in Svelte to see which framework is most expressive:
Here's the original, with the addition of an import for dataUriAsSrc
(and updated per @chriskrycho's comment):
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
import { action } from '@ember/object';
import dataUriAsSrc from './dataUriAsSrc.js';
export default class AvatarComponent extends Component {
size = 48;
@tracked letterform;
get src() {
return this.letterform
? this.letterform
: `https://example.com/avatars/${this.args.companyId}`;
}
@action useLetterform() {
this.letterform = dataUriAsSrc(this.args.name, this.size);
}
}
Here's a Svelte version (demo):
<script>
import dataUriAsSrc from './dataUriAsSrc.js';
export let size = 48;
export let name;
export let companyId;
let letterform = false;
$: src = letterform
? dataUriAsSrc(name, size)
: `https://example.com/avatars/${companyId}`;
</script>
<img
class="rounded-full object-cover"
alt="Profile image for {name}"
src={src}
width={size}
height={size}
on:error={() => letterform = true}
>
And here's one using React hooks (demo):
import React, { useState, useMemo } from "react";
import dataUriAsSrc from "./dataUriAsSrc.js";
export default function Avatar({ size = 48, name, companyId }) {
const [letterform, setLetterform] = useState(false);
const src = useMemo(
() => letterform
? dataUriAsSrc(name, size)
: `https://example.com/avatars/${companyId}`,
[letterform, name, companyId, size]
);
return (
<img
className="rounded-full object-cover"
alt={`Profile image for ${name}`}
src={src}
width={size}
height={size}
onError={() => setLetterform(true)}
/>
);
}
They're all pretty sleek β much more so than frameworks of yore. I find it useful to compare both lines of source code and bytes of source code (to count bytes, copy to clipboard then run pbpaste | wc -c
in your terminal):
framework | lines of code | bytes of code |
---|---|---|
Svelte | 22 | 422 |
React | 24 | 607 (+44%) |
Ember | 27 | 673 (+59%) |
In summary: use Svelte π
Edited to clean up 2019/10/21.
If we're going for that nice compressed style that the React and Svelte ones have (which I admit to liking a lot) then the Octane component should look like this (
674570 bytes):Using the experimental
set
helper:Drops it by another 5. π (Also, and more importantly, reads much more nicely.)