Greasy Fork の日本語訳は 81% しか完了していません。改善に参加しませんか?

Amazon CPU Tamer

AmazonのショッピングページでのCPU使用率を削減します。お買いものをサクサク楽しみましょう。

質問やレビューの投稿はこちらへ、スクリプトの通報はこちらへお寄せください。
  1. // ==UserScript==
  2. // @name Amazon CPU Tamer
  3. // @name:ja Amazon CPU Tamer
  4. // @name:zh-CN Amazon CPU Tamer
  5. // @namespace knoa.jp
  6. // @description It reduces CPU usage on Amazon shopping pages. Enjoy your snappy shopping.
  7. // @description:ja AmazonのショッピングページでのCPU使用率を削減します。お買いものをサクサク楽しみましょう。
  8. // @description:zh-CN 减少Amazon购物页面上的CPU利用率。顺利地享受买东西吧。
  9. // @include https://www.amazon.com/*
  10. // @include https://www.amazon.co.jp/*
  11. // @include https://www.amazon.co.uk/*
  12. // @include https://www.amazon.es/*
  13. // @include https://www.amazon.fr/*
  14. // @include https://www.amazon.de/*
  15. // @include https://www.amazon.it/*
  16. // @include https://www.amazon.*
  17. // @include https://*.amazon-*.com/*
  18. // @include https://*.*-amazon.com/*
  19. // @exclude */cart/*
  20. // @exclude */buy/*
  21. // @version 1.4.4
  22. // @grant none
  23. // @run-at document-start
  24. // @antifeature referral-link This script may add an associate ID to visited Amazon URLs. It doesn't replace any existed ID. Thank you.
  25. // @antifeature:ja referral-link ありがとうございます。本スクリプトは、訪れたAmazonページのURLにアソシエイトIDを付与することがあります。別のIDがすでに付与されている場合は、置き換えることはしません。
  26. // @antifeature:zh-CN referral-link 本脚本可能会为访问过的Amazon页面的URL授予联盟ID。如果已经授予了另一个ID,则不会进行替换。谢谢。
  27. // @contributionURL https://paypal.me/kantankikaku
  28. // ==/UserScript==
  29.  
  30. /*
  31. [update]
  32. Update @antifeature descriptions. Minor fix.
  33.  
  34. [memo]
  35. top:
  36. interval インタラクション要素にも使われるので、1インスタンスにまとめた上で前面タブのみやむなく125msごとに実行。
  37. もっとゆるい頻度にしつつ、click や keydown 時のみ頻度を上げる手はあるが、前面タブで1-2%なら許されるだろう。
  38. ゆるい interval による把握できている問題は詳細画像の切り替え表示だけなので、自分でやっちゃう手もあるが。
  39. timeout インタラクションのみで定常なしなので、そのまま実行してもよい。
  40. iframe(ad):
  41. interval 初期化時のみなのでそのまま実行してもよい。
  42. timeout 定常 100ms が iframe ごとに1つずつなので、1秒ごとに頻度を落とす。
  43. iframe(cloudfront.net ad)
  44. ローカルソースのiframeから事後生成されるのでTampermonkeyが機能しない。
  45. 広告除去することはできるが、このスクリプトの役目ではない。
  46. */
  47. (function(){
  48. const SCRIPTID = 'AmazonCpuTamer';
  49. console.log(SCRIPTID, location.href);
  50. const BUNDLEDINTERVAL = 125;/* the bundled interval */
  51. const BACKGROUNDINTERVAL = 60*1000;/* take even longer interval on hidden tab */
  52. const IFRAMETIMEOUT = 1*1000;/* amazon uses timeouts instead of intervals on iframes */
  53. /*
  54. [interval]
  55. tame quick intervals
  56. */
  57. if(window === top){
  58. /* integrate each of intervals */
  59. const bundle = {};/* {0: {f, interval, lastExecution}} */
  60. let index = 0;/* use it instead of interval id */
  61. let lastExecution = 0;
  62. /* bundle intervals */
  63. const originalSetInterval = window.setInterval.bind(window);
  64. window.setInterval = function(f, interval, ...args){
  65. //console.log(SCRIPTID, 'original interval:', interval, location.href);
  66. bundle[index] = {
  67. f: f.bind(null, ...args),
  68. interval: interval,
  69. lastExecution: 0,
  70. };
  71. return index++;
  72. };
  73. window.clearInterval = function(id){
  74. //console.log(SCRIPTID, 'clearInterval:', id, location.href);
  75. delete bundle[id];
  76. };
  77. /* execute bundled intervals */
  78. /* a bunch of intervals does cost so much even if the processes do nothing */
  79. originalSetInterval(function(){
  80. const now = Date.now();
  81. if(document.hidden && now < lastExecution + BACKGROUNDINTERVAL) return;
  82. Object.keys(bundle).forEach(id => {
  83. const item = bundle[id];
  84. if(item === undefined) return;/* it could be occur on tiny deletion chance */
  85. if(now < item.lastExecution + item.interval) return;/* not yet */
  86. item.f();
  87. item.lastExecution = now;
  88. });
  89. lastExecution = now;
  90. }, BUNDLEDINTERVAL);
  91. }
  92. /*
  93. [timeout]
  94. tame quick timeouts on iframe ads
  95. */
  96. if(window !== top){
  97. const originalSetTimeout = window.setTimeout.bind(window);
  98. window.setTimeout = function(f, timeout, ...args){
  99. if(document.hidden) return;
  100. if(timeout < IFRAMETIMEOUT){
  101. //console.log(SCRIPTID, 'timeout:', timeout, 'to', IFRAMETIMEOUT, location.href);
  102. timeout = IFRAMETIMEOUT;
  103. }
  104. return originalSetTimeout(f, timeout, ...args);
  105. };
  106. }
  107. /*
  108. [associate]
  109. add an associate tag
  110. */
  111. if(window === top){
  112. const IDS = {
  113. 'www.amazon.com': 'knoa-20',
  114. 'www.amazon.co.jp': 'knoa-22',
  115. 'www.amazon.co.uk': 'knoa01-21',
  116. 'www.amazon.es': 'knoa0c-21',
  117. 'www.amazon.fr': 'knoa09-21',
  118. 'www.amazon.de': 'knoa03-21',
  119. 'www.amazon.it': 'knoa0a-21',
  120. };
  121. if(IDS[location.host]){
  122. addTag(IDS[location.host]);
  123. }
  124. function addTag(tag){
  125. const url = new URL(location.href);
  126. if(url.searchParams.get('tag') !== null) return;/* do not overwrite */
  127. console.log(SCRIPTID, 'associate tag:', tag);
  128. document.documentElement.addEventListener('mousedown', function(e){
  129. for(let target = e.target; target; target = target.parentNode){
  130. if(target.href && target.href.startsWith(location.origin) && !target.getAttribute('href').startsWith('#')){
  131. const separator = (target.href.includes('?')) ? '&' : '?';
  132. target.href = target.href.replace(/(?=#)|$/, separator + 'tag=' + tag);
  133. }
  134. }
  135. });
  136. const separator = (url.search === '') ? '?' : '&';
  137. history.replaceState(null, document.title, location.href.replace(/(?=#)|$/, separator + 'tag=' + tag));
  138. }
  139. }
  140. })();