浏览器兼容性问题
浏览器的兼容性包括样式兼容性(CSS)、交互兼容性(javascript)、浏览器hack
样式兼容性
(1) 通过Normalize.css 不同的浏览器样式存在差异,可以通过normalize.css抹平差异,或者定制自己的reset.css
(2) 浏览器CSS兼容前缀。在开发过程中一般通过IDE开发插件、CSS预处理器以及前端自动化构建工程帮我们处理
浏览器内核与前缀的对应关系如下
内核 主要代表的浏览器 前缀 JS引擎
Trident IE浏览器 -ms
Gecko Firefox -moz
Presto Opera -o
Webkit Chrome和Safari -webkit v8
(3) opacity属性
div { opacity:0.5 }
IE8和早期版本支持另一种过滤器属性。像:filter:Alpha(opacity=50)
浏览器内核
一个浏览器通常由以下常驻线程组成:
-
GUI渲染线程 负责渲染浏览器界面,解析 HTML,CSS,构建 DOM 树和 RenderObject 树,布局和绘制等
-
JS引擎线程(JS内核)
负责解析 Javascript 脚本,运行代码 -
事件触发线程
用来控制事件循环 -
定时触发器线程
-
异步http请求线程
浏览器多进程架构
- 主进程:负责浏览器界面的显示与交互。各个页面的管理,创建和销毁其他进程。网络的资源管理、下载等
- 第三方插件进程:每种类型的插件对应一个进程,仅当使用该插件时才创建。
- GPU进程:用于3D绘制等
- 渲染进程(也称浏览器内核,内部是多线程的,主要负责页面渲染、脚本执行、事件处理等)
- 事件触发线程:当对应的事件符合触发条件被触发时,该线程会把事件添加到待处理队列的队尾,等待 JS 引擎的处理
- 定时触发器线程:setInterval 与 setTimeout 所在线程
- 异步http请求线程
- GUI渲染线程:负责渲染浏览器界面,解析 HTML,CSS,构建 DOM 树和 RenderObject 树,布局和绘制等
- JS引擎线程:也称为 JS 内核,负责处理 Javascript 脚本程序
注意: GUI渲染线程与JavaScript引擎为互斥关系
浏览器是多线程的
JavaScript是单线程的,与异步不冲突
- JS的单线程是指一个浏览器进程中只有一个JS的执行线程,同一时刻内只会有一段代码在执行
- 异步机制是浏览器的两个或以上常驻线程共同完成的 比如异步请求由JS执行线程和事件触发线程共同完成
CSS加载会造成哪些阻塞?
- CSS不会阻塞DOM解析,但是阻塞DOM渲染
- CSS会阻塞JS执行,并不会阻塞JS文件下载
DOM和CSSOM通常是并行构建的,所以CSS不会阻塞DOM解析 但是渲染树(render tree)依赖DOM tree和CSSOM tree的,需两者加载完后才开始渲染,所以CSS会阻塞DOM渲染
JS文件下载和CSS文件下载是并行的,而样式表会在后面的js执行前先加载,所以CSS会阻塞后面js的执行
JS会阻塞页面加载?
JS阻塞DOM解析,也就会阻塞页面
defer和async的区别?
同:
- 两者都是异步加载外部JS文件,不会阻塞DOM解析
- async是在外部JS加载完成后,load事件触发前执行
- defer是在JS加载完成后,整个文档解析完成后,触发DOMContentLoaded事件前执行
异:
<script async src="js/vendor/jquery.js"></script>
async表示异步
- 浏览器遇到async脚本时,请求该脚本的网络请求是异步的,不会阻塞浏览器解析HTML,一旦网络请求回来之后,如果HTML没有解析完,浏览器会暂停解析,先让JS引擎执行代码,执行完毕后再进行解析
- 所以async是不可控的,乱序 | 它们之间的执行顺序完全依赖于网络传输结果
<script defer src="js/script2.js"></script>
defer表示延迟
- 当浏览器遇到defer脚本时,获取该脚本的网络请求也是异步的,不会阻塞浏览器解析HTML,一旦网络请求回来之后,如果此时HTML没有解析完,浏览器不会暂停解析并执行JS代码,而是等待HTML解析完再执行JS代码。即脚本会被延迟到整个页面都解析完毕后再运行
- 如果存在多个defer script标签,浏览器会保证它们按照在HTML出现的顺序执行,不会破坏JS脚本之间的依赖关系