一、提升网站性能:前端性能优化就是让网站打开速度更开,提升用户体验。
1、页面级别的优化
①减少HTTP的请求
原因:用于HTTP请求是无状态的,所以每次请求都需要重新建立连接,这是一个复杂的过程,既消耗时间成本又消耗资源。时间成本是用户需要等待所需要的;资源成本就是由于每一个请求都需要携带数据,所以需要占用带宽;同一时间请求数超过浏览器的上限后,浏览器就会分批进行,用户的等待时间就会增加。
方法:那么如何减少HTTP请求呢?
* 设置HTTP缓存:将一些常用的资源在第一次加载时缓存到本地,再次加载就会减少HTTP的请求
* 资源合并压缩:CSS、JS代码等都可以用响应的工具进行压缩
* 雪碧图:合并CSS图片可以减少HTTP的请求
* 懒加载:在某些条件下或者页面刚加载时会减少HTTP的请求
②资源加载的位置优化
** 将CSS代码放到head中:让浏览器尽快加载CSS,由于页面渲染是在CSS代码全部下载之后进行的,例如将CSS放到body中时可能在CSS还没有完全下载时页面就进行渲染,这样会使页面从无CSS到有CSS的过程,用户体验较差。
** 将JS代码放到页面的最底部,body之前。因为JS代码是立即执行的,有可能会阻塞页面造成页面加载缓慢,因此javascript最好放在页面最下面。但如果页面解析时就需要用到javascript,这时放到底部就不合适了
** 处理页面的JS文件放在head中,body中尽量不要出现<script> <style>标签
③资源加载的时机
** 异步加载script: ???
-defer: 异步加载,在HTML解析完成后执行。defer的实际效果与将代码放在body底部类似
-async: 异步加载,加载完成后立即执行
** 模块按需加载: ???
-ECMAScript 提案 的 import() 语法
-webpack 特定的 require.ensure
** 预加载preload ???
-preload让浏览器提前加载指定资源,需要执行时再执行,可以加速本页面的加载速度
** 预读取prefetch ???
-prefetch告诉浏览器加载下一页面可能会用到的资源,可以加速下一个页面的加载速度
** 懒加载: ???
-也叫做资源延迟加载:延迟加载资源或符合某些条件时才加载某些资源
④DOM操作
** HTML Collection(HTML收集器,返回的是一个数组内容信息),document.images、document.forms 、getElementsByTagName()返回类数组对象,但是访问性能要比类数组对象差很多。遍历 HTML Collection时尽量将其 转换为数组后再遍历,尽量少访问它,比如遍历时可以将length属性、成员保存到局部变量后再使用局部变量。
** 减少重排与重绘
【什么是重排与重绘】
生成页面的过程:
HTML代码生成DOM---CSS生成CSSOM(css object model)---结合DOM和CSSOM,生成一棵渲染树(包含每个节点的视觉信息)---
生成布局(layout),即将所有渲染树的所有节点进行平面合成---
将布局绘制(paint)在屏幕上
注意:在生成页面的过程中最耗时的就是布局和绘制过程,这两个过程合称渲染。重排一定会重绘,但是重绘不一定会重排
触发重排的属性:修改元素的尺寸布局隐藏等属性
触发重绘的属性:修改元素的外观风格而不改变布局的属性
【如何减少重排与重绘】
●样式优化
◇ 避免使用层级较深的选择器,或其他一些复杂的选择器,以提高CSS渲染效率
◇ 避免使用CSS表达式???CSS表达式是动态设置CSS属性的强大但危险方法,它的问题就在于计算频率很快。不仅仅是在页面显示和缩放时,就是在页面滚动、乃至移动鼠标时都会要重新计算一次
◇ 元素适当地定义高度或最小高度,否则元素的动态内容载入时,会出现页面元素的晃动或位置,造成
◇ 给图片设置尺寸。如果图片不设置尺寸,首次载入时,占据空间会从0到完全出现,上下左右都可能位移,发生回流
◇ 不要使用table布局,因为一个小改动可能会造成整个table重新布局。而且table渲染通常要3倍于同等元素时间
◇ 能够使用CSS实现的效果,尽量使用CSS而不使用JS实现
●渲染层优化
◇ 将需要多次重绘的元素独立为render layer渲染层,如设置absolute,可以减少重绘范围???
◇ 对于一些进行动画的元素,使用硬件渲染,从而避免重绘和回流???
●DOM优化
◇ 缓存DOM:由于查询DOM比较耗时,在同一个节点无需多次查询的情况下,可以缓存DOM???
◇ 减少DOM深度及DOM数量
HTML 中标签元素越多,标签的层级越深,浏览器解析DOM并绘制到浏览器中所花的时间就越长,所以应尽可能保持 DOM 元素简洁和层级较少。
◇ 批量操作DOM
由于DOM操作比较耗时,且可能会造成回流,因此要避免频繁操作DOM,可以批量操作DOM,先用字符串拼接完毕,再用innerHTML更新DOM
◇ 批量操作CSS样式
通过切换class或者使用元素的style.csstext属性去批量操作元素样式
◇ 在内存中操作DOM
使用DocumentFragment对象,让DOM操作发生在内存中,而不是页面上
◇ DOM元素离线更新
对DOM进行相关操作时,例、appendChild等都可以使用Document Fragment对象进行离线操作,带元素“组装”完成后再一次插入页面,或者使用display:none 对元素隐藏,在元素“消失”后进行相关操作
◇ DOM读写分离
浏览器具有惰性渲染机制,连接多次修改DOM可能只触发浏览器的一次渲染。而如果修改DOM后,立即读取DOM。为了保证读取到正确的DOM值,会触发浏览器的一次渲染。因此,修改DOM的操作要与访问DOM分开进行
◇ 事件代理
事件代理是指将事件监听器注册在父级元素上,由于子元素的事件会通过事件冒泡的方式向上传播到父节点,因此,可以由父节点的监听函数统一处理多个子元素的事件
利用事件代理,可以减少内存使用,提高性能及降低代码复杂度
◇ 防抖和节流
使用函数节流(throttle)或函数去抖(debounce),限制某一个方法的频繁触发
◇ 及时清理环境
及时消除对象引用,清除定时器,清除事件监听器,创建最小作用域变量,可以及时回收内存
⑤
⑥⑦⑧⑨
2、代码级别的优化