首页性能优化有多个不同的方向,对应的优化方案也有所不同,本文主要介绍首页如何在首次加载时减少所依赖javascript文件数量来提升性能,即javascript的按需加载。


首先先说明一下javascript按需加载的概念及适用场景:通常一个页面会在header标签里声明依赖的javascript文件,这些javascript文件可能是jquery、angular、vue这样的框架库,也可能是d3这样的工具库,或者是我们自定义的函数库或插件,但在页面首次加载时,除了框架库外,部分工具库和自定义函数库或插件仅仅只是加载,并没有被调用,但是加载这些暂时并不会使用的javascript文件却实实在在地消耗了时间,这里的优化点就是变更这部分javascript文件的加载时机——让核心模块优先加载,非核心模块延迟加载。

按笔者的开发经验,延迟加载可以分为三类:
1. 按需加载——当发生交互行为时加载;
2. 定时加载——在window.onload里定义setTimeout延时加载(或在页面idle时期加载,不影响核心模块加载);
3. 刷新加载——当页面二次加载时加载(二次加载时很多首次加载请求的资源已在本地缓存)。

下面用一个例子来介绍一下按需加载,例子功能如下:
按需加载例子

再补充说明一下:input框允许输入一个字符串,检查按钮会按逗号对字符串进行分割,并显示匹配的字符串“李庆”。

在上面的例子中,检查触发的自定义函数只有当用户点击检查按钮发生交互时才会被调用,并不需要在页面首次加载时就载入。再从浏览器控制台看一下这个自定义函数的加载时机:

网络

元素

从网络可以看到当点击按钮后才发送请求获取自定义函数(check.js),从元素可以看到当点击按钮后请求的check.js才拼到body的末尾。即用户在未触发指定的动作之前,执行该动作所需的javascript就永远不会加载(这是不是很cooooool)。

上代码:

performance.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<input type="text" id="names" value=""/>
<button onclick="check()">检查</button>
</body>
</html>
<script>
var scriptList = {};
function load(url, callback) {
    var script = document.createElement("script");
    script.type = "text/javascript";
    script.src = url;
    document.body.appendChild(script);
    scriptList[url] = script;
    if(typeof(callback) !== "undefined"){
        script.onload = function () {
            callback();
        };
    }
}

function check () {
    var url = "check.js";
    if (scriptList.hasOwnProperty(url)) {
        var names = document.getElementById("names").value;
        checkObj.checkName(names);
    } else {
        load(url, function () {
            var names = document.getElementById("names").value;
            checkObj.checkName(names);
        });
    }
}
</script>


check.js

var checkObj = {
    "checkName": function (names) {
        var nameList = names.split(",");
        nameList.forEach(function (name) {
            if (name === "李庆") {
                alert("find name 李庆.");
            }
        });
    }
}

当然,当执行按需加载的时候必须知道需要请求什么资源,就上面的例子来说,在定义check函数时必须明确需要调用的自定义函数在check.js内。另外补充说明一下,scriptList这个对象是为了保证当前页面相同的资源只请求一次(去掉的话每次触发都会请求相同的资源,然后页面的check.js会越拼越多)。

Logo

前往低代码交流专区

更多推荐