• 前端面试题之性能优化篇


    懒加载

    图片懒加载

    懒加载的概念

    懒加载也叫延迟加载,按需加载,指在长网页中延时加载图片数据,是一种比较好的网页性能优化的方式。在比较长的网页或应用中,如果图片加载很多,所有图片都加载出来,而用户只能看到可是窗口的那一部分图片,这样就浪费性能。

    懒加载的特点

    • 减少无用资源的加载:使用懒加载明显减少服务器的压力和流量,同时减少浏览器的负担
    • 提升用户体验:如果同时加载较多图片,可能需要等待的时间较长,这样影响了用户体验
    • 防止加载过多的图片而影响其他资源文件的加载

    懒加载实现原理

    图片的加载是由src引起的,当对src赋值时,浏览器会请求图片资源,根据这个原理,我们使用HTML5 的data-xxx属性来存储图片路径,在需要加载图片的时候,会将data-xxx中的图片路径赋值给src,这样就实现了图片的按需加载,即懒加载

    回流和重绘

    回流和重绘的概念和触发条件

    (1)回流(也叫重排)
    当渲染树中部分或者全部元素的尺寸,结构或者属性发生变化时,浏览器会重新渲染部分或者全部文档过程称为回流

    下面这些操作会导致回流:

    • 页面的首次渲染
    • 浏览器的窗口大小发生变化
    • 元素的内容发生变化
    • 元素的尺寸或者位置发生变化
    • 元素的字体大小发生变化
    • 激活css伪类
    • 查询某些属性或者调用某些方法
    • 添加或者删除可见DOM元素

    在触发回流(重排)的时候,由于浏览器渲染页面是基于流式布局的,所以当触发回流时会导致周围的DOM元素重新排列,它的影响范围有两种:

    • 全局范围:从根节点开始,对整个渲染树进行重新布局
    • 局部范围:对渲染树的某部位或者一个渲染对象进行重新布局

    (2)重绘
    当页面中某个元素的样式发生变化,但是不会影响其在文档流中的位置时,浏览器会对元素进行重新绘制,这个过程就叫重绘

    下面的操作会导致重绘

    • color、background相关属性:background-color、background-image等
    • outline相关属性:outline-color、outline-width、text-decoration
    • border-radius、visibility、box-shadow

    注意:当触发回流时,一定会触发重绘,但是重绘不一定引发回流

    如何减少回流和重绘

    • 操作DOM时,尽量在低层级的DOM节点进行操作
    • 不要使用table布局,一个小的改动可能会使整个table进行重新布局
    • 不要频繁的操作元素的样式,对于静态页面,可以修改类名,而不是样式
    • 使用absolute或者fixed,使文档脱离文档流,这样它们发生改变就不会影响其他元素
    • 避免频繁的操作DOM,可以创建一个文档片段documentFragment,在它上面应用所有DOM操作,最后把它添加到文档中

    防抖和节流

    对防抖和节流的理解

    • 函数防抖是指在事件被触发n秒后在执行回调,如果在这n秒内事件又被触发则重新计算,这可以使用在一些点击请求的事件上,避免因为用户多次点击后向后端发送多次请求
    • 函数节流是指在规定的时间内,只能触发一次回调函数,如果在同一单位时间内某件事被触发多次,只能一次生效。节流可以使用在scroll函数的事件监听上,通过事件节流来降低事件调用的频率

    防抖函数的应用场景

    • 按钮提交的场景:防止多次提交按钮,只执行最后提交的一次
    • 服务端验证场景:表单验证需要服务端配合,只执行一段连续的输入事件的最后一次,类似于搜索联想词功能

    节流函数的应用场景

    • 拖拽场景:固定时间内只执行一次,防止超高频的触发位置变动
    • 缩放场景:监控浏览器的resize
    • 动画场景:避免短时间内多次触发动画引起性能问题

    实现防抖和节流函数

    防抖函数的实现

    function debounce(fn, wait) {
        // 首先定义一个定时器
        let timer = null;
    
        // 返回一个函数
        // 使用闭包能保存变量的值
        return function () {
            // 获取参数
            const args = arguments
    
            console.log(timer)
    
            // 如果再次触发,先判断定时器状态
            timer && clearTimeout(timer)
    
            // 定时器
            timer = setTimeout(() => {
                // this 表示调用debounce()的对象
                fn.apply(this, args)
                timer = null
            }, wait)
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    使用方法一

    document.getElementById("click").addEventListener("click", debounce(callback, 1000))
    
    • 1

    使用方法二

            const debounceFn = debounce(callback, 1000)
            document.getElementById("click").addEventListener("click", function(e) {
                debounceFn(e)
            })
    
    • 1
    • 2
    • 3
    • 4

    注意: 不能把 debounce防抖函数放在 监听事件的回调函数里面 否则每次会生成多个防抖函数,不能实现防抖功能

    // 注意:这是错误的调用
            document.getElementById("click").addEventListener("click", function(e) {
                debounce(callback, 1000)(e)
            })
    
    • 1
    • 2
    • 3
    • 4

    节流函数的实现

    function throttle(fn, wait) {
        // 获取当前时间戳
        let currentTime = Date.now()
    
        // 使用闭包
        return function () {
            // 获取参数
            const args = arguments
    
            // 获取调用时的时间戳
            let nowTime = Date.now()
    
            // 判断条件
            if(nowTime - currentTime >= wait) {
                // 执行回调函数
                fn.apply(this, args)
                currentTime = Date.now()
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    使用方法

    window.addEventListener('resize', throttle(resize, 1000))
    
    • 1
  • 相关阅读:
    【回眸】HighTec编译文件烧录及串口调试
    【iOS安全】提取app对应的URLScheme
    华为OD机考算法题:分班
    电脑图片无损放大怎么操作?怎么无损放大图片?
    计算机毕业设计 基于微信小程序的“共享书角”图书借还管理系统的设计与实现 Java实战项目 附源码+文档+视频讲解
    day 32 文件上传&二次渲染&.htaccess&变异免杀
    pytorch-实现猴痘识别
    即时零售业态下如何实现自动做账?
    【NestJS系列】核心概念:Module模块
    拼多多不满“国内市场”,将于9月中旬在美国推出跨境电商平台
  • 原文地址:https://blog.csdn.net/qq_43706089/article/details/134357572