What tools would you use to find a performance bug in your code?
chrome
What are some ways you may improve your website’s scrolling performance?
在绑定了 scroll 事件后,chrome 不知道事件会不会阻止滚动,所以会有 100ms 但延迟来判断是否会调用 preventDefault,然后再滚动,所以 chrome 提供了 passive 来忽略事件中带 prevenDefault
scroll 被频繁触发,减少 handler 执行评论
requestAnimationFrame // 按照 1 /60 秒的速度触发 debounce // 多次触发合成一个 1 个 throttle // 执行一个后,一段时间不被触发 1. 兼容性不好。不灵活,动画流程 2. 精度搞 2.3 使用 settimeout 精度不高
Explain the difference between layout, painting and compositing.
JavaScript:一般来说,我们会使用 JavaScript 来实现一些视觉变化的效果。比如做一个动画或者往页面里添加一些 DOM 元素等。
Style:计算样式,这个过程是根据 CSS 选择器,对每个 DOM 元素匹配对应的 CSS 样式。这一步结束之后,就确定了每个 DOM 元素上该应用什么 CSS 样式规则。
Layout:布局,上一步确定了每个 DOM 元素的样式规则,这一步就是具体计算每个 DOM 元素最终在屏幕上显示的大小和位置。web 页面中元素的布局是相对的,因此一个元素的布局发生变化,会联动地引发其他元素的布局发生变化。比如,<body> 元素的宽度的变化会影响其子元素的宽度,其子元素宽度的变化也会继续对其孙子元素产生影响。因此对于浏览器来说,布局过程是经常发生的。
Paint:绘制,本质上就是填充像素的过程。包括绘制文字、颜色、图像、边框和阴影等,也就是一个 DOM 元素所有的可视效果。一般来说,这个绘制过程是在多个层上完成的。
Composite:渲染层合并,由上一步可知,对页面中 DOM 元素的绘制是在多个层上进行的。在每个层上完成绘制过程之后,浏览器会将所有层按照合理的顺序合并成一个图层,然后显示在屏幕上。对于有位置重叠的元素的页面,这个过程尤其重要,因为一旦图层的合并顺序出错,将会导致元素显示异常。
如果改变了 layout 属性,也就是改变了元素的几何属性,高宽,位置就会自动重排
如果只改变了 paint only 例如背景 文字颜色,则不会影响布局,浏览器会跳过布局
如果改变既不要布局也不要绘制的属性,则浏览器会跳过绘制, 例如动画和滚动
优化 js 执行
使用 requestAnimationFrame 来实现视觉变化
使用 web worker 来执行长时间的任务
使用微任务来执行多个桢的 dom 更改
使用 chrome profile 来评估性能
缩小样式计算范围
降低选择器的复杂性,使用以类为中心的方法,例如 BEM,减少伪类选择器 例如 nth
减少必须计算样式的元素数量(例如在改变了 body 元素的类,所有子元素都要重新计算样式)
避免大型,复杂的布局和布局抖动
使用 flex 布局模型,新的 flex 比旧的 flex 和浮动更快
避免布局操作,例如改变元素几何属性
避免强制同步布局,先读取样式值,然后进行样式更改
避免布局抖动,多次强制布局同步
简化绘制的复杂度,减小绘制区域
除了 transform 和 opacity, 其他属性更改都会触发绘制
绘制通常时像素管道中开最大的
通过层的提上和动画的编排来减少绘制区域
通过创建新层,将定期重绘的元素放在新层上,避免其他层的绘制
will-change 属性,或者 transform: translateZ(0)
降低绘制复杂度,涉及模糊阴影比红框时间更长
减少层数量,使用合成层属性
坚持使用 transform 和 opacity 属性更改来实现动画。
使用 will-change 或 translateZ 提升移动的元素。
避免过度使用提升规则;各层都需要内存和管理开销。
使用 debounce,去除抖动
requestAnimationFrame 或者 debounce 优化滚动程序