当前位置: 首页 > news >正文

延迟脚本的方式

昨晚‘今日头条’笔试题中遇到这道题,今天专门查了一下。

从 IE 8、Firefox 3.5、Safari 4 和 Chrome 2 开始都允许并行下载 JavaScript 文件。

<script>标签在下载外部资源时不会阻塞其他<script>标签。遗憾的是,JavaScript 下载过程仍然会阻塞其他资源的下载,比如样式文件和图片。尽管脚本的下载过程不会互相影响,但页面仍然必须等待所有 JavaScript 代码下载并执行完成才能继续。

实现延迟加载的方式有:

方式一:标签放在底部

<script>节点放置在</body>之前,这样js脚本会在页面显示出来之后再加载。

方式二:Defer和Async属性

使用script标签的deferasync属性

Defer属性

defer是在html4.0中定义的

html5规范要求脚本按照出现的顺序执行,对应的js文件在页面解析到<script>标签时开始下载,但不会执行,直到DOM加载完成,即onload事件触发前才会执行

当一个带有 defer 属性的 JavaScript 文件下载时,它不会阻塞浏览器的其他进程,因此这类文件可以与其他资源文件一起并行下载。

<script type="text/javascript" defer="defer" src="example.js">
<script type="text/javascript" defer="defer" src="example.js">

缺点:并不是所有浏览器支持该属性

async属性

async是html5新增的属性,IE10和其他浏览器都支持该属性

同defer一样,不会阻塞其余资源的加载,也不会影响页面的加载,但js一旦加载好了就会执行,所以很有可能不是按照原本的顺序来执行

方式三:动态脚本元素

DOM动态创建<script>

var script = document.createElement('script');
script.type = "text/javascript";
script.src = "script.js";
document.getElementByTagName('head')[0].appendChild(script);

可以监听脚本是否加载成功

script.onload = function(){
    alert('script loaded!');
};
/*IE中的监听方式不一样*/
script.onreadystatechange = function(){
    if(script.readyState == 'load' || script.readyState == 'complete'){
        script.onreadystatechange = null;
        alert('script loaded');
    }
};

方法四:使用XMLHttpRequest(XHR)

var xhr = new XMLHttpRequest();
xhr.open('get', 'script.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代码;
同样的代码在所有现代浏览器中都可以正常运行。

缺点:
javasript文件必须和页面放置在同一个域中,不能从CDN下载,所以大型网页通常都不采取XHR脚本注入技术。

总结

减少 JavaScript 对性能的影响有以下几种方法:

将所有的<script>标签放到页面底部,也就是</body>闭合标签之前,这能确保在脚本执行前页面已经完成了渲染。

尽可能地合并脚本。页面中的<script>标签越少,加载也就越快,响应也越迅速。无论是外链脚本还是内嵌脚本都是如此。

采用无阻塞下载 JavaScript 脚本的方法:
使用<script>标签的 defer 属性(仅适用于 IE 和 Firefox 3.5 以上版本);
使用动态创建的<script>元素来下载并执行代码;
使用 XHR 对象下载 JavaScript 代码并注入页面中。

相关文章:

  • shell中变量的查看和删除
  • 算法分析-分治 归并排序,递归插入排序,二分查找
  • mysql搭建及数据迁移教程
  • mysql 5.7 zip 文件在 windows下的安装
  • linux_group总结
  • scrapy 学习笔记
  • 关于 jquery 选择器的 深入理解 -1
  • c++ vector 用法
  • LD_LIBRARY_PATH的设定
  • 关于分布式事务
  • Oracle update 日期
  • some useful linux commands
  • Oracle RacOneNode 修改 cluster name步骤
  • 论文笔记之:A CNN Cascade for Landmark Guided Semantic Part Segmentation
  • C#文件相同性判断
  • 【个人向】《HTTP图解》阅后小结
  • Fastjson的基本使用方法大全
  • Flannel解读
  • Netty 框架总结「ChannelHandler 及 EventLoop」
  • vue2.0开发聊天程序(四) 完整体验一次Vue开发(下)
  • 阿里云Kubernetes容器服务上体验Knative
  • 测试开发系类之接口自动化测试
  • 服务器从安装到部署全过程(二)
  • 猴子数据域名防封接口降低小说被封的风险
  • 少走弯路,给Java 1~5 年程序员的建议
  • 树莓派 - 使用须知
  • 数据仓库的几种建模方法
  • 要让cordova项目适配iphoneX + ios11.4,总共要几步?三步
  • 用jQuery怎么做到前后端分离
  • 大数据全解:定义、价值及挑战
  • # Swust 12th acm 邀请赛# [ A ] A+B problem [题解]
  • #gStore-weekly | gStore最新版本1.0之三角形计数函数的使用
  • #Lua:Lua调用C++生成的DLL库
  • (附源码)流浪动物保护平台的设计与实现 毕业设计 161154
  • (六)c52学习之旅-独立按键
  • (论文阅读26/100)Weakly-supervised learning with convolutional neural networks
  • (转)iOS字体
  • (转载)深入super,看Python如何解决钻石继承难题
  • .describe() python_Python-Win32com-Excel
  • .net core webapi 部署iis_一键部署VS插件:让.NET开发者更幸福
  • .Net FrameWork总结
  • .NET MAUI学习笔记——2.构建第一个程序_初级篇
  • .NET 中什么样的类是可使用 await 异步等待的?
  • @软考考生,这份软考高分攻略你须知道
  • [ vulhub漏洞复现篇 ] struts2远程代码执行漏洞 S2-005 (CVE-2010-1870)
  • []AT 指令 收发短信和GPRS上网 SIM508/548
  • [2018/11/18] Java数据结构(2) 简单排序 冒泡排序 选择排序 插入排序
  • [ai笔记4] 将AI工具场景化,应用于生活和工作
  • [Android]一个简单使用Handler做Timer的例子
  • [BSGS算法]纯水斐波那契数列
  • [C++]类和对象(中)
  • [HarmonyOS]第一课:从简单的页面开始
  • [HDOJ4911]Inversion
  • [IDF]摩斯密码
  • [iOS]中字体样式设置 API