ファーストスクリーン時間収集自動化ソリューションについて


ヘッドスクリーンについて


最初の画面時間とは、ページに移動してから画面内のページのすべての内容が表示されるまでの時間です.すでに多くのスクリーン時間の計算について、本文の中でこれらのすでに提出されたあるいは実現された方案を繰り返し述べないで、もっと多くのスクリーン自動化採集方案を探求して討論することを目的として、思考の範囲を拡大して、あなたと私の思想の間で互いに衝突して往々にしてもっと奇妙な解決方案を奮い立たせることができて、これもまさに私がこの文章を書く目的です.
ブラウザデバッグツールを使用すると、ページリソースのロードタイミングチャートが明確に表示されます.
まずhtmlページのロード、tokenの文法、文法解析を行った後、静的リソースのロードを開始し、関連スクリプトを実行し、DOMツリー、renderツリー、CSSOM数の構築を開始し、最後に画像をロードし、ユーザーは完全なページを見ることができます.
ブラウザにはそれぞれ最適化されたソリューションがありますが、多くの場合、ピクチャは最終的にロードされることが多く、これはピクチャのサイズが比較的大きいだけでなく、ピクチャのロードの有無がDOM構造と大きく関係しています.DOMが構築されたかどうか、renderツリーでレンダリングされているかどうか、および他のピクチャロードポリシーが関係しているかどうかは、ピクチャロードタイミングに影響を与える可能性があります.したがって,ヘッダ時間の計算では,最終ヘッダ画像のロード時間をノードとして計算した.

ヘッドスクリーン計算


原則1トップスクリーンコンピューティングモジュールはトラフィックラインを結合すべきではない


一般的に、ヘッダスクリーン計算は抽出されたjsスクリプトとして単独で参照され、このモジュールはAPIを開発者に露出しないようにし、すべての収集側タスクはモジュールによって完了する.この言葉はくだらない話のように聞こえるかもしれませんが、最初のスクリーンレンダリング時間の判断にビジネスマンが必要になる場合が多い場合があります.次に、この状況について実際のシーンを挙げます.
MVVMモードの勃興に伴い,フロントエンド非同期レンダリングが流行し,フロントエンド符号化はjQuery向けプログラミングからVue向けプログラミングに移行した.しかし、Vueを使用して作成されたビジネスコードは、ローカルでパッケージ化された後はbundleにすぎません.このときのHTMLファイルでは、プレースホルダが1つしかありません.では、スクリーン時間計算モジュールはどのようにしてスクリーン時間を正確に計算すればいいのでしょうか.したがって、ヘッダ画面時間計算モジュールは、ヘッダ画面のDOM構造がレンダリングされた時間ノードを知り、このノードの時点でヘッダ画面範囲内のピクチャロード時間を計算する必要がある.しかし、どのようにして最初のスクリーンDOM構造がレンダリングされた時間ノードを取得しますか?これは、ビジネス開発者が作成する必要があります.vueインスタンスのdataプロパティを更新した後、最初のスクリーン計算モジュールにDOMインタフェースがレンダリングされたことを通知し、最初のスクリーン時間の計算を開始します.
MVVM開発モデルでは、最初のスクリーン時間の計算に業務コードが結合されており、最初のスクリーン時間の正確性を保証することができるが、開発者にいくつかの判断ロジックをもたらしている.これらの判断は、新しい入社者たちを悩ませることが多いため、私たちの目標の一つは、手動で最初のスクリーン時間計算を行う必要がある現状を解決することである.

原則2性能と正確性のバランス


業界にはcanvasでスクリーンを切り、異なる時点のスクリーンショット画像の間のいくつかのランダムな画素点をポーリングして比較し、最初のスクリーンがロードされたかどうかを判断するものがあります.この方式は科学的だが、このような案を採用する会社は少ないだろう.canvasスクリーンショットという操作はハードウェアに対する要求が高く、追加の画素演算が必要であるため、性能が悪いに違いない.実はこのようなシーンは工事の分野でよく現れて、工事は科学のように厳格ではありませんて、私达はただ与えられた条件の最良の解を見つけるだけで、工事をするのはtrade offをしています.そのため、このような対比案も捨てなければなりません.

インプリメンテーション


開発者が最初の画面DOMをレンダリングして最初の画面の時間計算を行う方法は比較的正確であることを改めて強調した.そのため、後で議論する自動化計算の最初の画面の時間の正確性はこの基準に基づいて比較説明されている.自動化計算には人工的な介入が正確ではないに違いないからだ.この点は間違いない.

輪訓採集大法


ポーリングのたびにいくつかのアクションを実行するのとは異なり、輪訓です.
  • 最初の画面のすべての画像(IMGタグとcss関連属性を含む)
  • を取得する.
  • ヘッダピクチャをバインドするonloadおよびonerrorイベントは、ポーリングのたびにバインドされたピクチャ
  • を繰り返しバインドしません.
  • 同じピクチャは、バインドイベントのリスニングを繰り返す必要はありません.そうしないと、2のポーリングごとに
  • が混同されます.
  • ピクチャのイベント処理関数は、ドット情報を実行し、ピクチャのロード状態を統計するとともに、タイムスタンプに対して最も遅いロードが得られる時間
  • よりも遅いロードを行う.
    具体的な実装では、ヘッダ画面に表示される同じピクチャの場合に特に注意する必要がある.筆者は最初に,ヘッダピクチャのurl配列を簡単に計算し,重複ピクチャの個数を格納し,そのピクチャのロード状態にバインドした.同じピクチャが1画面に3枚現れた場合、そのピクチャonloadまたはonerrorでロードされたピクチャの数を3つ加算します.そうしないと、最終的なロードされたピクチャの総数が1画面のピクチャの総数と等しくない場合があります.この実装は論理が非常に悪く,実装が複雑になる.その後,ピクチャが存在するDOMオブジェクト配列を記憶することにより,より簡単なピクチャ状態判断を実現し,より既読とする.
    疑似コードは次のとおりです.
    // totalCounter       
    // DemandCounter         , 3000ms
    // imgsLoadedCount            
    // lastImageLoadedStamp           
    function checkFirstScreenDomReady(){
        if(totalCounter >= DemandCounter){
            // ...
            var stamps = Object.keys(pools),
            len = stamps.length,
            i = 0,
            it; 
            finalImgCount = pools[stamps[len - 1]].imgLen; 
            pollEnd = true;
    
            for(;i= finalImgCount){
                    self.onRecord = true;
                    _perfQueue._firstScreenLoadEnd = lastImageLoadedStamp;
                    firstScreen.firstScreenLoadEnd = lastImageLoadedStamp;
                    firstScreen.duaring = lastImageLoadedStamp - performance.timing.navigationStart;
                    
                    reportData(firstScreen);
                    return;
                }
            }
            return;
        }
        
        var imgEls = getImage();
    
        imgEls.forEach(function(el) {
            if(!imgLoadedHash.get(el)){
                var img = new Image();
                imgLoadedHash.put(el,{
                    loaded: true,
                });
                img.onload = OnLoad;
                img.onerror = OnError;
                img.src = el.__src;
            }
        });
        pools[totalCounter+''] = {
            imgLen: imgEls.length,
            stamp: Date.now(),
            imgsLoadedCount: imgsLoadedCount
        };
        totalCounter += timeout;
    }

    watch dog採取


    Mutation Observer APIを用いてコンテンツボックスのDOMイベントをリスニングし、ヘッダ画面のDOM構造が完備しているか否かを判断する.構築が完了すると、ヘッダ範囲内のピクチャロードイベントをリスニングし、ヘッダ時間を計算します.
    watch dogは、適切なヘッダDOMの構築が完了したことを知る必要があります.これは、最初のスクリーンコンピューティングモジュールがアクティブに打点ラベルを挿入し、ビジネスコードをラベルの内部に配置する必要があります(このステップは、足場で操作するパブリッシュフェーズに置くことが望ましい).mutationで偵察するj_collector_containerコンテナのDOM子孫ノードが変化します.observeイベント処理関数で計算する.j_collector_containerの高さは、スクリーンの高さより大きい場合は、最初のスクリーンのDOM構造がレンダリングされたことを意味し、最初のスクリーン時間の計算を開始します.
    計算中です.j_collector_container高さの場合、短時間で複数回のコンテナのレイアウト情報を計算しないように制限ポリシーを採用するのが望ましいのも仕方がない.
    疑似コードは次のとおりです.
    //     DOM       
    var firstScreenDomReady = false;
    var callback = function(records){
        if(firstScreenDomReady)
            return;
    
        //     throttle   
        for(var i=0,len=records.length;i= screenHeight){
                firstScreenDomReady = true;
                recordFirstScreenLoad();
                return;
            }
        }
    };
        
    var mo = new MutationObserver(callback);
    
    var option = {
        'childList': true,
        'subtree': true
    };
    
    var collectWrapper = document.querySelector('.j_collector_wrapper');
    if(collectWrapper.getBoundingClientRect().height < win.innerHeight){
        mo.observe(collectWrapper, option);
    }else{
        setTimeout(function(){
            recordFirstScreenLoad();
        });
    }

    まとめ


    いずれにしても、計算された最初のスクリーン時間は正確ではありません.また、各インプリメンテーションでは、getBoundingClientRectやoffsetTopプロパティへのアクセスによるrelayoutなど、JSエンジンを介してレンダリングエンジンのbridgeと通信する必要がある.しかし、これも仕方がありません.ブラウザが関連するトップスクリーンAPIを提供しない前提で、私たちはそうするしかありません.
    また、この3つの実装(開発者の手動打点、輪訓、watch dog採集)と比較して、複雑な電子商取引の最初の画面に対して性能テストを行い、このページの最初の画面部分には7つの非常に複雑なサブコンポーネントがあり、以下の結果を得た.
    結果も私たちの予想に合った.