共计 1792 个字符,预计需要花费 5 分钟才能阅读完成。
1. 页面加载过程
1.1 加载一个资源的过程
在浏览器地址栏输入 URL
浏览器查看缓存 (强缓存)
浏览器解析 URL 获取协议,主机,端口,path
浏览器组装一个 HTTP(GET)请求报文
浏览器根据 DNS 服务器得要域名的 IP 地址
打开一个 socket 与目标 IP 地址,端口建立 TCP 链接
向这个 IP 的机器发送 http/https 请求
服务器收到处理并返回 http 请求
判断协商缓存
服务器将响应报文通过 TCP 连接发送回浏览器
关闭 TCP 连接
浏览器检查响应状态吗做出不同处理
如果资源可缓存,进行缓存
浏览器得到返回的内容
1.2 浏览器渲染页面的过程
根据 HTML 结构生成 DOM Tree
根据 CSS 生成 CSSOM
将 DOM 和 CSSOM 整合成 RenderTree(渲染树,比 DOM 树多了样式)
根据 RenderTree 开始渲染和展示
HTML 解析器遇到没有 async 和 defer 的 script 时,会执行并阻塞渲染(js 可能会改变 dom 结构)
浏览器在 Document 对象上触发 DOMContentLoaded 事件
显示页面
图片加载完毕
调用 onload
1.3 为什么把 css 放在 head 中
在 html 渲染之前渲染 css
如果 css 放在 html 元素后面,会先按没有 css 的情况渲染 html,然后加载到 css 后再重新渲染 html 元素,这样会损耗性能。
1.4 为什么要把 js 放在 body 的最下面
1. 不会阻塞 body 中元素的渲染,能让页面更快出来
2.script 能拿到所有的标签
1.5 图片
图片是异步请求,不会影响 dom 树的渲染
1.6 load,DOMContentLoaded
window.addEventListener(‘load’,function(){
// 页面资源全部加载完成,包括图片视频
});
document.addEventListener(‘DOMContentLoaded’,function(){
//DOM 渲染完即可执行,图片视频还没有加载完
});
DOMContentLoaded : dom 结构化完成以后
load:dom 结构化以及静态资源全部加载完毕以后
$(document).ready 底层是 DOMContentLoaded 函数
$(window).load 底层是 load 函数
$(function () {}) 是 $(document).ready 的缩写
var show = console.log.bind(console);
show(‘ 观察脚本加载的顺序 ’)
document.addEventListener(“DOMContentLoaded”, function () {
show(‘DOMContentLoaded 回调 ’)
}, false);
window.addEventListener(“load”, function () {
show(‘load 事件回调 ’)
}, false);
show(‘ 脚本解析一 ’);
$(document).ready(function () {
show(‘$(document).ready’)
})
// 测试加载
$(function () {
show(‘ 脚本解析二 ’);
})
$(window).load(function () {
show(‘$(document).load’);
});
show(‘ 脚本解析三 ’);
1.7 重排 Reflow
DOM 结构中的元素都有自己的盒子,这些都需要浏览器根据各种样式来计算并根据计算结果来将元素放到他们该出现的位置,称为 Reflow。
触发 reflow 的条件:
1. 增删改 dom 节点
2. 移动 dom 位置或者有动画
3. 修改 css 样式
4.resize 窗口或者滚动(移动端没有该问题)
1.8 重绘 Repaint
页面要呈现的内容绘制在屏幕上。
DOM 改动,CSS 改动(判断页面呈现的内容有没有发生变化)
1.9 避免 relow 和 repaint
1. 尽量用 class 来修改样式
如果要修改多个样式,每个样式修改时都会出发 reflow,可以将这些样式保存在一个 class 中,每次修改只 reflow 一次。
将元素的 position 设置为 absolute 和 fixed 可以使元素从 DOM 树结构中脱离出来独立的存在,而浏览器在需要渲染时只需要渲染该元素以及位于该元素下方的元素,从而在某种程度上缩短浏览器渲染时间,这在当今越来越多的 Javascript 动画方面尤其值得考虑。
不要使用 table 布局,可能很小的一个小改动会造成整个 table 的重新布局