【Hight Performance Javascript】——脚本加载和运行
脚本加载和运行
当浏览器遇到一个<script>标签时,无法预知javascript是否在<p>标签中添加内容。因此,浏览器停下来,运行javascript代码,然后继续解析、翻译页面。
浏览器必须首先下载外部文件的代码,这要占用一些时间,然后解析并运行代码,这又要占用一些时间。此过程中,页面解析和用户交互是被完全阻塞的。
将脚本放在底部
合并脚本减少个数
延迟脚本(defer)
<script src="file1.js" defer></script>
defer属性指明元素中所包含的脚本不打算修改DOM,因此代码可以稍后执行。对应的Javascript文件将在<script>被解析时启动下载,但代码不会立即执行,直到DOM加载完成(在onload事件句柄被调用之前)。拥有defer属性的文件可以用页面的其他资源一起并行下载。
兼容性:只被IE 4+ 和FF 3.5+支持,在其他浏览器,defer属性被忽略。
动态异步加载脚本
动态脚本加载时非阻塞Javascript下载中最常用的模式,因为它可以跨浏览器,而且简单易用。
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = 'file1.js';
document.getElementsByTagName('head')[0].appendChild(script);
无论在何处启动下载,文件的下载和运行都不会阻塞其他页面处理过程。甚至可以放在<head>部分。
当使用动态脚本节点下载时,返回的代码通常立即执行。当脚本是“自运行”类型时,这一机制运行正常,但如果脚本只包含供页面其他脚本调用的调用接口,则会带来问题。此时,需要跟踪脚本下载完成并准备妥善的情况。使用动态<script>节点发出时间得到相关信息:
function loadScript(url, cb) {
var script = document.createElement('script');
script.type = 'text/javascript';
if(script.readyState) {// IE
script.onreadyStatechange = function () {
if(script.readyState === 'load' || script.readyState === 'complete') {
script.onreadystatechange = null;
cb();
}
}
}else {// Others
script.onload = function () {
cb();
}
}
script.src = 'file1.js';
document.getElementsByTagName('head')[0].appendChild(script);
}
浏览器不保证文件加载的顺序,下面可以保证脚本按顺序下载并运行:
loadScript('file1.js',function () {
loadScript('file2.js', function () {
...
})
})
如果多个文件的次序十分重要,更好的方法是讲这些文件按照正确的次序连接成一个文件。
XHR 脚本注入
var xhr = new XMLHttpRequest();
xhr.open("get", "file1.js", true);
xhr.onreadystatechange = function(){
if (xhr.readyState == 4){
if (xhr.status >= 200 && xhr.status < 300 || xhr.status == 304){
var script = document.createElement ("script");
script.type = "text/javascript";
script.text = xhr.responseText;
document.body.appendChild(script);
}
}
};
xhr.send(null);
优点:下载不立即执行的javascript代码;同样的代码在所有现代浏览器中都不会引发异常。
缺点:Javascript文件必须与页面放置在同一个域内,不能从CDNs 下载。
推荐的非阻塞模式
推荐的向页面加载大量脚本的方法分为两个步骤:第一步,包含动态加载javascript所需的代码,然后加载页面初始化所需的除javascript之外的部分。这部分尽量小,可能只包含loadScript()函数。当初始代码准备好之后,用它来加载其余的javascript。例如:
<script type="text/javascript" src="loader.js"></script>
<script type="text/javascript">
loadScript("the-rest.js", function(){
Application.init();
});
</script>
【Hight Performance Javascript】——脚本加载和运行的更多相关文章
- 浏览器环境下Javascript脚本加载与执行探析之DOMContentLoaded
在”浏览器环境下Javascript脚本加载与执行探析“系列文章的前几篇,分别针对浏览器环境下JavaScript加载与执行相关的知识点或者属性进行了探究,感兴趣的同学可以先行阅读前几篇文章,了解相关 ...
- 浏览器环境下JavaScript脚本加载与执行探析之动态脚本与Ajax脚本注入
在<浏览器环境下JavaScript脚本加载与执行探析之defer与async特性>中,我们研究了延迟脚本(defer)和异步脚本(async)的执行时机.浏览器支持情况.浏览器bug以及 ...
- 浏览器环境下JavaScript脚本加载与执行探析之defer与async特性
defer和async特性相信是很多JavaScript开发者"熟悉而又不熟悉"的两个特性,从字面上来看,二者的功能很好理解,分别是"延迟脚本"和"异 ...
- (转)高性能JavaScript:加载和运行(动态加载JS代码)
浏览器是如何加载JS的 当浏览器遇到一个<script>标签时,浏览器首先根据标签src属性下载JavaScript代码,然后运行JavaScript代码,继而继续解析和翻译页面.如果需要 ...
- 浏览器环境下JavaScript脚本加载与执行探析之代码执行顺序
本文主要基于向HTML页面引入JavaScript的几种方式,分析HTML中JavaScript脚本的执行顺序问题 1. 关于JavaScript脚本执行的阻塞性 JavaScript在浏览器中被解析 ...
- JavaScript脚本加载相关知识
<script>标签的位置 HTML4规范允许<script>可以放在<head>或<body>中. 但是,放在<head>中会导致性能问题 ...
- js文件加载太慢,JavaScript文件加载加速
原文出自:https://blog.csdn.net/seesun2012 js脚本加载太慢,JavaScript脚本加载加速(亲测有效) 测试背景: JS文件大小:6.1kB 传统形式加载js文件: ...
- 高性能JavaScript-JS脚本加载与执行对性能的影响
在web产品优化准则中,很重要的一条是针对js脚本的加载和执行方式的优化.本篇文章简单描述一下其中的优化准则. 1. 脚本加载优化 1.1 脚本位置对性能的影响 优化页面加载性能的原则之一是将scri ...
- 不得不说的JavaScript异步加载
同步加载的问题 默认的js是同步加载的,这里的“加载”可以理解成是解析.执行,而不是“下载”,在最新版本的浏览器中,浏览器对于代码请求的资源都是瀑布式的加载,而不是阻塞式的,但是js的执行总是阻塞的. ...
随机推荐
- 修改socket缓冲区大小
#include <stdio.h>#include <sys/time.h>#include <sys/types.h>#include <sys/sock ...
- 如何处理好前后端分离的 API 问题(转载自知乎)
9 个月前 API 都搞不好,还怎么当程序员?如果 API 设计只是后台的活,为什么还需要前端工程师. 作为一个程序员,我讨厌那些没有文档的库.我们就好像在操纵一个黑盒一样,预期不了它的正常行为是什么 ...
- Java数据结构和算法(五)二叉排序树(BST)
Java数据结构和算法(五)二叉排序树(BST) 数据结构与算法目录(https://www.cnblogs.com/binarylei/p/10115867.html) 二叉排序树(Binary S ...
- vuex入门文档
如果你在使用 vue.js , 那么我想你可能会对 vue 组件之间的通信感到崩溃 . 我在使用基于 vue.js 2.0 的UI框架 ElementUI 开发网站的时候 , 就遇到了这种问题 : 一 ...
- 让kbmmw 4.8 支持ios 64
随着xe8 的出来,其开始支持IOS 64 的编译了(不支持也没办法,从今年2月开始不支持ios 64 的应用 就不允许入住apple appstore,霸气呀).相信不少同学迫不及待的开始了ios6 ...
- sqlserver将数据库的数据导成excel文档方法
sqlserver将数据库的数据导成excel文档方法 最近公司需要下载uniport的数据跟之前的数据进行对比,所以避免不了需要将数据库的数据导出来,把SQLServer表中的数据导出为Excel文 ...
- hdu-1175(bfs+剪枝)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1175 思路:用bfs,注意要转弯的次数,次数大于两次就跳过. #include<iostream ...
- hadoop学习笔记(六):HBase体系结构和数据模型
1. HBase体系结构 一个完整分布式的HBase的组成示意图如下,后面我们再详细谈其工作原理. 1)Client 包含访问HBase的接口并维护cache来加快对HBase的访问. 2)Zooke ...
- linux将程序扔到后台并获取程序的进程号
我们经常需要写一些执行时间较长的程序,但是如果在程序执行过程中超时了,有许多原因,可能是程序已经挂起了,这时就需要杀死这样的进程,则可以通过如下的命令执行: java -jar TestProcess ...
- 山东省第七届ACM竞赛 J题 Execution of Paladin (题意啊)
题意:鱼人是炉石里的一支强大种族,在探险者协会里,圣骑士有了一张新牌,叫亡者归来,效果是召唤本轮游戏中7个已死鱼人.如果死掉的不足7个,那么召唤的数量就会不足7. 鱼人有很多,下面的4个是: 寒光智者 ...
