Performant JSS
At work, I mainly use Material-UI. It's a really useful library that offers great defaults, great theming, and a decent, though rather complicated, styling system.
I've come to see that the most performant way to style with JSS is to do it less. Huh?
Selectors are your friend
I've realized I started to think in "components" whenever I use JSS. It's probably because it's really a react-only thing.
However, when I start to think in CSS, it suddenly makes JSS much simpler.
Intuitively we use JSS in a manner similar to this:
1const styles = createStyles({2 table: {3 padding: "1rem",4 },5 tableHead: {6 fontWeight: "bold",7 },8 tableHeadCell: {9 fontSize: "0.75rem",10 },11 tableRow: {12 padding: "0.5rem",13 },14 tableRowCell: {15 fontSize: "0.5rem",16 },17});1819let useStyles = makeStyles(styles);2021function TableComponent(props) {22 let { items, columns } = props;23 let classes = useStyles();24 return (25 <table className={classes.table}>26 <thead className={classes.tableHead}>27 {columns.map((column) => (28 <th className={classes.tableHeadCell}>{column}</th>29 ))}30 </thead>31 <tbody>32 {items.map((row) => (33 <tr className={classes.tableRow}>34 {row.map((cell) => (35 <td className={classes.tableRowCell}>{cell}</td>36 ))}37 </tr>38 ))}39 </tbody>40 </table>41 );42}
I'm using good ol' fashion JSS here, but you can imagine the same principle with styled-components/emotion
Seems familiar right? Each style is it's own "component".
However, you can make this more performant by applying the styling once rather than to every item within the table by using one simple trick - selectors:
1const styles = createStyles({2 table: {3 padding: "1rem",4 "& thead": {5 fontWeight: "bold",6 "& th": {7 fontSize: "0.75rem",8 },9 },10 "& tbody": {11 "& tr": {12 padding: "0.5rem",13 "& td": {14 fontSize: "0.5rem",15 },16 },17 },18 },19});2021let useStyles = makeStyles(styles);2223function TableComponent(props) {24 let { items, columns } = props;25 let classes = useStyles();26 return (27 <table className={classes.table}>28 <thead>29 {columns.map((column) => (30 <th>{column}</th>31 ))}32 </thead>33 <tbody>34 {items.map((row) => (35 <tr>36 {row.map((cell) => (37 <td>{cell}</td>38 ))}39 </tr>40 ))}41 </tbody>42 </table>43 );44}
Selectors are your friend.