Explorar o código

speedup: use Uint8Array.toBase64 & fromBase64 in content

tophf hai 1 día
pai
achega
b904c61be0
Modificáronse 4 ficheiros con 27 adicións e 14 borrados
  1. 2 0
      src/common/consts.js
  2. 1 3
      src/common/util.js
  3. 12 5
      src/injected/content/requests.js
  4. 12 6
      src/injected/content/util.js

+ 2 - 0
src/common/consts.js

@@ -55,3 +55,5 @@ export const VM_HOME = 'https://violentmonkey.github.io/';
 export const VM_DOCS_MATCHING = VM_HOME + 'api/matching/';
 export const VM_DOCS_MATCHING = VM_HOME + 'api/matching/';
 export const FILE_GLOB_ALL = 'file://*/*';
 export const FILE_GLOB_ALL = 'file://*/*';
 export const XHR_COOKIE_RE = /:\W+([-\w]+)/; // extracts ://id in Chrome, ://{id} in Firefox
 export const XHR_COOKIE_RE = /:\W+([-\w]+)/; // extracts ://id in Chrome, ://{id} in Firefox
+/** @type {(str: string, opts?: {}) => Uint8Array} */
+export const U8_fromBase64 = process.env.IS_INJECTED !== 'injected-web' && Uint8Array.fromBase64;

+ 1 - 3
src/common/util.js

@@ -1,12 +1,10 @@
 // SAFETY WARNING! Exports used by `injected` must make ::safe() calls and use __proto__:null
 // SAFETY WARNING! Exports used by `injected` must make ::safe() calls and use __proto__:null
 
 
-import { NO_CACHE } from '@/common/consts';
+import { NO_CACHE, U8_fromBase64 } from '@/common/consts';
 
 
 export const i18n = memoize((name, args) => chrome.i18n.getMessage(name, args) || name);
 export const i18n = memoize((name, args) => chrome.i18n.getMessage(name, args) || name);
 const HAS_BASE64_RE = /(^|;)\s*base64\s*(;|$)/;
 const HAS_BASE64_RE = /(^|;)\s*base64\s*(;|$)/;
 const NON_ASCII_RE = /[\x80-\xFF]/;
 const NON_ASCII_RE = /[\x80-\xFF]/;
-/** @type {(str: string, opts?: {}) => Uint8Array} */
-const U8_fromBase64 = Uint8Array.fromBase64;
 
 
 export function memoize(func) {
 export function memoize(func) {
   const cacheMap = /*@__PURE__*/Object.create(null);
   const cacheMap = /*@__PURE__*/Object.create(null);

+ 12 - 5
src/injected/content/requests.js

@@ -1,6 +1,6 @@
 import bridge, { addBackgroundHandlers, addHandlers, onScripts } from './bridge';
 import bridge, { addBackgroundHandlers, addHandlers, onScripts } from './bridge';
 import { sendCmd } from './util';
 import { sendCmd } from './util';
-import { UA_PROPS } from '../util';
+import { U8_fromBase64, UA_PROPS } from '../util';
 
 
 const {
 const {
   fetch: safeFetch,
   fetch: safeFetch,
@@ -14,6 +14,7 @@ const getTypedArrayBuffer = describeProperty(getPrototypeOf(SafeUint8Array[PROTO
 const getReaderResult = describeProperty(SafeFileReader[PROTO], 'result').get;
 const getReaderResult = describeProperty(SafeFileReader[PROTO], 'result').get;
 const readAsDataURL = SafeFileReader[PROTO].readAsDataURL;
 const readAsDataURL = SafeFileReader[PROTO].readAsDataURL;
 const fdAppend = SafeFormData[PROTO].append;
 const fdAppend = SafeFormData[PROTO].append;
+const U8_set = SafeUint8Array[PROTO].set;
 const CHUNKS = 'chunks';
 const CHUNKS = 'chunks';
 const LOAD = 'load';
 const LOAD = 'load';
 const LOADEND = 'loadend';
 const LOADEND = 'loadend';
@@ -182,11 +183,17 @@ function processChunk(req, data, msg) {
     setOwnProp(req[CHUNKS] || (req[CHUNKS] = ['']), msg ? msg.i : 0, data);
     setOwnProp(req[CHUNKS] || (req[CHUNKS] = ['']), msg ? msg.i : 0, data);
     return;
     return;
   }
   }
-  data = safeAtob(data);
+  data = U8_fromBase64 ? U8_fromBase64(data) : safeAtob(data);
   const len = data.length;
   const len = data.length;
-  const arr = req[CHUNKS] || (req[CHUNKS] = new SafeUint8Array(msg ? msg.size : len));
-  for (let pos = msg?.chunk || 0, i = 0; i < len;) {
-    arr[pos++] = safeCharCodeAt(data, i++);
+  const lenAll = msg ? msg.size : len;
+  let arr = req[CHUNKS];
+  if (!arr && U8_fromBase64 && len === lenAll) {
+    req[CHUNKS] = /**@type{Uint8Array}*/data;
+  } else {
+    arr ??= req[CHUNKS] = new SafeUint8Array(lenAll);
+    let pos = msg?.chunk || 0;
+    if (U8_fromBase64) arr::U8_set(/**@type{Uint8Array}*/data, pos);
+    else for (let i = 0; i < len;) arr[pos++] = safeCharCodeAt(data, i++);
   }
   }
 }
 }
 
 

+ 12 - 6
src/injected/content/util.js

@@ -1,5 +1,6 @@
 // eslint-disable-next-line no-restricted-imports
 // eslint-disable-next-line no-restricted-imports
 import { sendMessage } from '@/common';
 import { sendMessage } from '@/common';
+import { U8_fromBase64 } from '../util';
 
 
 export * from './util-task';
 export * from './util-task';
 
 
@@ -64,15 +65,20 @@ export const decodeResource = (raw, isBlob) => {
   // TODO: do the check in BG and cache/store the result because safe-guarding all the stuff
   // TODO: do the check in BG and cache/store the result because safe-guarding all the stuff
   // regexp picks from an instance internally is inordinately complicated
   // regexp picks from an instance internally is inordinately complicated
   if (/[\x80-\xFF]/::regexpTest(res)) {
   if (/[\x80-\xFF]/::regexpTest(res)) {
-    const len = res.length;
-    const bytes = new SafeUint8Array(len);
-    for (let i = 0; i < len; i += 1) {
-      bytes[i] = safeCharCodeAt(res, i);
+    if (U8_fromBase64) {
+      res = U8_fromBase64(mimeData);
+    } else {
+      const len = res.length;
+      const bytes = new SafeUint8Array(len);
+      for (let i = 0; i < len; i += 1) {
+        bytes[i] = safeCharCodeAt(res, i);
+      }
+      res = bytes;
     }
     }
-    res = isBlob ? bytes : new SafeTextDecoder()::tdDecode(bytes);
+    if (!isBlob) res = new SafeTextDecoder()::tdDecode(res);
   }
   }
   return isBlob
   return isBlob
-    ? createObjectURL(new SafeBlob([res], { type: mimeType }))
+    ? createObjectURL(new SafeBlob([res], { __proto__: null, type: mimeType }))
     : res;
     : res;
 };
 };