性能优化面试题

2023-11-18

1.★★★ 当修改一个数据时,不想整个页面都被重新渲染,只想要渲染变更数据的那一部分,怎么做?

  • 选择合适的框架,vue和react都使用了虚拟dom加diff运行,找出最小化的差异并更新到真实dom中,只会改变发生变化的dom,不会渲染整个页面。并为列表中每一个节点添加唯一的key值,提高diff运算的速度。

  • 让数据变为响应式的,如:vue中,当页面初始化时候,vue会遍历data对象所有的属性,并使用defineProperty或Proxy把这些属性全部转化为getter/setter,所以属性必须在 data 对象上存在才能让 Vue 转换它,这样才能让它是响应的。

  • vue计算属性是基于它们的响应式依赖进行缓存的。只在相关响应式依赖发生改变时它们才会重新求值。

  • Vue 不允许在已经创建的实例上动态添加新的根级响应式属性,可以使用 Vue.set(object, key, value) 方法将响应属性添加到嵌套的对象上,也可以使用 this.$forceUpdate() 方法,可以局部更新。迫使Vue实例重新渲染。它仅仅影响实例本身和插入插槽的子组件,而不是所有字组件

2.★★★ 页面是否可以快速加载

  • 图片资源的预加载,懒加载,cdn加速,雪碧图/精灵图

  • 减少HTTP请求,尽可能的合并脚本,CSS,图像,在用户的浏览器上缓存文件

  • 压缩JS文件,图片,HTML文档,CSS文档等等。用户可以下载较小的文件,增加网页的加载速度,这样可以降低服务器的消耗

  • 去除不必要的空格, 注释 减少文件的总尺寸,较小的页面可以获得更快的加载速度

  • 把CSS放在顶端: css文件的加载不会阻塞dom树的解析,把CSS文件放在网站的顶端,可以让网站尽可能同时加载其他部件,如图片和文字。

  • 把js放在底端: 在body闭合标签前插入js脚本,让这些脚本在后台加载的同时,用户先得到看似完整的页面。

  • async异步 或 defer 推迟 加载js脚本

  • 避免使用CSS表达式,如:calc

  • 避免重定向:无论是服务器端头重定向,js重定向,或者HTML元素重定向。你的网站都会加载空白的页面的头, 然后再加载新的一页,用户为了获得需要的页面花费越来越多的时间

  • 使用Web Worker为 JavaScript 创造多线程环境,允许主线程创建 Worker 线程,将一些任务分配给Worker 线程运行。

3.★★★ 是否允许用户快速开始与之交互

  • 会引起回流的css属性:width、height、min-height、border、border-width、padding、margin、display、position、left、right、top、bottom、float、clear、font-size、font-weight、font-family、line-height、text-align、overflow、overflow-y、white-space、vertical-align 减少以上属性的使用或用其他属性代替,如:使用 visibility 替换 display: none ,因为前者只会引起重绘,后者会引发回流
  • 避免使用table布局,table中的单元格的宽度取决于最长的单元格,可能会引起多次回流。
  • 避免标签的过多嵌套,CSS 选择符从右往左匹配查找,避免节点层级过多。
  • 避免使用CSS表达式,动态的计算,可能会引起多次的回流
  • 将频繁重绘或者回流的节点设置为图层,图层能够阻止该节点的渲染行为影响别的节点,例如will-change、video、iframe等标签,浏览器会自动将该节点变为图层。
  • 将动画效果应用到position属性为absolute或fixed的元素上,避免影响其他元素的布局,这样只是一个重绘,而不是回流,同时,控制动画速度可以选择 requestAnimationFrame
  • 避免频繁操作样式,最好一次性重写style属性,或者将样式列表定义为class并一次性更改class属性。
  • 避免频繁操作DOM,创建一个documentFragment,在它上面应用所有DOM操作,最后再把它添加到文档中。
  • 避免频繁读取会引发回流/重绘的属性,如果确实需要多次使用,就用一个变量缓存起来。
  • 对具有复杂动画的元素使用绝对定位,使它脱离文档流,否则会引起父元素及后续元素频繁回流。

4.★★★ 怎么让滚动和动画流畅

  • 前提:滚动和动画会频繁的引起回流与重绘,操作卡顿问题
  • 防抖(debounce)与 节流(throttle)都是为了限制函数的执行频次,以优化函数触发频率过高导致的响应速度跟不上触发频率,出现延迟,假死或卡顿的现象。
  • window.requestAnimationFrame() 这个方法是用来在页面重绘之前,通知浏览器调用一个指定的函数,用于准确控制页面的帧刷新渲染,让动画效果更加流畅。频率是每秒 60 次,也就是 1000/60 ,触发频率大概是 16.7ms 。(当执行复杂操作时,当它发现无法维持 60fps 的频率时,它会把频率降低到 30fps 来保持帧数的稳定。)
  • 避免在scroll 事件中修改样式属性或将样式操作从 scroll 事件中剥离,因为如果你在 scroll 事件的处理函数中做了修改样式属性的操作,那么这些操作会被浏览器暂存起来。然后在调用 requestAnimationFrame 的时候,如果你在一开始做了读取样式属性的操作,那么这将会导致触发浏览器的强制同步布局。
  • 滑动过程中尝试使用 pointer-events: none 禁止鼠标事件,可用来提高滚动时的帧频。当滚动时,鼠标悬停在某些元素上,则触发其上的 hover 效果,多半导致滚动出现问题。

5.★★★ 怎么图片优化

  • 使用base64编码代替图片:适用于图片小于2KB,页面引用图片不多的情况。将图片转换为base64编码字符串inline到CSS或页面中,减少http的请求次数。
  • 合并图片sprite(雪碧图):任何用到页面图片的场景。将多个页面用到的背景图片合并成一个大的图片在页面中引用,可以有效地减少请求个数。
  • 使用canvas代替图片:需要高性能的图片或动画,使用HTML5的canvas元素绘制图片,页面渲染性能较高。
  • 响应式图片:不同终端对同一图片的需求不一样,根据终端加载不同的图片来节省不必要的流量。通过picture元素,picturefill或平台判断来为不同终端平台输出不同的图片。减少没必要的图片加载,灵活控制。
  • 图片压缩:在不得不加载图片的前提下,进一步提高优化效果,通过有损或无损压缩所见图片的大小。减少图片加载流量,效果明显。
  • 更好的图片格式:webp、bpg、sharpP等新图片格式具有更好的压缩比
  • 字体图库代替图标:使用字体图库你不仅可以改变大小,而且还可以改变颜色。
  • 图片懒加载:在页面图片非常多的情况下,可以使用懒加载。只加载第一屏的图片,当用户通过滚动访问后面的内容时再加载相应图片。
  • 按照HTTP协议设置合理的缓存:具体的缓存策略(如永久缓存+重命名)
  • 利用CDN加速

6.★★★ 骨架屏+合理的loading

  • 骨架屏 Skeleton Screen Loading 也叫加载占位图,是近年流行的加载控件,通常表现形式是在界面上待加载区域填充灰色的占位图,与线框图的效果非常相似。Skeleton Screen本质上是界面加载过程中的过渡效果。
  • loading 在一定程度上限制了用户的操作,而骨架屏不干扰用户的操作,弱网络环境下极大的优化了用户体验。
  • 异步加载样式表防止阻塞骨架屏的渲染
  • 当前端渲染内容替换掉骨架屏内容时,必须保证此时样式表已经加载完毕,否则真正有意义的页面内容将出现 FOUC。所以必须要保证 Vue 实例在异步样式表加载完毕后进行挂载,如果此时样式还没有完成,把挂载方法放到全局,等到样式加载完成后再调用。

7.★★★ 长列表懒加载思路与性能优化

  • 将需要渲染的内容限制在的给定固定容器中,给容器一个固定的高度与高度overflow:auto ,然后数据将在这个容器显示,只需要渲染视口容器中适合的数量节点
  • 为了避免用户快速的滚动,导致频繁的渲染行,可以使用requestAnimationFrame来实现对渲染速率的控制,从而平滑的滚动
  • 对节点进行缓存,在滚动时遇到缓存中节点时,可直接使用。
  • 有时候数据操作会导致列表需要重新渲染,会导致全列表的重新渲染,所以需要做列表的回收,永远只保证可视区域的节点与上下预渲染的节点数量即可,超出这个范围的节点进行回收缓存。

8.★★★ 循环太多引起浏览器的卡顿如何处理

  • 使用其他的循环代替for-in、for-of循环:for-in需要同时遍历实例和原型链,在遍历上的消耗更多,for-of需要去调用Symbol.iterator函数来构建一个迭代器,自动调用next(),且不向next()传入任何值,在接收到done:true之后停止
  • 减少每次循环工作量,获取并存储数组的长度。在查找该值时在作用域链上查找的步数就会减少,所以能有效地减少性能的消耗
  • 倒序循环,合并i和数组长度的比较和判断为true或false,以此来得到性能上的优化
  • 减少循环次数:达夫设备实际上就是在一次循环中完成多次循环的事情,以达到减少循环次数的作用
  • 基于函数的迭代,JavaScript本身封装了数组迭代方法,如:forEach、map、filter、some等。
  • 使用Web Worker创造多线程环境,主线程创建 Worker 线程,将循环任务分配给Worker线程运行,防止主线程的卡顿,影响程序的执行。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

性能优化面试题 的相关文章

随机推荐

  • python初学者学习第1天

    python环境安装 要想学习 门新的编程语 少不了安装各种各样的软件和配置各种各样的环境 为此 给学习python的同学准备了 份环境安装指南 一 python安装包下载 需要从python官网 https www python org
  • 认识MSCI ESG评级

    认识MSCI ESG评级 成为ESG领导者 ESG特辑 商道纵横 ESG 环境 社会和公司治理 简称ESG 投资理念逐渐成为国际资本市场中的主流投资策略 对于投资者而言 要充分掌握企业的ESG表现 评估企业的环境社会贡献 需要具有公允力的E
  • RabbitMQ 登录控制台出现 “你与此网站的连接不是私密连接“

    解决方案 可能是创建容器时 密码没能成功设置进去 重新设置密码 先进入MQ容器中 我这里是用的docker 容器 docker exec it mq容器名 bash 查看用户 rabbitmqctl list users 修改密码 rabb
  • Python内置数据类型之List篇

    List的定义 li one two three four List是一个有序的集合 这点不同于Dictionary Dictionary是无序的 1 索引和切片 索引有正负之分 正索引下标从0开始 负索引下标从 1开始 比如 gt gt
  • 区块链和传统数据库有什么区别?

    都说区块链就是一种数据库 那区块链和传统数据库到底有什么区别呢 传统数据库拥有与其记录相关的授的客户机可以更改放在统一服务器上的部分 通过演进 ace副本 无论客户端在什么时候使用他们的PC访问数据库 他们都将获得数据库部分的更新适应 对数
  • python二维数组列表输出格式化:对齐数据(实例)

    学习python过程中遇到的问题 在这里记录一下 下面是二维列表 数组 格式化输出的实例 注意 t 有加后会自动对齐 a 学生学号 高等数学 高等物理 高等化学 程序语言 英文六级 个人平均成绩 201 t65 t58 t75 t80 t8
  • python保留小数位的三种方法

    python保留小数位的三种方法 保留小数位是我们经常会碰到的问题 尤其是刷题过程中 那么在python中保留小数位的方法也非常多 但是笔者的原则就是什么简单用什么 因此这里介绍几种比较简单实用的保留小数位的方法 方法一 format函数
  • PhpStorm64修改内存后不能启动

    审查phpstorm bat 这个bat文件应该是监控程序运行 并输出错误日志用的 在末尾加上pause查看完整的运行周期 JAVA EXE ALL JVM ARGS cp CLASS PATH com intellij idea Main
  • javac 命令 javac 命令大全详解---推荐看

    javac 命令 javac 命令大全详解 温柔一刀的技术博客 51CTO博客 1 javac 命令 用法 javac
  • Java--集合知识再补充(Map集合)

    下面就是我整理的部分学习笔记 学无止境 加油 为方便对多个对象的操作 就对对象进行存储 集合就是存储对对象最常用的一种方式 数组长度是固定的 且可以存储基本数据类型 集合可变 集合只能存储对象 Collection 下有两个子接口 为Lis
  • 权限验证-JWT认证

    JWT 1 什么是JWT JSON Web Token 通过数字签名的方式 以JSON对象为载体 在不同的服务终端之间安全的传输信息 2 JWT有什么用 JWT最常见的场景就是授权认证 一旦用户登录 后续每个请求都将包含JWT 系统在每次处
  • CentOS7 - systemd服务及开启关闭服务命令

    RHEL CentOS 7 0中一个最主要的改变 就是切换到了systemd 它用于替代红帽企业版Linux前任版本中的SysV和Upstart 对系统和服务进行管理 systemd兼容SysV和Linux标准组的启动脚本 Systemd是
  • oracle date 和 timestamp区别

    在今天的工作中 学到了以下几个知识点 一 date和timestamp 的区别 date类型是Oracle常用的日期型变量 他的时间间隔是秒 两个日期型相减得到是两个时间的间隔 注意单位是 天 例如 查看一下当前距离伦敦奥运会开幕还有多长时
  • c++ multiple definition of 问题解决方法

    问题描述 有一个 h头文件 两个 cpp文件都引用了这个 h文件 在 h文件中声明了一些全局变量或函数 编译时报错 multiple definition of 原因 好像是由于多次包含 然后编译 cpp文件是重复 定义了 解决方法 1 使
  • Linux 通过RPM包安装 MySQL 8.0

    Linux平台上推荐使用RPM包来安装Mysql MySQL 提供了以下RPM包的下载地址 MySQL MySQL服务器 你需要该选项 除非你只想连接运行在另一台机器上的MySQL服务器 MySQL client MySQL 客户端程序 用
  • 一、安卓笔记(1)—Android Studio下的的APP目录结构

    一 Android Studio工程目录 1 gradle文件夹包含的是gradle工具的各个版本 不需要手动去填写 自动生成的 Gradle是一个基于Apache Ant和Apache Maven概念的项目自动化构建开源工具 它使用一种基
  • C#开发Windows窗体应用程序的步骤

    使用C 开发应用程序时 一般包括创建项目 界面设计 设置属性 编写程序代码 保存项目 程序运行等6个步骤 1 创建项目 在Visual Studio2017开发环境中选择 文件 新建 项目 菜单 弹出 新建项目 对话框 如图8 1所示 图8
  • Linux环境下Ubuntu系统中下载gvim及相关配置

    分享一下Linux环境下gvim的下载以及自己的相关配置 也方便自己以后重新进行虚拟机的相关配置时进行参考 相关代码带有简略注释 Ubuntu版本18 04 6 首先是下载 命令窗口打开位置无所谓 在命令行中输入以下代码 sudo apt
  • Qt信号槽-原理分析

    转载一篇关于Qt信号槽原理解析的文章 讲解的很详细 有的地方可能有点深度 不过还是能很大程度上的帮助理解信号槽原理 一 问题 moc预编译在干嘛 signals和slots关键字产生的理由 信号槽连接方式有什么区别 信号和槽函数有什么区别
  • 性能优化面试题

    目录 1 当修改一个数据时 不想整个页面都被重新渲染 只想要渲染变更数据的那一部分 怎么做 2 页面是否可以快速加载 3 是否允许用户快速开始与之交互 4 怎么让滚动和动画流畅 5 怎么图片优化 6 骨架屏 合理的loading 7 长列表