打开网页时卡顿、点击按钮响应慢,这些常见问题背后往往藏着算法效率的问题。很多人以为只有后端才需要关心性能,其实浏览器里的JavaScript代码一样会因为低效算法拖累整体体验。
从一个搜索框说起
比如你正在做一个带自动补全功能的搜索框。用户每输入一个字符,就去遍历上千条商品名称匹配。如果用的是简单的for循环逐个比对,数据一多,页面就会明显卡住。这时候光靠升级电脑没用,得看代码怎么写。
一个更高效的做法是提前建立索引结构,比如把所有关键词按首字母分组,或者用前缀树(Trie)存储。这样用户输入“苹”时,直接定位到相关分支,不用扫全表。
别小看时间复杂度
同样是查找,O(n)和O(log n)在浏览器里表现天差地别。n=1000的时候可能看不出,但n上万,差距就出来了。Chrome开发者工具的Performance面板能帮你看到哪段JS执行时间最长,结合代码逻辑就能判断是不是算法出了问题。
实际优化示例
下面是一个低效的数组去重写法:
function removeDuplicates(arr) {
let result = [];
for (let i = 0; i < arr.length; i++) {
if (result.indexOf(arr[i]) === -1) {
result.push(arr[i]);
}
}
return result;
}
indexOf在内部又是循环,整体变成O(n²)。换成Set,瞬间降到O(n):
function removeDuplicates(arr) {
return [...new Set(arr)];
}
代码变短了,运行也快了,用户滑动页面时不会因为后台计算而掉帧。
善用浏览器的利器
除了Performance,Memory面板可以查内存泄漏,避免长时间运行的脚本把浏览器吃满。如果你写的插件或单页应用用了大量事件监听,记得及时解绑,否则即便算法再优,内存堆积也会让页面越来越慢。
还有个小技巧:大量DOM操作尽量合并。比如要添加100个列表项,不要每次循环都appendChild,先用DocumentFragment攒起来,一次性插入,减少重排次数。
响应优先于完美
有时候不需要立刻算出最终结果。比如排序上万条数据,可以用Web Worker把计算挪到后台线程,主线程先返回部分结果让用户看到,剩下的慢慢加载。这样感觉上快了很多,用户体验自然就好。
算法效率不是纸上谈兵,它直接体现在页面是否流畅。下次写完功能逻辑,不妨多问一句:这段代码在10倍数据量下还能跑得动吗?