input处理函数是潜在的影响你app性能的问题,他们可以阻止帧的形成,并且可以造成多余的亦或不必要的layout的工作。
- 避免长时间运行input handler:它们会阻塞scroll
- 不要在input handler 中进行样式的改变
- Debounce 你的处理函数; 存储事件值并且在下一次requestAnimationFrame回调中处理样式改变
避免长时间运行的input处理函数
在最迅速的运行情况的假设下,当一个用户和页面进行交互的时候,页面的合成器线程(a compositor thread)可以获取用户的输入且移动输入的内容。
页面合成器线程在进行相关操作的时候,要求主线程不在进行任何的工作(js,layout和style以及paint都在主线程中进行)
当你使用了输入处理函数,例如 touchstart
, touchmove
, 亦或 touchend
,合成器线程必须等到处理函数执行完成,同样,用户的scroll也会被阻塞。
总之,你要确保用户输入处理函数尽快的被执行,且允许合成器来做这一项工作。
避免在输入处理函数中进行样式操作
输入处理函数,例如scroll和touch,在任何requestAnmationFrame回调函数之前被计划运行。
如果你在一个inout handler里面进行了一个样式的改变,那么在requestAnimationFrame开始的时候将会进行样式计算,然后会读取元素的样式属性在requestAnimationFrame回调函数执行的刚开始,这将触发一个同步的layout!
scroll处理函数去抖动(debounce)
所以你要做的是,在下一个requestAnimationFrame回调函数中去除视觉修改抖动。
function onScroll (evt) { // Store the scroll value for laterz. lastScrollY = window.scrollY; // Prevent multiple rAF callbacks. if (scheduledAnimationFrame) return; scheduledAnimationFrame = true; requestAnimationFrame(readAndUpdatePage); } window.addEventListener('scroll', onScroll);
上面代码的好处是在使用input handler的同时不会阻塞scroll亦或touch。