浏览器线程
- js主线程
- GUI渲染线程
- 事件监听线程
- 计时器线程
- 网络线程
渲染流程:
- 解析HTML形成DOMTree
- 解析css形成CSS Rule Tree
- 将DOMTree 和 cssTree 合并形成 RenderTree
- 根据渲染树计算出每一个节点在页面中的位置
- 根据布局进行绘制
- repaint 重绘 当页面中某个元素的样式(颜色)发生改变会引起重绘
- reflow 回流 当页面中的布局(位置、宽高)引起回流
display:none 引起回流 脱离文档流 整个页面元素的位置会重新布局
visibility:hidden 引起重绘 占用文档流
异步加载:
- 在script标签中添加 defer属性,这个脚本要等到dom解析完成后才执行
- 在script标签中添加 async属性,这个脚本加载完成后立马执行
异步加载
js加载脚本时也是一个同步的过程,js加载会影响整页面的效率,需要对工具方法进行按需加载,需要用到的时候再加载
js中的异步加载方案:
- defer异步加载,要等到dom文档全部解析完成之后才会执行
- async异步加载,只要js文件加载完就执行,
只能加载外部链接的js文件
- 按需加载
js加载时间线
时间线:浏览器解析页面时,记录一系列按照顺序做的事情
-
创建Document对象、创建Element对象,开始解析HTML页面和节点中的内容添加到Element对象和Text对象中去。这个阶段document.readyState = ‘loading’。
-
遇到link外部css,创建线程加载,并继续解析文档。
-
遇到script外部js,并且没有设置async、defer,浏览器创建线程加载,并阻塞,等待js加载完成并执行该脚本,然后继续解析文档。
js拥有修改dom的能力-->domcument.write
-
遇到script外部js,并且设置有async、defter,浏览器创建线程加载,并继续解析文档。
- async属性的脚本,脚本加载完成后立即执行。
- defter等待整个完档解析完之后再执行。
- document.createElement(‘script’)的方式动态插入script元素来模拟async属性,实现脚本异步加载和执行。
-
遇到img等,浏览器创建线程加载,并继续解析文档。并发
-
当文档解析完成,document.readyState = ‘interactive’。文档解析完成
-
文档解析完成后,所有设置有defer的脚本会按照顺序执行。(注意与async的不同)
-
document对象触发DOMContentLoaded事件,这也标志着程序执行从同步脚本执行阶段,转化为事件驱动阶段。
-
当所有async的脚本加载完成并执行后、img等加载完成后,document.readyState = ‘complete’,window对象触发load事件。
-
从此,以异步响应方式处理用户输入、网络事件等。
-
document.readyState = ‘loading’ 加载中
- 外部链接文件(css、js异步、img) 创建子线程去下载外部资源,并且继续解析文档
- 如果js为同步代码(没有设置defer、async),创建子线程去下载外部资源,等待下载完成并且执行js代码
-
document.readyState = ‘interactive’ 文档解析完成
- 会触发DOMContentLoaded事件
- 按照顺序执行defer脚本代码
- async脚本下载完后立马执行
-
document.readyState = ‘complete’ 加载完成 所有外部资源下载完成
- 触发load事件
注意:在异步js脚本中 不要使用document.write()方法
ES5数组API
forEach() 遍历数据
every() 判断当前数组中是否所有的数据都满足条件
some() 判断当前数组中是有一个数据满足条件
reduce() 以此取出数组中的数据 然后将返回值作为参数的值
map() 返回一个新数组 并且是当前数组中经过处理的数据
filter() 返回一个新数组 存储满足条件的所有数据