https://www.bilibili.com/video/BV1f4411R7M5?p=48
页面绘制,渲染引擎一行一行1px去绘制页面,按照语法绘制
- 首先识别html代码,形成domTree
浏览器解析代码 深度优先
解析:认识是什么东西就行,没必要等里面的东西下载完。 --> 读到img标签,直接把节点挂到domTree上,不等它下载完
domTree的完成表示所有dom节点解析完毕,不是加载完毕
-
生成cssTree
-
domTree + cssTree = renderTree(render:渲染绘制
-
渲染引擎绘制页面
js动态修改dom元素,domTree改变,renderTree重新构建,页面重新绘制,浪费效率
dom优化,尽量减少dom节点的增删,最好一次做完
reflow 重排/重构:renderTree的重新构建
dom节点的删除、添加
dom节点的宽高变化、位置变化、display none --> block
offsetWidth offsetLeft
repaint 重绘 影响小,效率浪费的小
异步加载js
js加载(同步加载):加载到js文件,阻断了html、css加载线,加载完并且执行完才继续下载html、css,因为js会修改html、css
js加载的缺点︰加载工具方法没必要阻塞文档,过得js加载会影响页面效率,—旦网速不好,那么整个网站将等待js加载而不进行后续渲染等工作。
有些工具方法需要按需加载,用到再加载,不用不加载。
异步加载:系统读到js,不会阻断html、css下载,会和它们并行下载
javascript异步加载的三种方案
- defer 异步加载, 但要等到 dom文档 全部解析完(domTree生成)才会被 执行。
只有IE能用,可以引入外部文件,也可以将代码写到内部。
<script type="text/javascript" src="tools.js" defer></script>
<script type="text/javascript" defer>
var a = 123;
</script>
defer = 'defer'
属性名 = 属性值,只写属性名
-
async 异步加载, 加载完就执行,async只能加载外部脚本,不能把js写在script标签里。
<script type="text/javascript" src="tools.js" async></script>
1.2执行时也不阻塞页面
- 创建script,插入到DOM中,加载完毕后callBack,
var script = document.createElement('script');
script.type = "text/javascript";
script.src = "demo.js";
script.onload = function(){ // 下载完成触发
test();
}
// script.onload 兼容性:Safari chrome firefox opera
// IE
// 状态码 -- readyState script.readyState
// 一开始是loading,会根据script标签加载进度,动态改变值,加载完改为complete/loaded
script.onreadystatechange = function (){
if(script.readyState == 'complete' || script.readyState == 'loaded'){
test();
}
}
document. head.appendChild( script);
- 封装为函数
function loadScript(url, callback){
var script = document.createElement('script');
script.type = "text/javascript";
if(script.readyState){
// 传输速度快,在绑定事件之前 readyState改变,无法触发事件,所以先绑定事件,在修改url
script.onreadystatechange = function (){
if(script.readyState == 'complete' || script.readyState == 'loaded'){
callback();
}
}
}else{
script.onload = function(){ // 下载完成触发
callback();
}
}
script.src = url; // "demo.js";
document. head.appendChild( script);
}
// 当满足一定条件才执行的函数叫回调函数 -- callback
// loadScript('demo.js',test); // Uncaught ReferenceError: test is not defined
// 1. 方法1
loadScript('demo.js',function(){ test(); }); // 函数引用,读时不会读里面的代码,函数引用传进去执行时执行函数引用
// 2. 方法2 不要用
// loadScript('demo.js','test()');
// eval(callback); eval会把字符串当函数代码执行
// 3. 数据库
// var tools = {
// test : function(){
// console.log('a');
// },
// demo : function (){
// }
// }
// loadScript('demo.js','test');
// tools[callback]();
// https://www.bilibili.com/video/BV1f4411R7M5?p=48
js加载时间线
js时间线:依据 js 出生的那一刻开始,来记录一系列浏览器按照顺序做的事
-
创建 Document 对象,开始解析 web页面。解析 HTML元素和他们的文本内容后添加 Element 对象和 Text节点到文档中。这个阶段
document.readyState = 'loading'
。 -
遇到 link 外部 css,创建线程加载,并继续解析文档。
-
遇到 script 外部js,并且没有设置 async、defer,浏览器加载,并阻塞,等待js加载完成并执行该脚本,然后继续解析文档。
-
遇到 script 外部 js,并且设置有 async、defer,浏览器创建线程加载,并继续解析文档。
对于async属性的脚本,脚本加载完成后立即执行。(异步禁止使用document.write()
)
-
遇到 img 等,先正常解析 dom结构,然后浏览器异步加载 src,并继续解析文档。
-
当文档解析完成(domTree 刚建立完),
document.readyState = 'interactive'
。 -
文档解析完成后,所有设置有
defer
的脚本会按照顺序执行。(注意与 async 的不同,但同样禁止使用document.write()
); -
document 对象触发
DOMContentLoaded
事件,这也标志着程序执行从同步脚本执行阶段,转化为事件驱动阶段。 -
当所有 async 的脚本 加载完成并执行 后、img等加载完成后,
document.readyState = 'complete'
,window 对象触发 load事件。 -
从此,以异步响应方式处理用户输入、网络事件等。
https://www.bilibili.com/video/BV1f4411R7M5?p=49
BOM
定义: Browser Object Model,定义了操作浏览器的接口
BOM对象: Window,
History,Navigator,Screen, Location等
由于浏览器厂商的不同,Bom对象的兼容性极低。一般情况下,我只用其中的部分功能。
JSON
JSON是一种传输数据的格式(以对象为样板,本质上就是对象,但用途有区别,对象就是本地用的,json是用来传输的)
以前传输数据格式是XML
现在传输数据格式是对象 --> JSON
区别:对象的属性名可加"“可不加,规定JSON的属性名必须加”"
{
'name' : 'deng',
'age' : 20
}
传输数据传的是字符串,JSON格式的字符串'{'name' : 'deng','age' : 20}'
JSON.parse(); string —> json
JSON.stringify(); json —> string