【译】使用 Script-Streaming 提升页面加载性能

script-streaming 是什么?

加载 JavaScript 算是 web 性能最严重的瓶颈之一,尤其在低端 CPU 上情况更糟糕。加载 JavaScript 的性能损耗不仅包括从服务器上下载数据的网络时间,也包括文件解压、解析、编译,以及执行 JavaScript 的时间。为了更好的用户体验,web 页面大量的 JavaScript 代码数量持续地增长,页面加载变得越来越慢。浏览器社区一直在开发很多优化措施来提升 JavaScript 加载速度,比如将解析 JavaScript 文件和下载过程并行化(在此之前,浏览器会等待 JavaScript 文件完全下载后才会在渲染主线程上进行解析)。这项优化措施就是 script-streaming,它在 Chrome v41 上被引入。Google 声称 script-streaming 能够将页面加载速度提升 10%,因为大型 JavaScript 文件会边下载边解析,这可以减少数百毫秒的页面加载时间。

Script-streaming 是为加速 JavaScript 解析而做的一项巨大的优化。然而,Chrome 针对 JavaScript 文件启用 script-streaming 还有一些限制。

  • 首先,下载的 JavaScript 文件大小至少 30KB。这个尺寸限制确保了只有大型 JS 文件能够通过 script-streaming 解析,因为相比于较小的 JavaScript 文件,并行下载和解析大型 JavaScript 文件的收益最大。

  • 其次,目前 Chrome 在 script-streaming 的实现上,同一时刻 script-streaming 只能应用到一个 JavaScript 文件上。这是由于 Chrome 对于 script-streaming 只使用了单线程。既然这个线程忙于解析某个 JavaScript 文件,那么其他 JavaScript 文件就必须在主线程下载完成后,才能进行解析。

web 开发者如何利用 script-streaming ?

script-streaming 加速了 JavaScript 的解析。作为一个 web 开发者,你不必为了在页面上启用 script-streaming 做任何事情。然而,script-streaming 还是有一些限制的,这些限制只存在于 Chrome,它们是由于 Chrome 的实现造成的。具体来说,当大型 JavaScript 文件下载完成,script-streaming 线程不保证一定可用。同样地,页面并行下载多个大型 JavaScript 文件,只有一个文件能够通过 script-streaming 解析。并且,某些情况下,script-streaming 可能解析较小的脚本文件,而较大的脚本只能等待 script-streaming 线程可用,或者在完成下载后,由主线程进行解析。

开发者可以使用 performance 开发者工具来研究 script-streaming 是否被用于解析大型 JavaScript 文件,因为这项技术可以显著提升页面性能。下图是 www.akamai.com 在 performance 面板上的一个截图,脚本就是被红框里的 ScriptStreamer 线程解析的。

[图片上传失败...(image-229024-1538213191690)]

提升解析速度的两种方法

我做了一些研究,为了启用 script-streaming,可以解析较小的 JavaScript 文件(仍然大于 30KB),这样在解析相对较大的 JavaScript 文件时,保持线程是可用的。理论上,可以在大型 JavaScript 文件上发送一个 HTTP 响应头,告诉浏览器在具有这种响应头的文件上应用 script-streaming。然而,这个方法要求主流浏览器作出调整,并且能让 script-streaming 利用多线程,而不仅仅是单线程。值得注意的是,目前 使用多个 script-streaming 线程在 Chrome 团队内部依然是 TODO 状态。

一个比较实用的,执行起来简单得多,并且不需要浏览器改变的技巧,是重新排序 HTML 中那些加载静态资源 URL 的 <script> 标签的位置,以让大的 JavaScript 文件在较小(仍然大于 30KB)文件之前下载。当 script-streaming 可用时,此方法会强制解析大型 JavaScript 文件。重新排序 <script> 标签在 HTML 中的位置,可能存在潜在风险。因为为了保持页面的功能和 UI,一些 JavaScript 必须按顺序执行。因此,在重新排序时必须要谨慎。重新排序那些带上=有 async 或者 defer 属性的 <script> 标签会保险一些,因为这些脚本执行并不依赖于执行顺序。由于脚本重排序伴随着种种限制,这项实验性的方法将只在指定的网站上生效。除了脚本重排序之外,我加进来的另一个方法是,将多个大型 JavaScript 文件并行下载,让它们竞争 script-streaming 线程。我将所有这样的 JavaScript 文件串联起来,目的是让他们都可以实现边下载边解析。

实验结果

我做了一些实验,去衡量上述两个方法在多个设备上的页面加载时间,包括 MacBook Pro,一个低端移动设备(Motorola Moto E),和一个高端移动设备(Motorola Moto G)。性能数据通过一个私有网页测试实例.收集。在两个手动修改的网站(“Page A” 和 “Page B”,详情见下表)集合上,观察到在多个移动设备和 MacBook Pro 上,对于中等规模的页面有多达 6.2% 的页面加载时间提升。这些性能提升要归功于 JavaScript 解析和下载的并行化。

Page \资源数 页面大小 #JavaScript 资源数 ** JavaScript 总大小**
A 41 2.7 MB 12 1.3 MB
B 95 2.2 MB 19 1.1 MB

MacBook Pro 上的性能

图 1 和图 2 展示了在一台 MacBook Pro 上,两个测试页面加载时间的 CDF 分布。页面 A 上,重新排序 script 标签在 HTML 中的位置的页面加载时间减少了 6.2%。页面 B 上,加载重新排序的 scrip 标签的页面加载时间减少了 4.5%。
[图片上传失败...(image-cc044e-1538213191690)]

Motorola Moto E 上的性能

正如下图所示,重排序 script 标签的页面 A 的加载时间减少了 4.3%。

页面 B(没有示例图)上没有出现更快的加载速度,这可能是因为在 Moto E 设备上,当移动版页面 A 加载时, script-streaming 线程被占用了。
[图片上传失败...(image-dccbb4-1538213191690)]

Motorola Moto G 上的性能

如下图所示,重排序 script 标签的页面 A 的加载时间减少了 3.5%。

页面 B 上,中等规模页面的加载时间减少了 1.9%。
[图片上传失败...(image-bf44d5-1538213191690)]

总结

本文描述的实验性工作举例说明了相比默认的解析,通过 script-streaming 解析较大 JavaScript 文件带来的好处。实验包含重排序 HTML 中的 <script> 标签,以及串联多个大型 JavaScript 文件,让它们并行下载,以允许相对较大的文件能够通过 script-streaming 解析。实验结果显示,在 MacBook Pro 和两个低端和高端的移动设备上,对于中等大小的页面,加载速度有多达 6% 的提升。


原文作者: Utkarsh Goel

译者: 熊贤仁

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,968评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,601评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,220评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,416评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,425评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,144评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,432评论 3 401
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,088评论 0 261
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,586评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,028评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,137评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,783评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,343评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,333评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,559评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,595评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,901评论 2 345

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,522评论 25 707
  • 用两张图告诉你,为什么你的 App 会卡顿? - Android - 掘金 Cover 有什么料? 从这篇文章中你...
    hw1212阅读 12,693评论 2 59
  • 1.ios高性能编程 (1).内层 最小的内层平均值和峰值(2).耗电量 高效的算法和数据结构(3).初始化时...
    欧辰_OSR阅读 29,321评论 8 265
  • 56【反思】月度检视是一个好习惯 如何过一天,就是如何过一生。 没有反思的人生不值得过。 月度检视就是要坚持纪录,...
    依盈阅读 61评论 0 0
  • 昨晚彭彭帮爱人涂指甲油,我泡脚看着她们。想起之前帮宛芯画眉,啊哈哈。 而我在泡脚的同时也败了100多,悦诗风吟的眉...
    大大大未至阅读 107评论 0 0