【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的执行总是阻塞的. ...
随机推荐
- FTP 搭建
FTP 搭建 FTP 是 File Transfer Protocol(文件传输协议)的英文简称,它工作在 0SI 模型的第七层,TCP 模型的第四屋上,即应用层. 一.FTP 简介 FTP 会话时包 ...
- 共享内存system v(未编译)
#include <stdio.h> #include <string.h> #include <errno.h> #include <unistd.h> ...
- 编译 link
--generating dsym file change the appropriate one from 'DWARF with dSYM file' to just 'DWARF',This s ...
- 2018.09.24 bzoj4977: [[Lydsy1708月赛]跳伞求生(贪心+线段树)
传送门 线段树好题. 这题一看我就想贪心. 先把a,b数组排序. 然后我们选择a数组中最大的b个数(不足b个就选a个数),分别贪心出在b数组中可以获得的最大贡献. 这时可以用线段树优化. 然后交上去只 ...
- python面向对象-1方法、构造函数
类是指:描述一种事物的定义,是个抽象的概念 实例指:该种事物的一个具体的个体,是具体的东西 打个比方: “人”是一个类.“张三”是人类的一个具体例子 在编程时也是同样的道理,你先自己定义一个“类”,当 ...
- 2) 下载Maven
http://maven.apache.org/ http://maven.apache.org/download.cgi Maven 3.3.3 (Binary tar.gz) Maven 3.3. ...
- _variant_t与其他数据类型的转换
转自:http://kuaixingdong.blog.hexun.com/29627840_d.html 我们先看看COM所支持的一些类型的基本类: (微软提供,在comdef.h中定义) 在COM ...
- Hdu1728 逃离迷宫 2017-01-17 10:56 81人阅读 评论(0) 收藏
逃离迷宫 Time Limit : 1000/1000ms (Java/Other) Memory Limit : 32768/32768K (Java/Other) Total Submissi ...
- Hibernate多对多双向关联需要注意的问题(实例说话)
以Student和Course为例,一个学生可以选多门课程,一门课程也可以被多个学生选取: 持久化类Student: package bean; import java.util.Set; publi ...
- 【TypeScript】TypeScript 学习 3——类
在 EcmaScript 6 中,我们将会拥有原生的类,而不是像现在通过原型链来实现.使用 TypeScript 我们能提前体验这一特性. 首先来看看一个简单的例子: class Greeter { ...
