フィルター動作を最適化する 

「TwAvoid」は、次々とタイムラインに出現するツイートを処理しなければならず、その出現・増減の変化に反応する「MutationObserver」を使っています。 また、他のタイムラインに移動した時に、新しい画面に出現するツイート群に対応するために、タイムラインの変化に反応する別の「MutationObserver」を使っています。

 

「MutationObserver」の使用時は、処理過剰に陥らない制御に注意が要ります。 私の場合は、「Observer」が機能したら「body」を一瞬赤背景にするといった監視用のコードを使い、適度な発火をしているか目視でチェックしたりします。 もちろん、コードが完成したら、監視用コードは削除します。

 

また、今回の「TwAvoid」では、ツイートを非表示に処理した場合をカウントして、画面の隅でツールの動作が判る様にしています。

 

下は、「MutationObserver」の発火をチェックしている様子です。

 

 

 

この状態は、スクロールに合わせて時々新しいツイートが呼込まれ、その度に処理がエンハンスされています。 これは目的の通りで良好ですが、設定が悪くて過剰(ハウリングの様な状態)になると赤背景のままになります。 そうなると、画面の動作がギクシャクしたり、酷い場合はハングアップします。

 

この赤背景の度に、読み込まれたツイート(20弱)を取得して、ツイートのひとつずつを検索処理をして、ブロックするかどうかを判定しています。 PCの処理は電光石火で、大変な処理をしているわけです。

 

 

無駄な判定処理 

非表示処理をした回数をカウントするテストコードは、画面の左上にカウントを表示します。 下は ver. 0.1 ですが、これを見ると 15個位のツイートを移動する間に 3000回を超えるカウントです。

 

 

 

1個のツイートを非表示とすると 1カウントですから、なんでこんなに多いのか。

一番怪しいのは、「MutationObserver」を2重に設定している事です。 片方のエンハンスに反応してもう一方がエンハンスし、これが繰り返されるハウリング状態です。

 

そこで、タイムラインの移動に反応する方を外すと、一気に回数が減りました。

 

 

 

この「Observer」が原因らしいが、タイムラインを移動するとスクリプトが停止してしまうので「Observer」は必須です。 そこでこの「Observer」の監視対象を変更する事にしました。

 

 

 「タイムラインの移動」の監視方法を変更する

通常よく利用する「ページ移動」を監視する「MutationObserver」のコードを、前バージョンでは「タイムラインの移動」の監視に使っていました。

 

let target=document.querySelector('head');
let monitor0=new MutationObserver(page_ck);
monitor0.observe(target, { childList: true });

 

監視対象は「head要素」で、移動を感知すると「page_ck」という関数を実行し、タイムラインを取得し、そのツイート読込みを監視する「Observer」を起動します。

 

今回の輻輳は、後者の「Observer」以降のブロック処理が「head要素」の変更を招くので、それに最初の「Observer」が反応していると思われます。

 

その抑止には、ブロック処理に影響されない「タイムラインの移動」の監視対象を指定すれば良いわけです。 適当な監視対象を探していると、「記事タイトル」がタイムラインの変更時に書き換えられる事が判りました。

 

「MutationObserver」の監視対象は「DOM」でなければならないので、「head要素」の中の「title要素」を対象に変更しました。(下の赤枠)

 

 

 

この要素は、思ったより遅く「head要素」内に出来る様で、私の環境でページロード後 50msec以下では不安定で、安全を見越して 200msecのタイミングで取得する様にしています。

 

setTimeout(()=>{
    let target=document.querySelector('head title');
    let monitor0=new MutationObserver(page_ck);
    monitor0.observe(target, { childList: true });
}, 200);

 

これまでの「head」➔「head title」に監視対象を変更して、取得のタイミングを遅らせています。 この改善で、3000回 の異常動作が 30回以下に抑止できました。 また、タイムラインの変更に問題なくエンハンスします。

 

 

更に改善 

上記のテストでは、15程度のツイートをスクロールして動作を調べていますが、ツールがブロックするツイートは 3個に過ぎません。 なぜ、カウントが 3ではなく 30弱になるのか?

 

これは、ブロック対象のツイートを発見したら「display: none」のスタイル指定をしますが、既に非表示にしたツイートにも何度も処理していると推測されます。

 

この無駄を省くため、一度判定したらツイートに印を着ける事にしました。 次に処理が繰り返された時は、印があれば処理をパスするという方式です。

 

TwAvoid ver. 0.2  49行以降~

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()

 

このマーク方法は、処理したツイート要素に対して「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ツールは、アメーバのページ構成の変更で動作しない場合があり、導入する場合は最新バージョンをお勧めします。

 

● 最新バージョンへのリンクは、以下のページのリンクリストから探せます。