写在前面
前端性能优化是一门很深的学问,作为前端工程师往往会为了优化项目加载的几十毫秒而绞尽脑汁,当然这也是前端面试常问的问题,今天就结合我所学的简单分享给大家,顺便也是对知识的一次总结。
性能优化
性能优化主要从三个方面解析:
- 提高外部css的加载速度
- 减少重绘重排
- 浏览器缓存
提高css的加载速度
-
使用CDN节点进行外部资源加速
cdn是一组分布在多个不同地理位置的web服务器,用于更高效的向用户发布内容
cdn能够去协调各用户之间访问的效率,以最快、最佳的速度给予用户数据响应
对css进行压缩(利用webpage、gulp等)
-
减少http请求数;例如:将多个css文件合并、图片合成雪碧图(Css Sprites)
将多张图片合并到一张图片中,可以减小图片的总大小。
将多张图片合并成一张图片后,下载全部所需的资源,只需一次请求。可以减小建立连接的消耗。
- 优化样式表代码(尽可能精简有效,去除无用css;把统一修改得样式放在一起执行等)
减少重绘和重排
重绘和重排都是以css图层为单位的,所以本质上是对图层在进行优化
- 元素位置的改变尽量使用css3的transform来代替top、left等操作,因为变换(transform)和透明度(opacity)的改变只会影响图层的组合不会触发重排重绘
- 用opacity代替visibility去实现元素的隐藏(opacity搭配图层不会触发重绘和重排)
- 将多次改变样式的操作合并成一次,例如写成类然后只修改DOM的类
- 将DOM元素离线后进行修改,也就是display:none===>有复杂操作时候可以先将那部分隐藏,让它脱离DOM树然后修改完成后,再显示渲染DOM树
- 利用文档碎片(DocumentFragment)实现性能优化(vue采用的优化方案)
- 在编写动画的时候,建议采用requestAnimationFrame实现
题外话:触发重绘重排的操作
重绘:当render tree中的一些元素需要更新属性,而这些属性只是影响元素的外观,风格,而不会影响布局的。-比如visibility、outline、背景色等属性的改变。
重排/回流:页面第一次渲染 在页面发生首次渲染的时候,所有组件都要进行首次布局,这是开销最大的一次回流。比如
浏览器窗口尺寸改变
元素位置和尺寸发生改变的时候
新增和删除可见元素
内容发生改变(文字数量或图片大小等等)
元素字体大小变化。
激活CSS伪类(例如::hover)。
设置style属性
查询某些属性或调用某些方法。比如说:
offsetTop、offsetLeft、 offsetWidth、offsetHeight、scrollTop、scrollLeft、scrollWidth、scrollHeight、clientTop、clientLeft、clientWidth、clientHeight
除此之外,当我们调用getComputedStyle方法,或者IE里的currentStyle时,也会触发回流,原理是一样的,都为求一个“即时性”和“准确性”
浏览器缓存
直接从浏览器缓存里取数据也是性能优化的方案之一;但是也并不是所有的页面数据都放在浏览器缓存中,这种方式只适合于一些简单但经常会被访问的页面中,比如百度的首页,访问量巨大而且用户访问的次数也非常多,读取的时候让浏览器直接在缓存中取数据渲染页面是一种非常快速的方式
定义:浏览器在本地磁盘上将用户之前请求的数据存储起来,当访问者再次访问不需要再从服务器取数据,但是第一次还是需要的!
-
缓存的好处:
- 减少请求个数
- 节省带宽、避免浪费不必要的资源
- 减轻服务器压力
- 提高浏览器网页加载速度
-
缓存的分类:
- 强缓存:(存在过期时间,会失效)
- 不会向服务器发请求,直接从本地取数据
- 请求资源的转态码为200
- 协商缓存
- 向服务器发请求,服务器会根据请求头的资源判断是否命中协商缓存
- 如果命中,返回304状态码告知浏览器读取缓存,如果没有命中则说明页面过期返回最新的页面数据
- 二者的共同点:都是从浏览器端读取资源
- 二者的不同点:
- 强缓存不发给服务器
- 协商缓存会发给服务期根据服务器返回的信息决定是否缓存
- 强缓存:(存在过期时间,会失效)
-
缓存中的header参数:
- expires:http1.0规范;为一个绝对时间GMT格式;指的是有效期,表明强缓存的有效时间
- cache-control:http1.1规范;为一个资源过期剩余时间:max-age=number
补充:
可用于优化 CSS 图片加载的技术有:
- Css Sprite
- Base 64
- IconFont
- SVG Sprite
页面渲染图示:
前端优化是一门很复杂的学问,我也是简单学了些,在此分享给大家,欢迎补充~