フィルター動作を最適化する
「TwAvoid」は、次々とタイムラインに出現するツイートを処理しなければならず、その出現・増減の変化に反応する「MutationObserver」を使っています。 また、他のタイムラインに移動した時に、新しい画面に出現するツイート群に対応するために、タイムラインの変化に反応する別の「MutationObserver」を使っています。
「MutationObserver」の使用時は、処理過剰に陥らない制御に注意が要ります。 私の場合は、「Observer」が機能したら「body」を一瞬赤背景にするといった監視用のコードを使い、適度な発火をしているか目視でチェックしたりします。 もちろん、コードが完成したら、監視用コードは削除します。
また、今回の「TwAvoid」では、ツイートを非表示に処理した場合をカウントして、画面の隅でツールの動作が判る様にしています。
下は、「MutationObserver」の発火をチェックしている様子です。
この状態は、スクロールに合わせて時々新しいツイートが呼込まれ、その度に処理がエンハンスされています。 これは目的の通りで良好ですが、設定が悪くて過剰(ハウリングの様な状態)になると赤背景のままになります。 そうなると、画面の動作がギクシャクしたり、酷い場合はハングアップします。
この赤背景の度に、読み込まれたツイート(20弱)を取得して、ツイートのひとつずつを検索処理をして、ブロックするかどうかを判定しています。 PCの処理は電光石火で、大変な処理をしているわけです。
無駄な判定処理
非表示処理をした回数をカウントするテストコードは、画面の左上にカウントを表示します。 下は ver. 0.1 ですが、これを見ると 15個位のツイートを移動する間に 3000回を超えるカウントです。
1個のツイートを非表示とすると 1カウントですから、なんでこんなに多いのか。
一番怪しいのは、「MutationObserver」を2重に設定している事です。 片方のエンハンスに反応してもう一方がエンハンスし、これが繰り返されるハウリング状態です。
そこで、タイムラインの移動に反応する方を外すと、一気に回数が減りました。
この「Observer」が原因らしいが、タイムラインを移動するとスクリプトが停止してしまうので「Observer」は必須です。 そこでこの「Observer」の監視対象を変更する事にしました。
「タイムラインの移動」の監視方法を変更する
通常よく利用する「ページ移動」を監視する「MutationObserver」のコードを、前バージョンでは「タイムラインの移動」の監視に使っていました。
監視対象は「head要素」で、移動を感知すると「page_ck」という関数を実行し、タイムラインを取得し、そのツイート読込みを監視する「Observer」を起動します。
今回の輻輳は、後者の「Observer」以降のブロック処理が「head要素」の変更を招くので、それに最初の「Observer」が反応していると思われます。
その抑止には、ブロック処理に影響されない「タイムラインの移動」の監視対象を指定すれば良いわけです。 適当な監視対象を探していると、「記事タイトル」がタイムラインの変更時に書き換えられる事が判りました。
「MutationObserver」の監視対象は「DOM」でなければならないので、「head要素」の中の「title要素」を対象に変更しました。(下の赤枠)
この要素は、思ったより遅く「head要素」内に出来る様で、私の環境でページロード後 50msec以下では不安定で、安全を見越して 200msecのタイミングで取得する様にしています。
これまでの「head」➔「head title」に監視対象を変更して、取得のタイミングを遅らせています。 この改善で、3000回 の異常動作が 30回以下に抑止できました。 また、タイムラインの変更に問題なくエンハンスします。
更に改善
上記のテストでは、15程度のツイートをスクロールして動作を調べていますが、ツールがブロックするツイートは 3個に過ぎません。 なぜ、カウントが 3ではなく 30弱になるのか?
これは、ブロック対象のツイートを発見したら「display: none」のスタイル指定をしますが、既に非表示にしたツイートにも何度も処理していると推測されます。
この無駄を省くため、一度判定したらツイートに印を着ける事にしました。 次に処理が繰り返された時は、印があれば処理をパスするという方式です。
TwAvoid ver. 0.2 49行以降~
このマーク方法は、処理したツイート要素に対して「opacity: 2」を指定するというものです。「opacity」は 1以上で表示は同じですが、スタイルのプロパティとしては指定が付加されます。 またツイート要素に、他から「opacity」が指定される事はありません。
上のコードは、ツイートの表示・非表示を判定した後は「opacity: 2」がマークされ、次の処理時に「opacity: 2」なら処理をパスします。 新たにタイムラインに読み込まれたツイートや、非表示にしたが上書きで再表示されたツイートは「opacity」が「無指定」になるので、判定処理が行われます。
これで、無駄な処理がなくなり、下の様に非表示の処理回数は数回になりました。
これは納得できる回数です。 ブロック対象は3個で、システムが非表示にしたツイートを再表示するので、それを再処理するために 2倍の回数になっています。
以上の簡単なコードの追加で、ツールの動作が最適化されたと思います。
「TwAvoid」を利用するには
このツールは Chrome / Edge / Firefox版の拡張機能「Tampermonkey」上で動作します。 以下に、このツールの導入手順を簡単に説明します。
❶「Tampermonkey」を導入します
◎ 使用しているブラウザに拡張機能「Tampermonkey」を導入する事が必要です。
既に「Tampermonkey」を導入している場合は、この手順 ❶ は不要です。
拡張機能の導入については、以下のページに簡単な説明があるので参照ください。
❷「Tampermonkey」にスクリプトを登録します
◎「Tampermonkey」の「+」マークの「新規スクリプト」タブを開きます。
◎「新規スクリプト」には、最初からテンプレートが記入されています。 これは全て削除して、完全に空白の編集枠に 下のコードをコピー&ペーストします。
〔コピー方法〕 軽量シンプルなツール「PreBox Button 」を使うと
コード枠内を「Ctrl+左Click」➔「Copy code 」を「左Click」
の操作で、掲載コードのコピーが可能になります。
◎ 最後に「ファイル」メニューの「保存」を押すと、ツールが使用可能になります。
〔 TwAvoid 〕 ver. 0.2
// ==UserScript== // @name TwAvoid // @namespace http://tampermonkey.net/ // @version 0.2 // @description Twitter Filter // @author Everyone // @match https://twitter.com/* // @icon https://www.google.com/s2/favicons?sz=64&domain=twitter.com // @grant none // ==/UserScript== // 🔴 特定のURLのハッシュタグ・ユーザーリンクを含むツイートを非表示 let avoid=['/RakutenJP', '/digimartnet']; // 🔴 特定の文字列を含むツイートを非表示 複数は縦棒で分割 let avoid_regexp=/@RakutenJP|楽天カード/; setTimeout(()=>{ let target=document.querySelector('head title'); let monitor0=new MutationObserver(page_ck); monitor0.observe(target, { childList: true }); }, 200); function page_ck(){ let retry=0; let interval=setInterval(wait_target, 100); function wait_target(){ retry++; if(retry>50){ // リトライ制限 5secまで clearInterval(interval); } let time_line=get_line(); // 監視 target if(time_line){ clearInterval(interval); let monitor1=new MutationObserver(main); monitor1.observe(time_line, { childList: true }); }} function get_line(){ let cell=document.querySelector('[data-testid="cellInnerDiv"]'); if(cell){ let container=cell.parentNode; return container; }} } // page_ck() function main(){ let cell=document.querySelectorAll('[data-testid="cellInnerDiv"]'); for(let k=0; k<cell.length; k++){ if(cell[k].style.opacity!='2'){ // ❶ の検索処理 🟦⬜ let all_link=cell[k].querySelectorAll('a'); let url=[]; for(let i=0; i<all_link.length; i++){ url.push(all_link[i].getAttribute('href')) } let result=url.filter(data=>avoid.includes(data)); if(result.length>0){ cell[k].style.display='none'; } // ❷ の検索処理 🟦⬜ let tweet_text=cell[k].textContent; if(avoid_regexp.test(tweet_text)){ cell[k].style.display='none'; } cell[k].style.opacity='2' }} } // main()
「TwAvoid」最新版について
旧いバージョンの JavaScriptツールは、アメーバのページ構成の変更で動作しない場合があり、導入する場合は最新バージョンをお勧めします。
● 最新バージョンへのリンクは、以下のページのリンクリストから探せます。