当前位置: 首页 > 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#文件相同性判断
  • $translatePartialLoader加载失败及解决方式
  • 【跃迁之路】【444天】程序员高效学习方法论探索系列(实验阶段201-2018.04.25)...
  • Android优雅地处理按钮重复点击
  • ES6, React, Redux, Webpack写的一个爬 GitHub 的网页
  • gcc介绍及安装
  • JavaScript 是如何工作的:WebRTC 和对等网络的机制!
  • Koa2 之文件上传下载
  • Node + FFmpeg 实现Canvas动画导出视频
  • Python中eval与exec的使用及区别
  • uva 10370 Above Average
  • V4L2视频输入框架概述
  • VUE es6技巧写法(持续更新中~~~)
  • 基于游标的分页接口实现
  • 什么是Javascript函数节流?
  • Linux权限管理(week1_day5)--技术流ken
  • ​一些不规范的GTID使用场景
  • # 再次尝试 连接失败_无线WiFi无法连接到网络怎么办【解决方法】
  • #vue3 实现前端下载excel文件模板功能
  • (¥1011)-(一千零一拾一元整)输出
  • (分类)KNN算法- 参数调优
  • (六)vue-router+UI组件库
  • (四)图像的%2线性拉伸
  • (转)shell中括号的特殊用法 linux if多条件判断
  • ******IT公司面试题汇总+优秀技术博客汇总
  • .NET BackgroundWorker
  • .NET delegate 委托 、 Event 事件,接口回调
  • .net 流——流的类型体系简单介绍
  • .NET/C# 在 64 位进程中读取 32 位进程重定向后的注册表
  • .net6解除文件上传限制。Multipart body length limit 16384 exceeded
  • .NET开发不可不知、不可不用的辅助类(三)(报表导出---终结版)
  • .net实现客户区延伸至至非客户区
  • .NET中的Exception处理(C#)
  • @hook扩展分析
  • @JsonSerialize注解的使用
  • @RequestParam,@RequestBody和@PathVariable 区别
  • [\u4e00-\u9fa5] //匹配中文字符
  • [20190401]关于semtimedop函数调用.txt
  • [ASP]青辰网络考试管理系统NES X3.5
  • [bzoj1324]Exca王者之剑_最小割
  • [C#] 如何调用Python脚本程序