JS以及CSS对页面的阻塞

一、JS阻塞

所有的浏览器在下载JS文件的时候,会阻塞页面上的其他活动,包括其他资源的下载以及页面内容的呈现等等,只有当JS下载、解析、执行完,才会进行后面的 操作。在现代的浏览器中CSS资源和图片image资源是并行下载的,在IE6中默认的并行的加载数目是2个,在IE6以后以及其他的浏览器中的默认的并行加载数目是6个。

在浏览器从服务器接收到HTML文档后,并把HTML在内存中转换为DOM树,在转换节点的过程中如果引入了CSS文件以及添加了images,则会在文档加载的同时并行的加载CSS文件以及图片。但是JS不一样,因为浏览器需要1个稳定的DOM树结构,而JS中很有可能有代码直接改变了DOM树结构,比如使用document.write 或 appendChild,甚至是直接使用的location.href进行跳转,浏览器为了防止出现JS修改DOM树,需要重新构建DOM树的情况,所以就会阻塞其他的下载和呈现.在没有使用异步加载(async)或者是延迟加载(defer)的情况下,只有在一个JS文件加载解析完后才能加载后面的JS文件。利用延迟脚本和异步脚本可以实现脚本的并行加载。以下讨论都是在没有这两个属性的情况下。

(1)内嵌脚本的阻塞

直接写在HTML文档中的js代码就是内嵌JS,内嵌脚本无需加载,可以直接执行,所以当页面有内嵌的脚本时,可以直接执行,导致会阻塞所有资源的加载和页面的呈现。

<!DOCTYPE html><html lang="en"><head>
    <meta charset="UTF-8">
    <title>内嵌JS会阻塞页面上的所有内容的呈现</title></head><body><div><ul>
    <li>blogjavaspan style="color: #800000;"</li>
    <li>CSDNspan style="color: #800000;"</li>
    <li>博客园span style="color: #800000;"</li>
    <li>ABCspan style="color: #800000;"</li>
    <li>AAAspan style="color: #800000;"</li></ul><span style="color: #800000;"></span></div><script type="text/javascript">// 循环5秒钟var n = Number(new Date());var n2 = Number(new Date());while((n2 - n) < (6*1000)){
n2 = Number(new Date());
}</script><ul>
    <li>MSNspan style="color: #800000;"</li>
    <li>GOOGLEspan style="color: #800000;"</li>
    <li>YAHOOspan style="color: #800000;"</li></ul></body></html>

上面的内嵌脚不仅会阻塞第二个ul的展示,也会阻塞第一个ul的展示,页面在5秒前是一片空白,当延迟结束后才展现所有的内容

(2)外联脚本阻塞

外联脚本不一样,外联脚本只有当页面加载到该<script>之后才会加载外联脚本,所以外联脚本只会阻塞其后面的内容的呈现以及资源的下载,在下面的代码中,页面会先展示一部分内容,后面一部分内容在5秒后展现

<!DOCTYPE html><html lang="en"><head>
    <meta charset="UTF-8">
    <title>外联JS文件只会阻塞后面的资源的下载和呈现</title></head><body><ul>
    <li>blogjavaspan style="color: #800000;"</li>
    <li>CSDNspan style="color: #800000;"</li>
    <li>博客园span style="color: #800000;"</li>
    <li>ABCspan style="color: #800000;"</li>
    <li>AAAspan style="color: #800000;"</li></ul><script src="定时.js"></script><!--定时中的代码和上面的延迟函数的内容一样的--><ul>
    <li>MSNspan style="color: #800000;"</li>
    <li>GOOGLEspan style="color: #800000;"</li>
    <li>YAHOOspan style="color: #800000;"</li></ul></body></html>

二、嵌入JS导致CSS阻塞加载的问题

    
    Title

fireBug中的时间栈:

谷歌中的事件栈:

在上图中CSS和图片是并行下载的,通过时间线可以看出,后面的图片并没有等到CSS文件完全加载完后在加载。

(2)内嵌脚本导致CSS阻塞页面

<!DOCTYPE html><html><head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link type="text/css" rel="stylesheet" href="http://cdn.bootcss.com/bootstrap/4.0.0-alpha.6/css/bootstrap-grid.css" />
    <script type="text/javascript">
        function a(){};    </script></head><body><img src="http://www.blogjava.net/images/logo.gif" /><img src="http://csdnimg.cn/www/images/csdnindex_piclogo.gif" /></body></html>

fireBug中的时间栈:

谷歌中的时间栈:

通过上图在狐火中由于内嵌脚本的作用使得图片要等到css完全加载完后在加载,即CSS阻塞了图片的加载。其实质是因为浏览器会维持HTML中CSS和JS的顺序,即在JS前面出现的CSS文件需要加载、解析完后才会执行后面的内嵌JS,而内嵌JS又会阻塞后面的内容

(2)外联脚本

<!DOCTYPE html><html><head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link type="text/css" rel="stylesheet" href="http://cdn.bootcss.com/bootstrap/4.0.0-alpha.6/css/bootstrap-grid.css" />
    <script type="text/javascript" src="fun.js"></script><!--这里fun中的内容就是a方法--></head><body><img src="http://www.blogjava.net/images/logo.gif" /><img src="http://csdnimg.cn/www/images/csdnindex_piclogo.gif" /></body></html>

外联脚本会阻塞后面资源的加载,但是在谷歌浏览器中不管是内联还是外联的脚本均不会阻塞

三、为了不阻塞页面脚本的放置位置

(1)尽量合并脚本减少<script>的出现

(2)尽量使用外联脚本并将脚本放置在<body>底部

(3)使用延迟脚本和异步脚本

(4)内嵌脚本放置在window.onload中执行

时间: 2024-08-10 01:59:40

JS以及CSS对页面的阻塞的相关文章

JS 和 CSS 的位置对其他资源加载顺序的影响

JS 和 CSS 在页面中的位置,会影响其他资源(指 img 等非 js 和 css 资源)的加载顺序,究其原因,有三个值得注意的点: JS 有可能会修改 DOM. 典型的,可能会有 document.write. 这意味着,在当前 JS 加载和执行完成前,后续所有资源的下载有可能是没必要的.这是 JS 阻塞后续资源下载的根本原因. JS 的执行有可能依赖最新样式.比如,可能会有 var width = $('#id').width(). 这意味着,JS 代码在执行前,浏览器必须保证在此 JS

Asp.Net之后台加载JS和CSS

在Asp.Net开发时,用到的JS库.通用的CSS等,在许多页面都会用到,而每次都需要手动引入,相当麻烦,而且有时一旦忘了引用,还得找半天才能找到问题.那有没有什么办法能够一劳永逸的呢?答案是有的. 我们知道Asp.Net是可以通过后台来渲染前端的,所以如果能够在渲染时将所要的js库和css等添入就可以了.而为了能够复用,所以需要进行类的继承.我们写一个Page的基类PageBase,代码如下. [html] view plaincopy using System; using System.C

CSS加载会阻塞页面显示?

可能大家都知道,js执行会阻塞DOM树的解析和渲染,那么css加载会阻塞DOM树的解析和渲染吗?接下来,我们就一起来分析一下. 原理解析 那么为什么会出现上面的现象呢?我们从浏览器的渲染过程来解析下. 不同的浏览器使用的内核不同,所以他们的渲染过程也是不一样的.目前主要有两个: webkit渲染过程 Gecko渲染过程 从上面两个流程图我们可以看出来,浏览器渲染的流程如下: HTML解析文件,生成DOM Tree,解析CSS文件生成CSSOM Tree 将Dom Tree和CSSOM Tree结

asp.net使用httphandler打包多CSS或JS文件以加快页面加载速度

介绍 使用许多小得JS.CSS文件代替一个庞大的JS或CSS文件来让代码获得更好的可维 护性,这是一个很好的实践.但这样做反过来却损失了网站的性能.虽然你应该将你的Javascript代码写在小文件中并且将大的CSS文件分割到小文件 中,当一个浏览器请求那些JS以及CSS文件,它却将为每一个文件产生一个请求.每一个HTTP请求将导致从你的浏览器到服务器上的一次"往返",从响应 服务器到客户端浏览器之间的等待时间称之为"延时".因此,如果你有四个JS文件以及三个CSS

【easyui】关于tabs的选项卡的href 引入页面后 js、css失效

示例: $("tabs").tabs("add",{ href:"test.html" }) test.html 只有body里的内容会被执行  如果js或css在body外则会失效 解决办法: 1.如果是内部js.css   将它们放到body内即可 2.如果是外部js.css   将他们在主页面引用即可 3.写一个servlet,在servlet里response.sendRedirect("test.html") [附]

js+html+css实现简单页面交互功能(2015知乎前端笔试题)http://v.youku.com/v_show/id_XMTI0ODQ5NTAyOA==.html?from=y1.7-1.2

js+html+css实现简单页面交互功能(2015知乎前端笔试题) http://v.youku.com/v_show/id_XMTI0ODQ5NTAyOA==.html?from=y1.7-1.2 密码:hellozhihu

原生aspx页面如何引用公共js和css

项目过程中遇到一个问题,每个页面需要引用很多的js和css文件,其中很多都是控件,而且大部分都是一样的,造成很多重复引用. 针对这种情况,参考了mvc的BundleConfig,思路是建立一个公用的用户控件,直接在每个页面调用这个用户控件,通过不同的参数获取不同的引用文件,这种方式的好处就是大大减少了工作量,也规范了代码, 不会出现一个文件引用多次的情况了. 具体实现如下: 1.  新建一个用户控件:BundleConfig.ascx 2.前端调用,这里放到head里面.(注意:web.conf

Maven工程webinfo下面的JSP页面无法加载.js、.css文件的解决方案

--下面是我的工程路径 --我jsp的写法 -----启动工程,访问js文件的路径是这样的, href="http://localhost:8080/activiti/css/public.css" 怎么看都没毛病.但是提示404找不到. 所以判断是因为访问被拦截住了.最后分析查找得知,是因为在web.xml缺少了SpringMVC拦截设置. -----下面这段代码来源于其他博客转载 通过在web.xml中添加如下设置后,问题的得以解决: 注意: 下面这段代码,要写在引入springM

将js和css文件装入localStorage加速程序执行

原理如下: 一次批量加要加载的文件存入数组,采用Ajax方式异步载入各个文件,然后采用循环方式逐个执行下载下来的Js或者Css文件,如果已经被缓存(localStorage)的则省略下载过程. 由于JS采用的是单线程模式运行,在执行某一个js时会阻塞其它并发的js执行,所以会按顺序执行各个js.在执行完所有的脚本之后,图片会被浏览器接着 加载,所以第一次加载速度略慢,后面就会比较快了.在JQuery Mobile 1.4.5+FireFox/微信浏览器下实测效果不错,IE就被省略了,我主要是要在