JS脚本文件的位置对页面加载性能影响以及无阻塞脚本(javascript)模式
JS的阻塞特性:当<script>出现的时候,页面必须等待脚本文件的加载、解析、执行完毕后才能继续进行页面的渲染。不管脚本文件是以内联形式还是外部引入的形式出现在<script>中,页面的加载和渲染都必须停下来等待脚本文件的执行完成。因为在脚本文件中可能会修改页面的内容。这就会出现一个问题,当HTML文件中引入很多的外部脚本文件和内联脚本时,可能会导致页面的严重阻塞,影响页面的加载和渲染,用户体验特别的差。因而需要寻找适当的方法来减小脚本文件对页面加载带来的影响。
改善性能的几种方式:
1、 我们都知道脚本文件既可以存放在<head>标签中也可以存放在<body>标签中,并且是循序重复出现的如果将将本文件放在<head>中,如下:
<!DOCTYPE html>
<html >
<head>
<meta charset="utf-8">
<title></title>
<script src="script.js"></script>
<script src="file1.js"></script>
<script src="file2.js"></script>
<script src="file3.js"></script>
<link rel="styleSheet" type="text/css" hhref="styles.css"></link>
</head>
<body onload="init()">
<p> swapCache方法示例</p>
</body>
</html>
在上述代码在<head>中加载了四个JS文件,由于脚本阻塞页面的渲染,所以只有当脚本全部下载完并执行完毕后,页面才会开始渲染,在body标签之前是不会渲染任何部分的。同时在加载JS文件时,只有当前一个加载完毕并执行完毕后才会进行下一个JS文件的加载和执行,在早期的浏览器中都是不能进行JS文件的并行下载的,不过目前很多主流的浏览器都支持异步加载JS包,但是页面渲染的其他资源如图片等,仍然或因为JS的加载而阻塞,所以通常建议将JS文件尽量放在<body>标签中,以尽量减少对整个页面下载的影响。
2、由于每个<script>标签的初始下载时都会阻塞页面的渲染,所以尽量减少<script>标签的数量有助于改善页面阻塞情况。也就是说内联JS文件尽量合并,外部引入的文件如果可以合并最好不过,通常单个下载100KB文件比下载4个25KB文件更快。
3、无阻塞脚本的秘诀在于,在页面加载完毕后才加载javascript代码,也就是说当触发window对象的onload事件后再下载脚本。有如下几种方式实现这一效果:
(1)利用属性:async/defer
async:异步加载脚本同时在脚本加载的时执行脚本,不影响页面的加载和渲染
defer:异步加载脚本同时进行页面渲染,但脚本的执行需要等到页面加载完毕
<!DOCTYPE html>
<html >
<head>
<meta charset="utf-8">
<title></title>
<script defer>
alert("defer");
</script>
<script >
alert("script");
</script>
<script>
window.onload=function(){
alert("onload")
}
</script>
<link rel="styleSheet" type="text/css" hhref="styles.css"></link>
</head>
<body onload="init()">
<p> swapCache方法示例</p>
</body>
</html>
上述代码在不支持defer的浏览器弹出的顺序依次为:defer,script,load;在支持defer的浏览器中的弹出顺序为:script,defer,load。带有defer属性的标签是在onload的事件执行之前执行的,也即当页面加载完后执行带有defer属性的<script>中大JS代码。但是加载与页面加载异步执行的。
(2)利用动态脚本元素即通过document.createElement("script")动态生成脚本
var script=document.craateElement("script");
script.type="text/script"
script.src="file.js";
docuemnt.getElementsByTagName("head")[0].appendChild("script");
这种方法的优势在于无论什么时候启动加载,问价的下载和执行都不会阻塞页面的其他进程。该方法具有挂浏览器的兼容性和易用性优势,是最为通用的无阻塞加载的解决方法。
(3)XMLHttpRequest脚本注入的方法
利用XHR对象,借助它进行javascript脚本的下载,最后通过动态创建<script>元素将代码注入到页面当中
var xhr=new XMLHttpRequest();
xhr.open("get","file.js",true);
xhr.onreadystatechange=function(){
if(xhr.state==4&&xhr.status==200)
var script=docuemnt.createElement("script");
script.type="text/script";
script.text=xhr.reaponseText;
document.body.appendChild(script);
}
JS脚本文件的位置对页面加载性能影响以及无阻塞脚本(javascript)模式的更多相关文章
- 【JavaScript】页面加载性能优化
核心在于:减少加载时间 1.减少请求次数 2.缩减文件大小 3.异步加载---------------------->比如document.write 4.延迟加载.动态加载---------- ...
- js数据显示在文本框中(页面加载显示和按钮触动显示)
web代码如下: <!DOCTYPE html> <html> <head> <title>jsTest02.html</title> &l ...
- 前端开发入门到进阶第三集【js和jquery的执行时间与页面加载的关系】
https://blog.csdn.net/u014179029/article/details/81603561 [原文链接]:https://www.cnblogs.com/eric-qin/p/ ...
- Web前端性能优化——如何提高页面加载速度
前言: 在同样的网络环境下,两个同样能满足你的需求的网站,一个"Duang"的一下就加载出来了,一个纠结了半天才出来,你会选择哪个?研究表明:用户最满意的打开网页时间是2-5秒, ...
- 【转】Web前端性能优化——如何提高页面加载速度
前言: 在同样的网络环境下,两个同样能满足你的需求的网站,一个“Duang”的一下就加载出来了,一个纠结了半天才出来,你会选择哪个?研究表明:用户最满意的打开网页时间是2-5秒,如果等待超过10秒, ...
- Web前端性能优化——提高页面加载速度
前言: 在同样的网络环境下,两个同样能满足你的需求的网站,一个“Duang”的一下就加载出来了,一个纠结了半天才出来,你会选择哪个?研究表明:用户最满意的打开网页时间是2-5秒,如果等待超过10秒, ...
- 【ASP.NET MVC】提高页面加载速度:脚本优化
在这里我们说一下脚本优化的三个方法: 一.在我们做Web开发的时候,当我们引用Js文件的时候,我们一般会将js文件放在文档的head标签中,这时当页面加载的时候,浏览器会按着由上到下的顺序,当浏览器遇 ...
- angularjs ocLazyLoad分步加载js文件,angularjs ocLazyLoad按需加载js
用angular有一段时间了,平日里只顾着写代码,没有注意到性能优化的问题,而今有时间,于是捋了捋,讲学习过程记录于此: 问题描述:由于采用angular做了网页的单页面应用,需要一次性在主布局中将所 ...
- 20180911 关于页面加载顺序引发的JS的undefined/null错误
引用: 百度知道-HTML+JavaScript执行顺序问题 这是我在学习JS滚动播放图片案例意外遇到的一个问题,代码完成后console弹出错误警告: Uncaught TypeError: Can ...
随机推荐
- Linux chkconfig 命令详解
一.简介 chkconfig 命令主要用来更新(启动或停止)和查询系统服务的运行级信息.谨记chkconfig不是立即自动禁止或激活一个服务,它只是简单的改变了符号连接. 二.安装&启动 us ...
- Visual Studio: Show Solution Platform in Toolbar
link: http://stackoverflow.com/questions/7516755/solution-configuration-but-not-platform-in-vs2010-t ...
- A hard puzzle
A hard puzzle Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Tot ...
- python 代码片段19
#coding=utf-8 # 函数 def foo(x): print x foo(123) # import httplib def check_web_server(host,port,path ...
- BZOJ3562 : [SHOI2014]神奇化合物
可以发现,从头到尾有一堆点是始终连在一起的,所以把没被删掉的一开始就有的边都加上后求出每个联通块, 缩完点后我们发现,边数也减少得差不多了,剩下的就直接暴力. #include<cstdio&g ...
- JS学习(二)
1 数组对象 作用是:使用单独的变量名来存储一系列的值. 1.1 新建数组: var mycars = new Array() mycars[0] = "Saab" mycars[ ...
- 相遇点对 & 数点问题
题意: 一个长为l的环,环上有n个点,每个点以一定的速度顺时针或逆时针运动,两个点相遇即某一时刻内两个点位置相同. 求有多少点对相遇----相同点对出现多次仅统计一次. SOL: 考试的时候想到用线段 ...
- BZOJ 2038 小z的袜子 & 莫队算法(不就是个暴力么..)
题意: 给一段序列,询问一个区间,求出区间中.....woc! 贴原题! 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿.终于有一天,小Z再也无法忍受这恼人的找袜子过 ...
- 51Nod 1021 石子合并 Label:Water DP
N堆石子摆成一条线.现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的代价.计算将N堆石子合并成一堆的最小代价. 例如: 1 2 3 4,有 ...
- linux 远程桌面的配置
root根用户登录在/root目录下#rpm -q vnc vnc-server查询已安装vnc的客户端和服务器端vnc-4.1.1-36vnc-server-4.1.1-36 #vi /etc/sy ...