深层dom树和过多节点导致路由切换卡顿,超12层嵌套或总节点超2000个会显著拖慢重排;应精简结构、用documentfragment、display:contents优化,并修复ejs移动节点及hashchange初始化问题。

深层DOM树导致路由切换卡顿
路由切换时渲染慢,八成不是JS执行慢,而是新视图的DOM嵌套太深——浏览器重排(reflow)要从根节点递归计算每一层的样式与布局,超12层后低端设备就会肉眼可见延迟。折叠面板、表格行内编辑、动态插入区域最容易踩坑。
- 用Chrome DevTools → Elements面板右键节点 → 启用“Show DOM tree depth”(需在
chrome://flags开启实验功能),快速定位深度超标区域 - 避免直接
innerHTML插入整块多层HTML;改用document.createDocumentFragment()预建结构再批量append() - 表格行内编辑不用
<td><div><div><input></div></div></td>,换成display: contents容器,让input直接“透出”到tr层级,跳过冗余布局计算
DOM节点数失控拖慢首屏与切换性能
总DOM节点超2000个,layout耗时会指数级增长,尤其在低端安卓WebView或iOS Safari里。这不是CSS或JS优化能救回来的,得从结构源头砍。
文章转信息图。将文章/笔记转化为手机可读的 HTML 信息图,自动匹配视觉风格。触发场景:文章转图、笔记转图、信息图、转小红书图、做张图、可视化这篇文章、文生图。
- 运行
document.querySelectorAll('*').length查总数,SPA首屏建议≤500,整页控制在2000以内 - 删掉无意义的
<div>包装:居中用<code>flex、间距用gap、分隔线用::before,别堆三层<div> <li>服务端返回的EJS/HTML片段必须精简:去空格、删注释、合并冗余标签;用<code>DOMPurify.sanitize()过滤后再insertAdjacentHTML() - 错误写法:
layout.append(view.childNodes)——childNodes是Live NodeList,移动后原节点消失 - 正确解法:
layout.append(view)—— 整个#view-users-search元素被完整移动,结构和ID都保留 - 验证方式:控制台执行
document.querySelector('#view-users-search').childNodes.length,返回后为0即确认此问题 - 必须补一手初始化:
router(location.hash.slice(1) || '/') - 别用
window.onhashchange = handler,会被后续赋值覆盖,监听器静默丢失 - 匹配路径时务必先
slice(1)取纯路径段,否则#/user/和#/user判为不同
EJS模板路由切换时DOM丢失的根源
用EJS + 原生JS做SPA时,常见“首次正常、返回变空白”的问题,根本不是数据没加载,而是view.childNodes被移动而非复制,导致原容器变空,二次匹配时childNodes为空数组。
hashchange监听不全引发首屏白屏
只写window.addEventListener('hashchange', handler),但忽略首次加载时location.hash已有值——hashchange事件不会自动触发,结果刷新页面就白屏或错显默认页。
<div>问一句——它非得在这儿吗?</div>










