chrome扩展对页面性能的影响

1109次阅读  |  发布于5年以前

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