笔记

作者: 条条大道通罗马 | 来源:发表于2018-11-20 16:29 被阅读0次

    css will-change

    will-change属性可以提前通知浏览器我们要对元素做什么动画,这样浏览器可以提前准备合适的优化设置。这样可以避免对页面响应速度有重要影响的昂贵成本。元素可以更快的被改变,渲染的也更快,这样页面可以快速更新,表现的更加流畅。

    举个例子,当对于素使用 CSS 3D变形时,元素及其内容可以在合成到页面之前被创建到我们之前说的layer。然而把元素放到layer中是个昂贵的操作,这将会导致变形动画延迟一个课件的瞬间,也就是flicker

    为了避免这种延时,我们可以在发生之前通知浏览器,这样浏览器会有一定的时间去准备这些变化,当发生的时候layer已经准备好了,这样动画酒会很流畅,不会闪屏

    使用will-change提示浏览器关于即将发生的变形十分简单,添加个CSS属性就行

    will-change: transform;
    也可以告诉浏览器要改变元素的滚动条位置,或者多个要变化的属性,写下属性的名字就行,也可以写多个,逗号隔开

    will-change: transform, opacity;
    声明了元素即将进行的变化会让浏览器在渲染页面时做更好的决定,这明显比之前说的3D hacks要好。

    参考链接

    Load 和 DOMContentLoaded 区别

    Load 事件触发代表页面中的 DOM,CSS,JS,图片已经全部加载完毕。

    DOMContentLoaded 事件触发代表初始的 HTML 被完全加载和解析,不需要等待 CSS,JS,图片加载。

    Node 中的 Event loop

    防抖

    节流

    重绘(Repaint)和回流(Reflow)

    重绘和回流是渲染步骤中的一小节,但是这两个步骤对于性能影响很大。

    • 重绘是当节点需要更改外观而不会影响布局的,比如改变 color 就叫称为重绘
    • 回流是布局或者几何属性需要改变就称为回流。

    回流必定会发生重绘,重绘不一定会引发回流。回流所需的成本比重绘高的多,改变深层次的节点很可能导致父节点的一系列回流。

    所以以下几个动作可能会导致性能问题:

    • 改变 window 大小
    • 改变字体
    • 添加或删除样式
    • 文字改变
    • 定位或者浮动
    • 盒模型

    很多人不知道的是,重绘和回流其实和 Event loop 有关。

    1. 当 Event loop 执行完 Microtasks 后,会判断 document 是否需要更新。因为浏览器是 60Hz 的刷新率,每 16ms 才会更新一次。
    2. 然后判断是否有 resize 或者 scroll ,有的话会去触发事件,所以 resizescroll 事件也是至少 16ms 才会触发一次,并且自带节流功能。
    3. 判断是否触发了 media query
    4. 更新动画并且发送事件
    5. 判断是否有全屏操作事件
    6. 执行 requestAnimationFrame 回调
    7. 执行 IntersectionObserver 回调,该方法用于判断元素是否可见,可以用于懒加载上,但是兼容性不好
    8. 更新界面
    9. 以上就是一帧中可能会做的事情。如果在一帧中有空闲时间,就会去执行 requestIdleCallback 回调。

    以上内容来自于 HTML 文档

    减少重绘和回流

    使用 translate 替代 top

    <div class="test"></div>
    <style>
        .test {
            position: absolute;
            top: 10px;
            width: 100px;
            height: 100px;
            background: red;
        }
    </style>
    <script>
        setTimeout(() => {
            // 引起回流
            document.querySelector('.test').style.top = '100px'
        }, 1000)
    </script>
    

    使用 visibility 替换 display: none ,因为前者只会引起重绘,后者会引发回流(改变了布局)

    把 DOM 离线后修改,比如:先把 DOM 给 display:none (有一次 Reflow),然后你修改100次,然后再把它显示出来

    不要把 DOM 结点的属性值放在一个循环里当成循环里的变量

    for(let i = 0; i < 1000; i++) {
        // 获取 offsetTop 会导致回流,因为需要去获取正确的值
        console.log(document.querySelector('.test').style.offsetTop)
    }
    

    不要使用 table 布局,可能很小的一个小改动会造成整个 table 的重新布局

    动画实现的速度的选择,动画速度越快,回流次数越多,也可以选择使用 requestAnimationFrame

    CSS 选择符从右往左匹配查找,避免 DOM 深度过深

    将频繁运行的动画变为图层,图层能够阻止该节点回流影响别的元素。比如对于 video 标签,浏览器会自动将该节点变为图层。

    相关文章

      网友评论

          本文标题:笔记

          本文链接:https://www.haomeiwen.com/subject/wtexqqtx.html