JavaScript设计模式之代理模式-惰性加载大文件

在看此文之前,建议先看前篇JavaScript设计模式之代理模式-实现加载图片loading

1.需求

假设有一个非常大的js文件,我们只在需要用的时候,才触发去加载它。比如有一个应用于移动端打印日志的控制台,在按F2才加载该文件并打印相关日志。效果如下:

2.实现

  • 首先我们创建index.html文件,html代码如下:

    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>虚拟代理惰性加载文件</title>
        <style>
            #consoleContent{
                border:1px solid #ccc;
                width: 200px;
                height: 300px;
                color:#333;
                overflow: auto;
                display: none;
            }
            #consoleContent p{
                margin: 0;
                padding: 5px 10px;
                vertical-align: middle;
                border-bottom:1px solid #ccc;
                overflow-wrap: break-word;
            }
        </style>
    </head>
    
    <body>
        <section id="consoleContent"></section>
    </body>
    
    </html>
  • 接着在以上文件中插入script脚本,代码如下:

    let miniConsole = (function () {
            let cache = [];
            // 当用户按下F2时,开始加载真正的miniConsole.js 
            const handler = function (ev) {
                if (ev.keyCode === 113) {
                    const script = document.createElement('script');
                    script.onload = function () {
                        for (let i = 0, fn; fn = cache[i++];) {
                            fn();
                        }
                        cache = null;
                    };
                    script.type = 'text/javascript';
                    script.src = "miniConsole.js";
                    document.getElementsByTagName('head')[0].appendChild(script);
                    document.removeEventListener('keydown', handler);
                }
            };
            document.addEventListener('keydown', handler, false);
            return {
                log: function () {
                    const args = arguments;
                    cache.push(function () {
                        // 不直接用miniConsole.log(args)是为了解决传多个参数的问题
                        return miniConsole.log.apply(miniConsole,args);
                    })
                }
            }
        })();
        miniConsole.log(11,22);
        miniConsole.log(22);
        miniConsole.log(33);

由于我们要加载的js文件中的对象为miniConsole,所以创建了一个同名代理对象:

  1. 在其中添加监听按键事件,当用户按下F2时,才开始加载真正的miniConsole.js文件;
  2. 实现与本体对应的log方法,文件未加载时,先存放于缓存对象cache中;
  3. 在真正的miniConsole.js加载完成后,调用cache中缓存的方法,实现真正的打印功能。
  • 最后,miniConsole.js主要代码大致如下:

    miniConsole = {
        log: function () {
            const p = document.createElement('p');
            p.innerHTML = Array.prototype.join.call(arguments);
            const content = document.getElementById('consoleContent');
            content.appendChild(p);
            content.style.display = 'block';
        }
    };

3.思路总结

以上miniConsole.js有时候需要处理各种类型的日志打印,导致文件会更大。但我们这个功能不一定用户都会用,所以实现惰性加载,减少网络开销。

当我们遇到大文件且非必要的功能,我们可以用虚拟代理实现惰性加载,步骤如下:

  1. 创建与原文件接口相同的同名代理对象;
  2. 在特定需要的情况(如监听按键)时加载原文件;
  3. 在代理对象接口中缓存所有的调用,并监听文件加载,等文件加载完成时再进行执行。

代理模式系列:

实现加载图片loading

频繁发送请求性能优化

注:参考书籍《JavaScript设计模式与开发实践》,喜欢可以关注博主哦,不断更新设计模式系列学习笔记~

不要吝啬点赞评论哦~

猜你喜欢

转载自blog.csdn.net/qq_39287602/article/details/108751853