高性能JavaScript——1、加载与执行

脚本位置

  • 脚本会阻塞页面谊染
  • 浏览器在解析到<body>标签之前,不会渲染页面的任何
    部分。 把脚本放到页面顶部将会导致明显的延迟
  • 推荐将所有的句口ipt>标签尽可能放到<body>标签的底部,以尽量减少对整个页面下载的影响

组织脚本

  • 控制脚本数量
    <script>标签初始下载时都会阻塞页面植染, 所以减少页面包含的<script>标签数量有助于改善这一情况。内嵌脚本的数量同样也要限制。

无阻塞的脚本

JavaScript倾向于阻止浏览器的某些处理过程,如HTTP请求和用户界面更新,这是开发者所面临的最显著的性能问题。减少JavaScript文件大小并限制HTTP请求数仅仅是创建响应迅速的Web应用的第一步。Web应用的功能越丰富,所需要的JavaScript代码就越多,所以精简源代码并不总是可行。尽管下载单个较大的JavaScript文件只产生一次HTTP请求, 却会锁死浏览器一大段时间。为避免这种情况,你需要向页面中逐步加载JavaScript文件, 这样做在某种程度上来说不会阻塞浏览器。

无阻塞脚本的秘诀在干,在页面加载完成后才加载JavaScript代码。用专业术语来说,这意味着在window对象的load事件触发后再下载脚本。有多种方式可以实现这一效果。

延迟的脚本

HTML 4为<script>标签定义了一个扩展属’性:defer0Defer属性指明本元素所含的脚本不会修改DOM,因此代码能安全地延迟执行。

带有defer属性的<script>标签可以放置在文档的任何位置。对应的JavaScripr文件将在页面解析到<script>标签时开始下载,但并不会执行,直到DOM加载完成(onload事件被触发前)。当一个带有defer属性的JavaScripr文件下载肘,它不会阻塞浏览器的其他进程,因此这类文件可以与页面中的其他资源并行下载。

任何带有defer属性的<script>元素在DOM完成加载之前都不会被执行,无论内嵌或外链脚本都是如此。

动态脚本元素

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

这 种技术的重点在于:无论在何时启动下载,文件的下载和执行过程不会阻塞页面其他进程。 你甚至可以将代码放到页面<head>区域而不会影响页面其他部分(用于下载i主文件的HTTP链接本身的影响除外)。

XMLHttpRequest脚本注入

function loadScript(url){
    let xhr = new XMLHttpRequest()
    xhr.open('get',url,true)
    xhr.onreadystatechange = function(){
        if(xhr.readyState == 4){
            if(xhr.status >= 200 && xhr.status <= 300 || xhr.status == 304){
                let script  = document.createElement('script')
                script.type = 'text/javascript'
                script.text = xhr.responseText
                document.body.appendChild(script)
            }
        }
    }
    xhr.send(null)
}
  • 优点
    • 可以下载JavaScript 代码但不立即执行
    • 同样的代码在所有主流浏览器中无一 例外都能正常工作
  • 局限性
    • JavaScript文件必须与所请求的页面处干相同的域

推荐的无阻塞模式

只需两步:先添加动态加载所需的代码,然后加载初始化页面所需的剩下的代码。因为第一部分的代码尽量精简,甚至可能只包含loadScript() 函数, 它下载执行都很快, 所以不会对页面有太多影响。 一旦初始代码就位, 就用它来加载剩余的JavaScript。 例如:

<script type="text/javascript”src=”loader.js”></script> 
<script type="text/javascript">
loadScript("the-rest.js",function(){ 
	Application.init(); 
}) 
</script> 

把这段加载代码放到</body>闭合标签之前。
这样做有几个好处:

  • 首先,如前文提到,应样做确保了JavaScript执行过程中不会阻碍页面其他内容的显示。
  • 当第二个JavaScript 文件完成下载时,应用所需的所有DOM结构已经创建完毕,并做好了交互的准备,从而避免了需要另一个事件(比如window.onload)来检测页面是否准备好。

小结

管理浏览器中的JavaScript代码是个棘手的问题,因为代码执行过程会阻塞浏览器的其他进程,比如用户界面绘制。每次遇到<script>标签,页面都必须停下来等待代码下载(如果是外链文件)并执行,然后继续处理其他部分。尽管如此,还是有几种方法能减少JavaScript 对性能的影响:

  • </body>闭合标签之前,将所有的<script>标签放到页面底部。这能确保在脚本执行前页面已经完成了渲染。
  • 合并脚本。页面中的<script>标签越少,加载也就越快,响应也更迅速。无论外链文件 还是内嵌脚本都是如此。
  • 有多种无阻塞下载JavaScript的方住:
    • 使用<script>标签的defer属性:
    • 使用动态创建的<script>元素来下载并执行代码:
    • 使用XHR对象下载JavaScript代码井注入页面中。

通过以上策略,可以极大提高那些需要使用大量JavaScript的Web应用的实际性能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值