前两天折腾个老项目,页面里表格数据一多就卡成PPT,翻开代码一看满屏的knockout绑定。寻思着给这老伙计升个级,顺手查了圈Knockout2.0的高级玩法,还真挖到宝了!
踩坑现场直击
原来项目里有个要命的foreach循环:
- 每次加载500条用户数据
- 每条数据绑6个*
- 嵌套了两层计算属性
刚点搜索按钮就看见浏览器标签页转圈圈,鼠标指针卡成电子表,等了三秒才吐出来数据——隔壁同事冲的挂耳咖啡都滴完了!
第一板斧:砍掉循环绑定时长
想起文档里提过虚拟滚动这招,抄起键盘就开始改:
- 先用div圈住表格区域限高500px
- 硬生生把foreach改成dataForEach插件
- 塞了个滚动事件监听器跟踪显示位置
手指敲回车那秒心跳加速,结果页面还是白茫茫一片!原来插件没引用对路径,控制台飘着红字报404。折腾半小时终于加载出来,首屏渲染快了1倍——虽然还是有点卡,但起码能看到表头了!
第二板斧:收拾计算属性烂摊子
翻代码发现有个致命操作:
- 用户状态计算属性里调了API
- 每行数据都去后台查权限
- 500条数据意味着500次请求
气得我直接摔鼠标:这不瞎搞吗!连夜改成纯函数计算:
- 把用户权限列表提前加载到内存
- 计算属性里直接查内存字典
- 所有计算属性加上pureComputed标记
改完刷新页面,加载进度条嗖地窜到头!鼠标滚轮滑到表格底部都不带抖的——低头看表才过了0.3秒!
终极大招:缓存数据变更
临下班前突然灵光一闪:表格里每行数据变更都触发全量渲染,这不冤大头吗?赶紧翻出Knockout的变更记录API:
- 给observableArray加上extend({ rateLimit:500 })
- 手动撸了个差异计算器
- 只更新变动的DOM节点
测试时故意修改第499行的用户名,浏览器开发工具盯着DOM看——果然只有单行闪烁刷新!500条数据局部更新只要5毫秒,比之前全量渲染快了整整20倍!
第二天演示给组长看,他端着枸杞茶杯半天没说话。憋出来一句:“这老项目...还以为得重写” 深藏功与名。建议各位遇上Knockout老项目:
- 先揪出过度渲染的循环
- 收拾乱跑的计算属性
- 给数据变更上个缓冲阀
这套组合拳打下来,十年陈的老代码照样跑得嗖嗖快!