【译】延迟加载JavaScript
【译】延迟加载JavaScript
看到一个微信面试题引发的血案 --[译] 什么阻塞了 DOM?中提到的一篇文章,于是决定看下其博客内容,同时翻译下来留作笔记,因英文有限,如有不足之处,欢迎指出。同时,请给它五分钟。
原文地址:https://varvy.com/pagespeed/defer-loading-javascript.html
作者:Patrick Sexton
如何延迟加载JavaScript
真正的延迟加载JavaScript意味着:在页面内容已经完全加载完成之后才开始加载或解析JavaScript(这也就是说JavaScript不能影响页面速度或关键渲染路径)。
- 使用“onload”事件来调用外部JavaScript资源
- 外部JavaScript资源不能在页面内容加载完前加载
- 外部JavaScript资源在内容加载完成之后才开始运行并影响页面
解释
网络上的焦点往往是人们为了找到一种解决方案而抓狂,JavaScript的延迟加载便是焦点其中之一。
许多人说”只要使用defer就可以了“、”只要使用async就可以了“,或者说”只要把你的JavaScript放到页面最底部就可以了“,但是这些都没有解决问题 —— 让页面完全加载完成然后(只能在完全加载之后)加载外部JS。这些方式也不会让你通过从Google页面速度工具中获取的”延迟加载JavaScript“ 警告(这一点译者有些疑问,因为我在测试的时候发现上面的三个方法是可以去掉这个警告的)。
这个解决方案将会解答。
调用外部JavaScript文件的脚本
这段代码放到HTML文档的</body>
标签之前(靠近HTML文档底部)。外部脚本的名称为defer.js
。
<script type="text/javascript">
function downloadJSAtOnload() {
var element = document.createElement("script");
element.src = "defer.js";
document.body.appendChild( element );
}
if ( window.addEventListener ) {
window.addEventListener( "load", downloadJSAtOnload, false );
} else if ( window.attachEvent ) {
window.attachEvent( "onload", downloadJSAtOnload );
} else {
window.onload = downloadJSAtOnload;
}
</script>
这段脚本做了什么?
这段代码说等文档完全加载完,然后加载外部文件”defer.js“。
详细说明
- 1、复制上面的代码
- 2、把代码粘贴到你的HTML文档中,
</body>
标签之前 - 3、把
defer.js
改成你外部文件的名字 - 4、确保到你文件的路径是正确的。例如:如果你使用”defer.js“,那么”defer.js“文件必须和你的HTML文件在相同文件夹下
你可以用它来干嘛(或不能干嘛)
这段代码在你的页面还没完全加载完成之前不会加载外链文件。你应该把你的JavaScript分成两组,一组是页面需要加载的,另一组是做页面加载后要做的事情(比如寻找click事件或其他事情)。可以接受等待并且一直到页面加载后才加载的JavaScript应该都被放到一个外部文件中调用。
例如,在该页面中我使用了上述的脚本来延迟加载谷歌统计、Viglink、以及底部的Google plus头像。我没有理由在页面初始时加载这些文件,因为这些文件和我上述的内容是不相关的,是非必须加载的。也许在你的页面上也会有相同类型的东西,你会在展示给你的用户内容之前让用户等待加载这些资源吗?
为什么其他方式不行?
内联、把脚本放到最底部、使用defer
或者async
这些方法都没有完成先让页面加载,然后在加载JS的目标,并且这些方式也确实不通用以及跨浏览器。
为什么这很重要?
这是因为Google把页面的加载速度作为排名的一个因素,也因为用户想要更快的加载页面。这对你的移动端SEO也大有益处。Google是从它被调用时开始到页面初始化加载完成来测量你的页面加载速度。这也意味着你需要让页面的load
事件尽可能快的完成。谷歌根据网页首页加载时间评估你的网页(并且不要忘了,用户正在等待页面加载)。
Google积极的宣传与推荐prioritizing above the fold content(屏幕内容优先)。所以让屏幕外的任何资源(js、css、images等等)放到主要渲染路径之外是值得努力的。如果这会让你的用户开心,让Google开心,何乐而不为呢。
使用示例
我创建了一个页面,点击这里,你会看到,在这里面我用到了上述代码段。
测试示例文件
好吧,为了举例说明,我写了一些测试页面供你测试。每一个页面做了相同的事情,一个纯HTML页面使用了一个脚本,脚本的内容是等待两秒输出”hello world“。你可以测试这些页面并且看到只有一种方式立即展示出了内容(页面加载时间没有包括这两秒的等待)。
关键点
最最关键的点是要尽可能快的把内容呈现给用户。We have not been doing that with how we have treated our javascript.用户必须要看到他们的内容,因为一些脚本做的事情在可视内容之下。不管你的页面底部有多酷,如果用户从不滚动到页面底部,那么你就毫无原因来加载脚本让页面底部变酷。
工具
使用javascript usage tool来测试你的页面中JavaScript是如何使用的。
翻译结束。
补充扩展
1、defer与async
这两个属性都可以页面优化的目的,但有什么不同呢?一个图即可解答:
2、Below the Fold
根据wordstream中的定义:
Below the fold
是指网页中只有滚动才可见的区域。
Above the Fold
指不需滚动页面就可见的内容区域。
一般而言,不需滚动就展示在屏幕中的内容会接受更多的注意力,需要滚动才可见的内容受到较低的关注。fold
观点来自新闻出版业。
【译】延迟加载JavaScript的更多相关文章
- 「译」JavaScript 的怪癖 1:隐式类型转换
原文:JavaScript quirk 1: implicit conversion of values 译文:「译」JavaScript 的怪癖 1:隐式类型转换 译者:justjavac 零:提要 ...
- 【译】JavaScript 开发者年度调查报告
截至目前有超过了 5000 人参与了(该次调查),准确的说是 5350 人.我迫不及待的想要和大家分享一下这次调查的细节.在分享之前我想要感谢参与调查的每一个人.这是 JavaScript 社区一个伟 ...
- (译)JavaScript内存泄露
译者前言 原文地址:Memory leaks 最近简单了解了下JavaScript的闭包和垃圾回收机制(GC),这中间也不得不接触内存泄露这个概念.然后不小心找到了这篇文章,看下来后理解了不少东西,于 ...
- [译]理解Javascript的异步等待
原文链接: https://ponyfoo.com/articles/understanding-javascript-async-await 作者: Nicolás Bevacqua 目前async ...
- 【转】【译】JavaScript魔法揭秘--探索当前流行框架中部分功能的处理机制
推荐语: 今天推荐一篇华为同事的同事翻译的一篇文章,推荐的主要原因是作为一个华为员工居然晚上还能写文章,由不得小钗不佩服!!! 其中的jQuery.angular.react皆是十分优秀的框架,各有特 ...
- 【简译】JavaScript闭包导致的闭合变量问题以及解决方法
本文是翻译此文 预先阅读此文:闭合循环变量时被认为有害的(closing over the loop variable considered harmful) JavaScript也有同样的问题.考虑 ...
- 【译】Javascript中的数据类型
这篇文章通过四种方式获取Javascript中的数据类型:通过隐藏的内置[[Class]]属性:通过typeof运算符:通过instanceof运算符:通过函数Array.isArray().我们也会 ...
- (译) 《Javascript 24条最佳实践》
(摘录) <Javascript 24条最佳实践> 自己一直偏向于实用主义,不是学院派,不是学究派,只讲究把东西能够很好的做出来,但经过一段时间的开发工作当自己总结出来一些东西时,觉得挺有 ...
- 【译】JavaScript Promise API
原文地址:JavaScript Promise API 在 JavaScript 中,同步的代码更容易书写和 debug,但是有时候出于性能考虑,我们会写一些异步的代码(代替同步代码).思考这样一个场 ...
随机推荐
- Android音频系统之AudioPolicyService
地址:http://blog.csdn.net/edmond999/article/details/18599327 1.1 AudioPolicy Service 在AudioFlinger小节,我 ...
- The 2014 ACMICPC Asia Regional Beijing Online
[A]极角排序+树状数组 [B]计算几何,凸包(队友已出) [C]-_-///不懂 [D]数论,概率密度 [E]图的连通性+Floyed传递闭包+bitset [F]贪心 [G]签到题 [H]区间维护 ...
- (简单) HDU 2612 Find a way,BFS。
Description Pass a year learning in Hangzhou, yifenfei arrival hometown Ningbo at finally. Leave Nin ...
- MAP--复杂map结构的构造
我的关键结构比如 struct{ int a; int b; int c; }s: 因为这三个数据是基本信息,可以唯一区别一个设备.拿这样一个数据结构作为索引就能找到每个设备. ...
- 【亲测】Python:解决方案:Python Version 2.7 required, which was not found in the registry
好久不更新随笔了,今天因为数据可视化作业,想抓取一些人人网好友关系数据,于是开始尝试python,用到numpy模块,安装的时候提示: 'Python Version 2.7 required, wh ...
- Http协议与TCP协议理解
TCP协议对应于传输层,而HTTP协议对应于应用层,从本质上来说,二者没有可比性.Http协议是建立在TCP协议基础之上的,当浏览器需要从服务器获取网页数据的时候,会发出一次Http请求.Http会通 ...
- jQuery.extend({...})分析
作者:zccst 看一下是如何写的 jQuery.extend({ prop:"" method:function(){} }); 可以看出,这些方法是jQuery的静态属性和方法 ...
- 为什么无线信号(RSSI)是负值(转)
源:为什么无线信号(RSSI)是负值 为什么无线信号(RSSI)是负值 答:其实归根到底为什么接收的无线信号是负值,这样子是不是容易理解多了.因为无线信号多为mW级别,所以对它进行了极化,转化为dBm ...
- ajax常用写法
$.ajax( url,{ type:"post", data:{},}) .done(function() { alert("success"); }) .f ...
- 最小化安装Linux记录
挂载点: /boot 挂载点 100M swap 交换分区 / 根分区 最小化安装: 基本--基本.兼容库.调试工具 开发--开发工具 修改hostname 永久设置:/etc/sysconfig/ ...