在浏览器渲染过程中的阻塞和一些解决方法

来源:互联网 发布:mac 序列号 编辑:程序博客网 时间:2024/06/05 15:35

昨天总结了一下浏览器的渲染机制和特别总结了一下dom树的构建。今天再看一些资料发现其中还有一个大学问。就是有关于阻塞的问题。昨天我还以为只有js脚本会阻塞html解析和browser渲染。其实会导致阻塞的还有css。
在browser进行加载时,其实是并行加载所有资源。对于css和图片等资源,browser加载是异步的,并不会影响到后续的加载、html解析和后续渲染。对于js脚本文件的加载,则会导致html解析和渲染停止,直至js脚本加载并执行完毕才继续。但是对于后续的资源加载并不会停止,browser会对后续资源进行预加载

现在来总结一下我对于css阻塞和js阻塞的一些理解。
对于css阻塞渲染:
css的加载并不会导致html解析和渲染的停止,但是会影响到js脚本的执行。因为js脚本不仅可以读取修改到dom,也可以读取修改到cssom。故在js脚本执行前,browser必须保证到css文件完全加载并解析完成,即cssom树完全构建好。这就导致了js执行的延迟,也因此导致html解析和渲染延迟。
(这就是css阻塞js执行,阻塞渲染的根本原因)
因此一些解决方法:
1、在引入顺序上,css资源的引入要优于js脚本的引入
2、对css进行精简并尽快提供
3、可以用媒体类型(会加载不会阻塞)
4、用媒体查询(会记载,只有在符合的设备上才会进行阻塞)

对于JavaScript的阻塞则更复杂,js脚本的记载会到html解析、渲染停止,直到js脚本加载执行完毕才继续。(这也是为什么将js脚本放于body后)
对于js阻塞,有两种解决方法,defer(延迟执行)和async(异步执行)。这两种方法只适合与引入式的js脚本,不适合inline-script。

defer属性(<script src="" defer></script>
(这是延迟执行引入的js脚本(即脚本加载是不会导致解析停止,等到document全部解析完毕后,defer-script也加载完毕后,在执行所有的defer-script加载的js代码,再触发Domcontentloaded)

async属性(<script src="" async></script>
(1)这是异步执行引入的js脚本文件
(2)与defer的区别是async会在加载完成后就执行,但是不会影响阻塞到解析和渲染。但是还是会阻塞load事件,所以async-script会可能在DOMcontentloaded触发前或后执行,但是一定会在load事件前触发。

因为是菜鸡,肯定还有很多不足,欢迎留言修改

原创粉丝点击