当前位置:Gxlcms > html代码 > 最佳实践:非阻塞脚本载入_html/css_WEB-ITnose

最佳实践:非阻塞脚本载入_html/css_WEB-ITnose

时间:2021-07-01 10:21:17 帮助过:88人阅读

当今Web页面和脚本已经越来越复杂,页面性能有时会变得很差。 这常常被误解为网络或浏览器的问题,其实前端技术对页面性能有着非常显著的影响。 前端对页面性能的影响也是多方面的:

  • 脚本/样式文件的划分会影响浏览器缓存效率。
  • 频繁的DOM操作会占用大量CPU资源。
  • 资源链接的先后顺序也会影响页面渲染速度。
  • 同步的网络请求会使页面停止响应。

本文将探讨不同的脚本载入方式对页面性能的影响, 包括『浏览器忙提示』、『页面停止渲染』、『光标停止响应』等。 最终给出无阻塞脚本载入的最佳实践。

什么是脚本阻塞

本文的主题是无阻塞脚本载入技术,那么什么是脚本阻塞呢?

在 Web性能优化:prefetch, prerender 一文中提到, 浏览器在获取资源时会经过DNS解析、建立连接、下载文件、渲染页面等过程。 浏览器只会同时下载3-5个脚本,然后顺序执行它们。 并且在下载和执行过程中,页面会停止渲染和响应(也就是我们说的页面卡死)。

性能最差的情形是某个脚本下载超时,后面的脚本和样式都会被阻塞很长时间, 浏览器的图标会一直处于忙的状态。 如果这个脚本出现在HTML HEAD标签中,阻塞过程中整个页面都将是空白,用户体验极差。

为了防止脚本阻塞,我们来探讨非阻塞的脚本载入方式。 采用这种脚本在如方式时,浏览器(以Chrome为例)不会显示忙指示器图标, 页面也不会停止响应。

XHR

缺点:不能跨域,容易被劫持

我们知道 XHR 可以用来执行异步的网络请求,XHR Eval方法的原理便是通过XHR下载整个脚本,通过 eval() 函数来执行这个脚本。

$.get('/path/to/sth.js')    .done(function(src){        eval(src);    });

因为 XHR 的下载过程是异步的,所以这个过程中浏览器图标不会显示『忙提示』。 JS的执行时间很短暂,可以认为页面始终不会停止响应。 XHR 有跨域问题,因此该方法只适用于资源位于同一域名的情况(或者开启CORS响应头字段)。

我们知道 eval() 方法是不安全的,除了使用 eval() 方法,我们还可以创建一个

浏览器的同源策略也不允许Iframe的JS访问跨域的父页面,因此该方法也不能跨域。 同时浏览器需要为Iframe创建完整的一套DOM并进行渲染,开销较大。

DOM Element

优点:可跨域

可能读者也想到了,直接在页面里插入一个

这是比较流行的解决方案。

Defer/Async

优点:可以灵活控制优先页面渲染还是优先执行脚本。

缺点:Opera浏览器尚不支持。

既然在脚本执行时我们插入新的

这两者有什么区别呢?请看:

图片来自 peter.sh 。

正常执行

在下载和执行脚本时HTML停止解析

defer执行

在下载脚本时HTML仍然在解析,HTML解析完成后再执行脚本。延迟执行不会阻塞渲染,额外的好处是脚本执行时页面已经渲染结束。

async执行

在下载脚本时HTML仍然在解析,下载完成后暂停HTML解析立即执行脚本。

人气教程排行