【译】延迟加载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,但是有时候出于性能考虑,我们会写一些异步的代码(代替同步代码).思考这样一个场 ...
随机推荐
- phpcms 细节
Phpcms V9采用if语句判断当前栏目高亮.判断分类信息是否过期 10月05, 2013 by SJY 在用PC V9建站的时候,很多朋友会想到Phpcms V9判定当前栏目,让当前栏目高亮的功能 ...
- hibernate---树状映射
总公司--分公司1, 分公司2 分公司1: 分公司1下部门1, 分公司1下部门2 分公司2: Org.java: package com.bjsxt.hibernate; import java.ut ...
- HDU 2412 Party at Hali-Bula
树形DP水题.判断取法是否唯一,dp的时候记录一下每个状态从下面的子节点推导过来的时候是否唯一即可. #include<cstdio> #include<cstring> #i ...
- mousewheel,DOMMouseScroll判断滚轮滚动方向
firefox使用DOMMouseScroll,其他浏览器使用mousewheel 首先绑定一个滚动事件 //firefox使用DOMMouseScroll,其他浏览器使用mousewheel$(do ...
- Charles从入门到精通
Charles 从入门到精通 发表于 2015-11-14 12:00 文章目录 1. 目录 2. 简介 3. 安装 Charles 4. 将 Charles 设置成系统代理 5. Charles 主 ...
- (简单) HUST 1017 Exact cover , DLX+精确覆盖。
Description There is an N*M matrix with only 0s and 1s, (1 <= N,M <= 1000). An exact cover is ...
- truetype技术和矢量字库的技术原理及实现(转)
源:truetype技术和矢量字库的技术原理及实现 广泛汉字矢量字库(HZKSLxxJ)格式 在矢量字库中,每个汉字都是以128 X 128点阵制成矢量数据.每个汉字 ...
- 火狐上的一个post提交工具(主要用于测试接口时候)
添加的过程 安装完后,就可以在下图上,看到一个poster 点击poster就可以看到下图 图中红线圈好的,是必须要填写的 Url是访问路径 Name是参数名称 Value是参数值 需要注意一点的是: ...
- STM8时钟系统详解
就我个人看来,研究一块单片机,分为新手和老手两种模式,新人迫切的想先用,你得告诉他们怎么样最快的写出一个能跑起来的程序,告诉他们每一个外设的使用方式,老手不同,用的单片机多了外设对于他们而言没太多好奇 ...
- iOS越狱包 分类: ios相关 app相关 2015-06-10 10:53 152人阅读 评论(0) 收藏
编译完了的程序是xxx.app文件夹,我们需要制作成ipa安装包,方便安装 找一个不大于500*500的png图片(程序icon图标即可),改名为:iTunesArtwork,注意不能有后缀名. 建立 ...