本周黑板报 #1

身为技术 er，特别是大龄程序员，在当前糟糕的社会大环境中生存，心中常存一丝焦虑，这样的焦虑是由不稳定性、缺乏成就、同辈压力催生的

读书心得

最近在读《人生效率手册》这本书，虽然我是不推荐的，内容夹杂个人私货、废话多且反复、吹牛逼、浮于表面不触地面，但其中某些理念还是比较认可的，修炼硬本领
确实，投资自己，为自己的人生设定目标，对目标进行拆分实现步骤，真正落实到位，打怪升级一样让自己不断成长，不断修炼自己身边优秀之人身上的优秀品质，甚至超越他们，让其成为自己的硬本领，才能缓解以上的那些焦虑

上班

从 b 站裸辞，来到大厂也 4 个月了，仿佛试用期的成长是最迅速的，顶着很高的 OKR、熟悉环境、和新同事打交道，那段最艰难的时间扛过来了。成为正式员工后，仿佛一切压力都消失了，也没有很好很新的技术可以学习，也没有很复杂的项目可以接手，雀食，不能靠工作去成长哇！
我发现厂里代码托管平台还是有不少仓库值得学习的，毕竟真实应用到了生产环境，且有这么大体量的 UV/PV，好了，这下有方向了，把感兴趣的库 clone 下来自主学习，不仅能白嫖还能学到技术！😏

上班摸鱼

Tailwind

厂里一块业务项目用到了 Tailwind，以前知道这个玩意儿，当时觉得要记很多类名，元素上写一大串也挺不爽的，就没深入去了解。但是进厂之后才发现，厂里常态抓性能优化（这个后面也会出个系列拎出来细说），业务开发维护也都要用到，因此看了一天官网文档，也清晰了

优势

那在我看来，Tailwind 明显的优势在于：

css 经过了优化，据说多数项目打出的 css 不会超过 10KB，传统手撸可能会有非常多重复的代码，应用有更好的性能；

语义化转原子化，且遵循一套设计规范，细粒度、支持自定义，相比style内联魔法值、类命名因人而异，更加受约束

不用单独维护 css 文件，删除元素时不用担心相应类名如何删除，而且不存在样式冲突问题

开发体验，不用在 css 与 html / 组件间来回切，给元素加上类名一套写下来行云流水；

相比它的劣势，我是完全能接受的。因此在下个新项目或对已有项目做性能优化时，我可能也会将引入 Tailwind 原子化进一步缩减 css 体积作为一个手段

相关库

tailwind-merge
解决类名样式合并的问题，将样式正确进行覆写

Copy
import { twMerge } from 'tailwind-merge'

twMerge('px-2 py-1 bg-red hover:bg-dark-red', 'p-3 bg-[#B91C1C]')
// → 'hover:bg-dark-red p-3 bg-[#B91C1C]'

class-variance-authority
根据组件各属性，为组件生成不同类名组合。可结合 Tailwind 创建自己的组件

Copy
// components/button.ts
import { cva } from "class-variance-authority";

const button = cva(["font-semibold", "border", "rounded"], {
variants: {
intent: {
primary: [
"bg-blue-500",
"text-white",
"border-transparent",
"hover:bg-blue-600",
],
// **or**
// primary: "bg-blue-500 text-white border-transparent hover:bg-blue-600",
secondary: [
"bg-white",
"text-gray-800",
"border-gray-400",
"hover:bg-gray-100",
],
},
size: {
small: ["text-sm", "py-1", "px-2"],
medium: ["text-base", "py-2", "px-4"],
},
},
compoundVariants: [
{
intent: "primary",
size: "medium",
class: "uppercase",
// **or** if you're a React.js user, `className` may feel more consistent:
// className: "uppercase"
},
],
defaultVariants: {
intent: "primary",
size: "medium",
},
});

button();
// => "font-semibold border rounded bg-blue-500 text-white border-transparent hover:bg-blue-600 text-base py-2 px-4 uppercase"

button({ intent: "secondary", size: "small" });
// => "font-semibold border rounded bg-white text-gray-800 border-gray-400 hover:bg-gray-100 text-sm py-1 px-2"

clsx
一个 CSS-IN-JS 库，这里引用其官方非常精简介绍：

A tiny (239B) utility for constructing className strings conditionally.
Also serves as a faster & smaller drop-in replacement for the classnames module.

条件判断值 true/false 动态添加删除 css 类，如：

Copy
import clsx from 'clsx';
// or
import { clsx } from 'clsx';

// Strings (variadic)
clsx('foo', true && 'bar', 'baz');
//=> 'foo bar baz'

// Objects
clsx({ foo:true, bar:false, baz:isTrue() });
//=> 'foo baz'

// Objects (variadic)
clsx({ foo:true }, { bar:false }, null, { '--foobar':'hello' });
//=> 'foo --foobar'

// Arrays
clsx(['foo', 0, false, 'bar']);
//=> 'foo bar'

// Arrays (variadic)
clsx(['foo'], ['', 0, false, 'bar'], [['baz', [['hello'], 'there']]]);
//=> 'foo bar baz hello there'

// Kitchen sink (with nesting)
clsx('foo', [1 && 'bar', { baz:false, bat:null }, ['hello', ['world']]], 'cya');
//=> 'foo bar hello world cya'

tailwindcss-animate、tailwindcss-animated
Tailwind 动画插件

Preact

优化厂里的应用时，发现 INP 上报值 TOP10，其中大于 200 的多数 case，INP 元素都是html或html>body，INP 交互事件都是pointerdown/up或keydown/up

这种情况在本地浏览器模拟CPU x4 slowdown时是必现的，而且与网速无关。
经我推测，与该应用采用了同构 + 流式渲染方案有关，流式第一段让用户看到部分页面内容后，这时用户可能就与页面发生了交互，而客户端交互是依赖入口 js 文件执行的，hydration 注入交互后才会有响应。
点击空白处，INP 被统计：

任意按键按下，INP 被统计：

Performance 跑了下性能：

特别是在设备性能差的情况下，js 下载不受影响，但解析、执行或许受到了点影响，造成很高Input delay的概率更高。
排查厂里应用 INP 问题时发现，引入的react.production.min.js与react-dom.production.min.js在初始加载阶段阻塞了用户交互，因此不得不从框架选型的层面考虑是否有比
这不巧了么，preact 据说可以作为react的平替，而且竟然生产版本体积只有 3.5KB，太牛逼了吧

能带来性能优势，这是否能优化 INP 呢？将来有机会试试

有趣的事

查看包体积、下载时长在线工具 bundlephobia

一本有趣的插画书籍《生活蒙太奇》，生活当中的一些小事，治愈、共情，此时此刻我所想的世界上某时某刻也一定有同样的所想

博客封面取自 500px