chrome一直是高性能著称,并且市场占有率也越来越大。同时扩展功能也带来了很大的便利,但也发现用户安装的扩展可能会对页面的性能有影响。本文讨论下chrome扩展如何影响页面的性能以及一些解决办法。
下面我们对照看下没有安装任何扩展的chrome和安装了一些chrome扩展后访问百度新首页的瀑布流。
这是没有安装任何chrome扩展的瀑布流,效果还是非常不错的。
下面我们一些常用的chrome扩展,如:adblock, 音乐电台,截图,lastpass, 代理等,如:
安装了这些扩展后,我们在看下现在的瀑布流是什么样的:
从这个瀑布流里可以看到,中间有很多断的地方,直接导致了加载时间要长很多。
那是为啥装了些扩展后就会页面的加载速度呢?
熟悉chrome扩展开发的同学应该知道,chrome扩展是允许向页面里植入CSS和JS的,并且CSS和JS的植入可能还会引起一些图片等资源的下载。
具体的配置在manifest.json里的Content Scripts,如:
"content_scripts": [
{
"matches": ["http://www.google.com/*"],
"css": ["mystyles.css"],
"js": ["jquery.js", "myscript.js"],
"run_at": "document_end"
}
]
这个表示向 http://www.google.com/ 下所有页面植入mystyles.css和jquery.js和myscript.js这3个文件,并且植入时段是在document_end。run_at有3个属性值,分别对应:
并且一个扩展可以植入多个资源或者脚本,如果扩展安装比较多的话,对页面性能的影响就非常大了。
当然获取用户安装了哪些扩展会侵犯了用户的隐私,但如果知道用户装了哪些扩展,并且知道这些扩展植入了哪些资源,那对分析页面性能的影响帮助还是非常大的。
如果你去chrome webstore里安装扩展的话,细心的你会发现webstore是知道哪些扩展是安装了的。如图:
通过分析页面里的JS发现,是使用了chrome.*的API进行的,这个API就是chrome浏览器暴露给扩展的API。
在https://chrome.google.com/webstore/search/%E7%94%B5%E5%8F%B0页面的Console里,执行chrome,发现chrome有如下的属性和方法:
但在其他非chrome.google.com的域名下执行chrome,只有下面的属性和方法:
也就是说chrome.*下的很多API只给chrome.google.com开了白名单。
那有没有其他办法拿到用户装了哪些扩展呢?
波兰安全研究员Krzysztof Kotowicz通过一个简单粗暴可依赖的办法,只要很短的JS代码就能知道用户安装了哪些扩展,见测试DEMO页,代码如下:
var detect = function(base, if_installed, if_not_installed) {
var s = document.createElement('script');
s.onerror = if_not_installed;
s.onload = if_installed;
document.body.appendChild(s);
s.src = base + '/manifest.json';
}
var log = function(msg) {
document.getElementById('log').value += '[*] ' + msg + '\n';
}
function logme(i, id) {
return function() {
log('Detected addon: ' + i + ' (' + id + ')');
}
}
window.onload = function() {
var xhr = new XMLHttpRequest();
xhr.open('GET', 'addons.json', false);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
var addons = JSON.parse(xhr.responseText);
for (var i in addons) {
if (addons.hasOwnProperty(i)) {
detect('chrome-extension://' + i,logme(addons[i], i));
}
}
}
}
xhr.send(null);
}
实现原理看懂了其实比较简单,通过下面几个步骤: 1、手工维护一个manifest.json,这个文件列举了webstore下扩展列表。当然webstore如果有扩展添加的话,需要手工更新这个列表
2、循环执行manifest.json这个列表,因为每个扩展都有manifest.json这个文件,所以通过script方法加载这个manifest.json文件,地址为:chrome-extention://扩展id/manifest.json
3、如果这个manifest.json存在,则表明安装了这个扩展
这种方式目前一个比较大的问题的是因为要循环那个大列表,所以有点耗时。当然这样方式chrome浏览器后续可能会fixed掉。
还有一种方式就是开发一个扩展,专门用来测试用户安装了哪些插件,以及这些插件有没有植入css和JS,并且植入的CSS和JS是否对当前页面有影响。当然这种方式需要用户的配合才能进行。
如果你有其他更好的方式,欢迎一起讨论。
Copyright© 2013-2020
All Rights Reserved 京ICP备2023019179号-8