页面卡顿?先看是不是DOM太臃肿
打开网页,滑动不跟手,点击没反应,这种情况很常见。很多人第一反应是网络慢,其实问题可能出在HTML结构本身。比如一个页面里塞了几万个DOM节点,浏览器光解析就得花好几秒,手机端更明显。可以打开开发者工具,看Elements面板里节点数量,如果超过5000个就要警惕了。
特别是用了一些老框架或者拼接字符串生成列表的场景,比如动态加载几百条商品信息,直接innerHTML一堆div,很容易拖垮页面。这时候应该考虑分页、虚拟滚动,或者用原生for循环控制每次插入的数量。
重排重绘别忽视
频繁操作样式会触发重排(reflow)和重绘(repaint)。比如在一个循环里不断修改元素宽高:
for (let i = 0; i < list.length; i++) {
element.style.width = i * 10 + 'px';
element.style.height = i * 5 + 'px';
}这种写法每轮都会强制浏览器重新计算布局。正确做法是先把样式收集起来,一次性更新,或者用CSS类来切换状态。
还有一个常见坑:读取offsetHeight、scrollTop这类属性时,也会强制触发重排。如果在循环中又改样式又读尺寸,性能直接崩掉。
图片和字体资源拖后腿
大图没压缩、WebFont加载阻塞,都是隐形杀手。比如页面首屏一堆高清背景图,每个几MB,就算HTML很快下来,视觉上还是白屏等资源。可以用Chrome的Network面板看资源加载时间线,重点关注Largest Contentful Paint(LCP)对应的元素。
字体方面,自定义字体没做fallback,浏览器会等字体下载完才显示文字,用户看到的就是空白。加上font-display: swap能缓解这个问题:
@font-face {
font-family: 'CustomFont';
src: url('font.woff2') format('woff2');
font-display: swap;
}JavaScript执行太久
长任务阻塞主线程,页面就没法响应交互。比如一段JS跑800毫秒,期间按钮点不动,输入框打不了字。用Performance面板录一段操作,看有没有超过50ms的长任务。
解决办法是拆任务,用setTimeout或requestIdleCallback把工作分片处理。比如处理一万条数据,不要一口气遍历完,可以每次处理100条,让出控制权给浏览器喘口气。
过度使用CSS复杂选择器
写样式图方便,来一句div ul li span em,看着没问题,但浏览器匹配是从右往左查,这个选择器要遍历所有em标签再往上找父级,节点一多就慢。尽量用类名直接定位:.menu-item比ul li a快得多。
还有animation和transition滥用的问题。给transform和opacity加动画还好,要是动不动就改margin、height,每次都触发布局重排,动画必然卡顿。该用transform位移就别用margin顶。
设备适配别一刀切
同一个页面在旗舰机流畅,在千元机卡成幻灯片,很正常。测试不能只盯着MacBook加Chrome。找个低端安卓机连上DevTools看看表现,很多时候问题就暴露了。比如某些机型对flex布局支持差,嵌套层级一深就掉帧。
可以针对低配设备降级体验,比如关闭复杂动效、简化DOM结构、用静态布局替代Flexbox,保证核心功能可用。