Closed LiuL0703 closed 4 years ago
处理用户输入也是潜在的可能会影响性能的因素,因为其可能会阻塞其他内容的加载并且导致不必要的布局(layout)工作
TL;DR
页面交互最快的情况是,当用户与页面交互时,页面的合成器线程接受用户的触摸输入并将内容四处移动。这个过程不需要与主线程通信,而是直接提交给GPU处理。所以不需要等待主线程对JS的处理、以及布局(layout)、绘制(paint)等操作完成。
但是,如果附加了输入处理程序(如touchstart,touchmove,或者touchend)后,合成器线程必须等待该处理程序执行完毕,因为有可能调用了preventDefault()来阻止触摸滚动事件的发生。即使没有调用preventDefault(),合成器也必须等待其执行完毕,这样用户的滚动操作就被阻止就可能导致帧丢失从而引起卡顿。
总而言之,你应该确保运行的所有输入处理程序都快速执行,并允许合成器执行其工作。
输入处理程序被安排在requestAnimtionFrame回调之前运行。如果在这个处理程序中做样式上的修改,那么在requestAnimationFrame开始处有需要更改的样式处理,这会触发强制同步布局。
上面两个问题的解决方案是相同的:你应该对下一个requestAnimationFrame的回调中做样式更改的情况做防抖处理。
function onScroll(evt){ lastScrollY = window.scrollY; if(scheduleAnimationFrame) retun; scheduleAnimationFrame = true; requestAnimationFrame(readAndUpdatePage); } window.addEventListener('scroll',onScroll);
这样做还有一个好处,就是保持输入处理程序的轻量,因为这样就不会阻塞比如滚动等其他操作。
对输入处理程序做防抖
处理用户输入也是潜在的可能会影响性能的因素,因为其可能会阻塞其他内容的加载并且导致不必要的布局(layout)工作
TL;DR
避免运行时间过长的处理程序
页面交互最快的情况是,当用户与页面交互时,页面的合成器线程接受用户的触摸输入并将内容四处移动。这个过程不需要与主线程通信,而是直接提交给GPU处理。所以不需要等待主线程对JS的处理、以及布局(layout)、绘制(paint)等操作完成。
但是,如果附加了输入处理程序(如touchstart,touchmove,或者touchend)后,合成器线程必须等待该处理程序执行完毕,因为有可能调用了preventDefault()来阻止触摸滚动事件的发生。即使没有调用preventDefault(),合成器也必须等待其执行完毕,这样用户的滚动操作就被阻止就可能导致帧丢失从而引起卡顿。
总而言之,你应该确保运行的所有输入处理程序都快速执行,并允许合成器执行其工作。
避免在输入处理程序中改变样式
输入处理程序被安排在requestAnimtionFrame回调之前运行。如果在这个处理程序中做样式上的修改,那么在requestAnimationFrame开始处有需要更改的样式处理,这会触发强制同步布局。
输入处理程序做防抖
上面两个问题的解决方案是相同的:你应该对下一个requestAnimationFrame的回调中做样式更改的情况做防抖处理。
这样做还有一个好处,就是保持输入处理程序的轻量,因为这样就不会阻塞比如滚动等其他操作。