用 IntersectionObserver 实现图片懒加载与占位占高
列表页一次性渲染 200 张商品图,首屏要下载十几 MB 的图片,用户滑动时白屏、闪烁、滚动位置乱跳,这是最典型的图片加载问题。把 loading="lazy" 加在 <img> 上只能解决「什么时候下载」,解决不了「下载之前这块地方占多高」。图片没有尺寸,浏览器在图片解码前把它当 0 高度处理,图片到达后页面被撑开,原本已经滚到第 80 条的用
列表页一次性渲染 200 张商品图,首屏要下载十几 MB 的图片,用户滑动时白屏、闪烁、滚动位置乱跳,这是最典型的图片加载问题。把 loading="lazy" 加在 <img> 上只能解决「什么时候下载」,解决不了「下载之前这块地方占多高」。图片没有尺寸,浏览器在图片解码前把它当 0 高度处理,图片到达后页面被撑开,原本已经滚到第 80 条的用
Go 标准库提供了 channel 来做协程间通信,但 channel 不支持「队列长度到达上限后单独统计丢弃次数」这类自定义策略;而在需要精细控制唤醒时机、需要复用同一把锁保护其他状态、或者需要实现「批量入队 / 批量出队」语义时,sync.Cond 是更合适的基础原语。本文从零实现一个泛型有界阻塞队列 BoundedQueue[T],包含 Put(满时阻
写 Rust 业务代码时,最容易卡住新人的不是所有权,也不是生命周期,而是函数返回 Result 之后,各种第三方库的 error 类型对不上:serde_json::Error 想变成自己的 AppError,std::io::Error 也想变成 AppError,偏偏 ? 一写就报 the trait bound `AppError: From<
在 TypeScript 项目里,把 unknown 或 any 收窄成具体类型是每天都要做的事。最常见的翻车现场是:接口返回的 JSON 被断言成 User,运行时字段缺失,页面白屏,控制台只留下一句 Cannot read properties of undefined (reading 'name')。类型守卫(type guard)就是解决这个问题的
很多人写 with 语句时只关心「打开、关闭」这一层,能跑通就不深究。可一旦业务里出现异常被悄悄吞掉、__exit__ 里抛出新的异常覆盖了原始异常、或者 GeneratorExit 让 @contextmanager 报出 RuntimeError: generator didn't stop after throw(),就会调上一两个小时。这篇文章把 w
Go 1.18 引入泛型后,最实用的场景之一就是把"返回值 + 错误码"这种固定结构的接口统一起来。本文用一个小例子讲清楚约束怎么写、什么时候该用。 问题:重复的返回结构 每个业务接口都要返回"数据 + 状态码 + 消息",手写三遍很烦:
asyncio 里"超时"和"取消"是一件事的两面:超时本质上是到点发取消信号。但很多代码只包了 wait_for 就以为万事大吉,真正的问题往往出在被取消的任务不肯干净退出。 最基础的写法 async def fetch(session,
sql.DB 本身就是一个连接池,但默认参数是为"单机演示"设计的。线上服务不调这三个参数,高并发下大概率会出现"连接打满、请求排队、P99 飙升"。 三个关键参数 SetMaxOpenConns(n):允许同时打开的最大连接数,防止把数据