Web运行环境总结
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 的重新布局