从输入url到渲染出页面的整个过程
- 网络请求:DNS解析、HTTP请求
- 解析:DOM树、CSSOM树、渲染树
- 渲染:布局、绘制、执行JS
浏览器渲染过程
注意:
- 渲染过程是逐步完成的,解析完一部分内容,就显示一部分,同时,这个过程可能还存在着其他请求资源的操作
- 渲染对象和DOM元素相对应,但不是一一对应的关系,可能存在着一些不可见的DOM元素,不会被插入到渲染树里
- JS脚本的执行会阻塞浏览器的解析渲染,因为可能存在着对DOM树的改变
window.onload和DOMContentLoad的区别
- window.onload 资源全部加载完(包括图片、视频等),才触发
- DOMContentLoaded dom渲染完触发,此时图片等可能还未加载完
性能优化
性能优化原则 - 空间换时间
- 多使用内存、缓存或者其他方法
- 减少CPU计算量,减少网络加载耗时
提高加载速度
- 减少资源体积:压缩代码
- 减少访问次数:合并代码;SSR服务器渲染;缓存
- 使用更快的网络:CDN
提高渲染速度
- CSS放在head,JS放在body最下面
- 尽早开始执行JS,用DOMContentLoaded触发
- 懒加载
- 对dom查询进行缓存
- 避免频繁操作dom的情况,将操作合并到一起再插入dom
- 防抖
// 防抖 - 一段时间内连续触发,只执行最后一次
// 场景:用户输入结束或者暂停时,触发相应事件
function debounce (fn, delay = 500) { // 默认间隔的时间是500ms
let timer = null // 定时器
return function () {
if (timer) // 清空定时器
clearTimeout(timer)
timer = setTimeout(() => {
// 执行函数
fn.apply(this, arguments)
timer = null
}, delay)
}
}
- 节流
// 节流 - 每隔一段时间触发一次
// 场景:拖拽时,获取元素位置
function throttle(fn, delay = 100) {
let timer = null
return function () {
if (timer) // 保证一段时间内只执行一次
return
timer = setTimeout(() => {
fn.apply(this, arguments)
timer = null
}, delay)
}
}