LoginSignup
1
1

テンプレートをIMG loading=lazyのような遅延読み込みさせる

Last updated at Posted at 2024-02-22

エレメントが画面内に入ったときにテンプレートを実行させる

Navboxのようなページ下部の巨大テンプレートを遅延読み込みさせて「参照読み込みの展開後のサイズ(Post‐expand include size)」を削減させる狙い。

ページ保存時、以下のテンプレートを使用すると<div>...</div>のみが展開されて保存される。

テンプレート:LazyLoad
<includeonly><div class="lazyLoad" data-page="{{{page|}}}"></div></includeonly>

ユーザーがページを開いた時点では<div>のまま読み込まれる。
そしてガジェットに仕込んだJavaScriptがエレメントを監視し、画面内に入った瞬間にテンプレートを動的に展開する。

Gadget-lazyLoad.js
 mw.loader.using( ['mediawiki.util', 'mediawiki.Title'], function(){
    
    // IntersectionObserverを使用したエレメントの座標監視
    const intersectionObserver = new IntersectionObserver( function( entries ) {

        entries.forEach( function( entry ) {
            // 画面内に入った
            if ( entry.isIntersecting ){

                // エレメントの要素から引数を取得
                var page = entry.target.getAttribute( 'data-page' );
                
                if( page ){

                    // Apiへのリクエスト情報
                    var requestData = {
                        action: 'parse',
                        prop: 'text|modules|jsconfigvars|templates',
                        title: mw.config.get( 'wgPageName' )
                    };

                    // 対象ページがテンプレートか記事か調べてWikitextを生成
                    var title = new mw.Title( page );
                    var template = title.getNamespaceId() == 10;
                    if ( template ) {
                        requestData.text = '{' + '{' + page + '}}';
                    } else {
                        requestData.text = '{' + '{:' + page + '}}';
                    }

                    // Wikitextを動的にパーサーさせる
                    new mw.Api().get( requestData ).done(function ( data ) {
                        // VisualEditorのプレビューと同じ処理
                        // * ve.init.mw.ArticleTarget.js
                        //
                        if ( data.parse.jsconfigvars ) {
                            // mw.loader呼び出しのための引数の割当
                            mw.config.set( data.parse.jsconfigvars );
                        }
                        if ( data.parse.modules ) {
                            // mw.loaderの呼び出し
                            mw.loader.load( data.parse.modules.concat(
                                data.parse.modulescripts,
                                data.parse.modulestyles
                            ));
                        }
                        // できたHTMLの差し込み
                        var html = $( $(data.parse.text['*']).html() ).removeClass( 'noscript' );
                        $( entry.target ).append( html );

                        // 他のスクリプトへ読み込み完了通知
                        mw.hook( 'wikipage.content' ).fire( $(entry.target) );
                    });

                }
                // 監視対象から除外
                intersectionObserver.unobserve( entry.target );
            }
        });
    });

    // エレメントの監視を開始
    var observe_target = document.querySelectorAll( ".lazyLoad" );
    observe_target.forEach( function( element ){
        intersectionObserver.observe( element );
    });
});

使用例:Minecraft Japan Wiki - ブロック/生物

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1