chrome扩展 – 在使用内容脚本时减少加载时间的最佳方法

我正在构建一个镀铬扩展,它应该通过超过12,000个值的数组进行查看,并将其与网页p标记进行比较,如果数组中的值位于p标记内,则应突出显示文本,并且当它hover时应该显示一些信息。 所以,我很容易使用内容脚本,但使用"run_at": "document_end"使网页加载速度慢3倍,加载扩展程序几乎多10秒。 显然不理想。

这是我的内容脚本代码:

 jQuery(document).ready(function($) { var $all_p = $("p"); $.each(arrayObj, function(key, value) { $all_p.highlight(key, {caseSensitive: true, className: 'highlight-882312', wordsOnly:true }); }); $('.highlight-882312').each(function() { var currentKey = $(this).text(); console.log(currentKey); //Create tooltip on hover. Tipped.create(this, "", { skin: "white", hook: 'rightmiddle', maxWidth: 306, maxHeight: 365, background: '#eee', }); }); }); 

无论如何,这对我来说太慢了,但我仍然想构建扩展,所以我想我可以将所有p标签的数组发送到我的后台/弹出窗口,这样在后台/弹出窗口中它会循环查找关键字然后显示弹出窗口内匹配的关键字,并将消息发送回内容脚本,其中关键字匹配,以便突出显示。 这会减少加载时间吗? 对于我的问题,这是一个很好的解决方案,因为额外的10秒加载时间根本不理想吗?

我真的很感激任何建议。

编辑:arrayObj:

 var arrayObj = { "word1": 'word_word1', "word2": 'word_word2', "word3": 'word_word3', // extra 12K lines... } 

manifest.json的:

我的清单很典型,但内容脚本信息是:

  "content_scripts": [ { "matches": ["http://*/*", "https://*/*"], "css": ["styles.css", "tipped.css"], "js": ["jquery.min.js", "jquery-highlight1.js", "spinners.min.js", "tipped.js", "word.js", "script.js"], "run_at": "document_end" } ], 

更新 http://jsfiddle.net/r4bnxemL/3/

这种新方法不那么复杂,并且不会将每个单词合并为一个大的正则表达式。 相反,它只使用setTimeout技巧使用asycn循环方法。

 var words = ['dolor', 'sit', 'odio']; var ele = document.getElementById('text'), html = ele.innerHTML; asycnIterator(words, function (word) { var reg = new RegExp('\\b' + word + '\\b', 'ig'); html = html.replace(reg, '' + word + ''); }, function () { ele.innerHTML = html; }); function asycnIterator(arr, func, cb) { var i = 0; nextCall(); function nextCall() { func(arr[i++]); if (i >= arr.length) { if (cb) cb(); return; } setTimeout(nextCall, 1); } } 

首先,你可以做两件事情首先将循环分解成小块,它可能会使整个过程在更多时间内完成一些但是它不会阻塞其他所有东西,Javascript单线程所以使用事件循环。

例如,你可以使用setTimeout来完成它。 (注意将需要使用回调模式,因为它将立即返回,下一行的执行不会等待循环完成)

 var arr = [1,2,3....100000]; var i = 0 ; nonBlockingAsycnLoop(); //will prints all values in console without blocking function nonBlockingAsycnLoop() { console.log(arr[i++]); setTimeout(nonBlockingAsycnLoop,0); } 

你可以做的第二件事是让你更快地查找。 就此而言,您使用的本机方法越多越好。 这只是我的方法

  1. 将所有数组元素连接成一个字符串
  2. 然后使用它们作为正则表达式进行搜索
  3. 存储索引

以下函数执行此操作并使用所有实例的列表调用cb。

 function returnOccurences(str, arr, cb) { var ele = null, index = 0, occurences = [], regexp = '\\b' + arr.join('\\b|\\b') + '\\b'; getNextWord(); function getNextWord() { ele = str.substr(index).match(new RegExp( regexp , 'i')); if (!ele) { cb(occurences); return; } occurences.push({i: ele.index, len: ele[0].length, word: ele[0]}); index = ele[0].length + ele.index; setTimeout(getNextWord,0); //makes it non blocking } } 

字符串匹配函数docs MDN LINK如果不使用参数g为regex调用它,则返回具有非可枚举属性的数组,这些属性是找到的单词的索引和包含原始文本的输入。

我们可以使用index在第一次匹配后进一步解析前面的字符串。