问题背景
之前也遇到脚本加载慢的问题,但是没这么慢,所以这次就特别写个⽂章记录⼀下我的解决过程。
⾸先上两张项⽬已完成的截图。
下图是通过第三⽅脚本渲染出来的3D建筑页⾯
下图是⾸页,不需要⽤到第三⽅脚本
遇到的问题和需求
引⼊外部脚本太⼤,加载时间太长
⾸页⽤不到外部脚本,需要先渲染出来
⽤到外部脚本的页⾯,要是脚本还没加载好就点进去会报错
解决问题的过程
我⼀开始通过<script>标签直接引⼊到⼊⼝⽂件的头部,如下
<head>
<script src="./DDEarth.js"></script>
</head>
这样页⾯是可以正常加载的,但是页⾯出来的很慢,⼀开始会⽩屏⼀段时间等待这个js脚本加载完成。虽然脚本体积⼤是事实,但这⽤户体验肯定是可以优化的。
后来我⼜把这个脚本放到了页⾯底部,也就是</body>标签下⾯。这样可以先让页⾯渲染出来,再慢慢加载这个庞⼤的脚本,于是⾸页是出来的很快,但是从⾸页跳转到需要⽤到这个脚本的页⾯就会报错,如下
这个错误原因是这个页⾯需要⽤到window.DDEarth这个对象,但是由于此时这个脚本还没有加载完成,所以window下并没有这个对象,所以就报错了。
于是我⼜想到等脚本加载完成再执⾏相关⽅法,这时就需要⽤到onload这个⽅法了,onload这个⽅法在脚本加载完成的时候会执⾏。我引⼊脚本的时候给它加了个id,⽅便以后通过dom到,代码如下:
// ⼊⼝⽂件
</body>
<script id="ddEarthScript" src="./DDEarth.js"></script>
// PageTwo.js
componentDidMount() {
const scriptEle = ElementById('ddEarthScript'); // 到脚本节点
if (scriptEle) {
// 脚本加载完成执⾏加载地图的操作
this.loadEarthMap();
};
}
}
有了以上代码我跳转到PageTwo这个页⾯的时候,会等到DDEarth.js这个脚本加载完成,再执⾏加载建筑地图的操作,这样就不会报错了。
但是这⼜有⼀个问题,就是如果我跳转到PageTwo的之前,DDEarth.js已经加载完成了,onload这个事件在PageTwo这个页⾯中就不⽣效了,loadEarthMap这个⽅法⾃然也就不会执⾏了。
当前页面脚本发生错误这个时候需要加⼀个判断,完整代码如下:
// PageTwo.js
componentDidMount() {
if (window.DDEarth) { // 如果跳转到此页⾯之前,脚本已加载完成
this.loadEarthMap();
} else {
const scriptEle = ElementById('ddEarthScript');
if (scriptEle) {
this.loadEarthMap();
};
}
}
}
总结⼀下我以上解决问题的步骤
在⼊⼝⽂件的底部引⼊第三⽅脚本,并给它加个id。当然也可以放在<head>⾥,但是需要额外加上html5新增的async这个属性,这样脚本才能异步加载。
在需要⽤到这个脚本的页⾯,先判断脚本有没有加载完成(我这⾥是直接判断window.DDEarth对象是否为空)。如果已经加载完成,就直接执⾏相关操作;如果没有,先通过ElementById到那个脚本,然后监听脚本的onload事件,再做相关操作。
什么情况可以⽤我以上思路?
引⼊的第三⽅脚本较⼤,加载所需时间较长
页⾯按需加载,整个项⽬只有其中某⼏个页⾯需要⽤到引⼊的第三⽅脚本
第三⽅脚本没加载完就渲染页⾯导致的页⾯报错
以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。
发布评论