浏览器渲染优化
优化 script 脚本
优化 script 脚本的加载。script 脚本会阻塞 HTML 的解析。
- 将 script 标签放到
body
最后面 - 尽量使用异步加载
JS
资源,这样不会阻塞DOM
解析,如 defer、async。
避免回流重绘
css:
- 复杂动画使用定位脱离普通文档流
- 使用 transform 替代动画。
- 避免使用 CSS 表达式(例如:calc())。
js:
- 避免频繁操作样式,最好将样式列表定义为 class 并一次性更改 class 属性。
- 避免频繁操作 DOM,创建一个 documentFragment ,在它上面处理所有 DOM 操作,最后再把它添加到文档中。
- 可以先为元素设置为 display: none,操作结束后再把它显示出来。
- 避免使用 getComputedStyle,会引起回流。
display: none; 元素不会出现在 render 树,但是 dom 树上还是存在的,否则无法响应事件。
Vue 性能优化
v-if
和v-for
不一起使用v-for
保证key
的唯一性v-if
和v-show
酌情使用- 使用
keep-alive
缓存组件 - 合理使用
watch
和computed
。 - 路由懒加载
- 图片懒加载
- 异步组件
- 第三方模块按需引入,不要全部引入,减小打包体积。
- 组件卸载前及时解绑全局事件、清除定时器、以及销毁插件实例。
- 合理使用组件。
- 避免使用
v-html
,存在安全风险和性能问题,可以使用v-text
JS 性能优化
- 避免使用
with
语句、eval
函数。with
可以简化对象的书写,。eval
性能不好,运行速度慢,容易被攻击。 - 尽量使用原生方法,执行效率高。
- 使用事件委托,减少事件绑定次数。
- 节流防抖
网络优化
- 使用
HTTP/2.0
- 减少
HTTP
请求,使用精灵图减少请求数量。 - 使用
HTTP
缓存,如强缓存、协商缓存
Webpack 优化
- 代码切割,使用
code splitting
将代码进行分割,避免将所有代码打包到一个文件,减少体积。 - 按需加载代码,在使用的时候加载代码。
- 压缩代码体积,可以减小代码体积
- 使用
Tree Shaking
删除未被引用的代码 - 开启
gzip
压缩
图片懒加载
只有当屏幕滚动到可视区域内才加载。
特点:
- 提高网页加载速度
- 减少后台服务器压力
- 提升用户体验
原理:
- 将图片地址存储到 img 标签的
data-xxx
属性上 - 判断图片是否在可视区域
Element.getBoundingClientRect()
- 如果在,就设置图片
src
- 绑定
scroll
监听事件
节流
函数在 n 秒内只执行一次,如果多次触发,则忽略执行。
应用场景:
- 拖拽场景
- scroll场景
- 窗口大小调整
防抖
函数在 n 秒后再执行,如果 n 秒内被触发,重新计时,保证最后一次触发事件 n 秒后才执行。
应用场景:
- 输入框搜索
- 表单提交按钮
- 文本编辑器 快捷键 保存 功能
SPA
首屏加载慢可能有以下原因:
- JavaScript文件过大:SPA 通常有很多 JavaScript 文件,如果这些文件的大小过大或加载速度慢或执行时间长,就会导致首屏加载缓慢。可以通过代码分割和按需加载的方式优化。
- 数据请求过多或数据请求太慢:SPA通过 AJAX 或 Fetch 等方式从后端获取数据,如果数据请求过多或数据请求太慢,也会导致首屏加载缓慢。可以通过减少数据请求、使用数据缓存、优化数据接口等方式来优化数据请求速度。
- 大量图片加载慢:如果首屏需要加载大量图片,而这些图片大小过大或加载速度慢,也会导致首屏加载缓慢。可以通过图片压缩、使用图片懒加载等方式来优化图片加载速度。
- 过多的回流和重绘操作:如果在首屏加载时进行大量的回流和重绘操作,也会导致首屏加载缓慢。可以通过尽可能少的DOM操作、使用CSS3动画代替JS动画等方式来优化回流和重绘操作。
- 网络问题:网络问题也会影响SPA首屏加载速度,比如网络延迟、丢包等。可以通过使用 CDN、使用HTTP/2等方式来优化网络问题。
为什么要做性能优化
- 提高用户体验
- 增加页面访问量
- 提高搜索引擎排名
- 减少服务器压力
- 节约成本
- 提高用户留存率
一个列表如果有 100000 条数据,怎么办?
我们需要思考的问题:该处理是否必须同步完成?数据是否必须按顺序完成?
解决办法:
(1)将数据分页,利用分页的原理,每次服务器端只返回一定数目的数据,浏览器每次只对一部分进行加载。
(2)使用懒加载的方法,每次加载一部分数据,其余数据当需要使用时再去加载。
(3)使用数组分块技术,基本思路是为要处理的项目创建一个队列,然后设置定时器每过一段时间取出一部分数据,然后再
使用定时器取出下一个要处理的项目进行处理,接着再设置另一个定时器。