原文标题:Slimming javascript applications: An approach for removing unused functions from javascript libraries
原文作者:H.C. Vázquez, A. Bergel, S. Vidal, J.A. Díaz Pace, C. Marcos
原文链接:https://www.sciencedirect.com/science/article/pii/S0950584918302210
发表会议:IST’19
笔记作者:NING@SecQuan
笔记小编:ourren@SecQuan
1 研究介绍
Javascript 应用程序发布时,通常会出现程序与所用库进行捆绑部署,例如当网站存在 Chart.js 制作的嵌入图表时,该网站会包含一个大型的 Chart.budle.js 文件,其是由 Chart.js 及其所使用三方库的源代码构成的,因此这样会导致整个应用的大小、性能受到限制。
本文的目标就是对去除这些依赖项中不必要的源代码(UFF,unused Foreign Function),从而缩小程序大小。具体开发了一种名为 UFF Remover 的工具。
2 主要架构
Identification
首先使用 Browserify 捆绑工具去遍历模块之间的依赖关系,从而构建依赖图,并将没有边的模块在图中进行标记,而存在连接的其他节点构成下一阶段的输入。
Instrumentation
这里通过对 JS 文件解析,进而识别所有函数(这里针对函数声明和函数表达式),并在识别的所有函数前加一条指令,要求指令执行时,将函数是否执行进行记录,从而获取所有需要的函数。
Dynamic Detection
动态运行时,将会吧第二步中所有的内容输出列表 UFF,并提供给开发人员确认。
Removal
当 UFF 被发现并被开发人员确认后,便需要删除,而由于存在动态加载的方式,那么必然会存在误报,这里作者的做法的是 “清空” 而不是 “删除” 函数。通过引入 XMLHttpRequest,当出现误报时,该函数便会从服务器进行加载。但该方法会存在缺点就是需要添加代码和全局变量,同时会延迟加载。
3 实验效果
实验选择了 22 多个流行 JavaScript 应用程序进行测试,要求其满足以下条件:
-
开源 -
可以运行在 Web 浏览器中 -
至少依赖一个库 -
拥有编译和测试信息 -
应用程序功能覆盖率大于 85%(方便函数追踪,需要程序附带的单元测试)
RQ:JS 应用的 UFF 数目如何?去除可以缩减多少源代码?
表 2 展示了本次实验发现、去除、清空的 UFF 数目。可以发现本次针对这些项目共去除了 7021 个 UFF。其中 30.5% (2142) 被完全去除、69.5% (4879) 被清空。然而在整个实验中发现几乎在包中使用的函数,一半来源于依赖的第三方包,函数总数 19,586,其中 10,063 (51.38%) 属于库;同时 bundle LOC(line of code)总数为 336,983,其中 158,695 (47.09%) 属于依赖库。因此分析属于依赖库的函数以删除不需要的函数很重要。
同时图 2 显示了 UFF 识别数目占功能总数的百分比。中位数为 27.56%。UFF 消除数目占功能总数的百分比。中位数为 17.99%。
4 个人思考
-
删减不必要的打包代码是很重要的,能够缩减下载时间,同时可能加快网页端的加载。同时这篇文章所使用的 “清空” 是一个较为聪明的手段,能够帮助代码尽可能地运行起来,而不会缺少部分所需函数。
-
该篇文章应该是 Bloated code 在 JS 服务端代码的早期工作,具有一定的开创意义,同时推动了后面许多文章的前进,包括安全领域、软件工程领域等。
-
该篇文章缺少一些细节描述,支持 ES6 规范,但是可能在一些特殊情况下无法识别 UFF,需要依赖与测试用例来遍历所有功能,同时动态的使用可能会导致一定的效率问题。
安全学术圈招募队友-ing
有兴趣加入学术圈的请联系 secdr#qq.com
原文始发于微信公众号(安全学术圈):精简JS应用:一种去除JavaScript库中未使用函数的方法