一、异步加载
1. 为什么选择异步加载
浏览器解析html文件时,从上向下解析构建DOM树。当解析到script标签时,会暂停DOM构建。先把脚本加载并执行完毕,才会继续向下解析。js脚本的存在会阻塞DOM解析,进而影响页面渲染速度。
2. 处理js脚本的常规操作
1. js和html混合在一起的场景
- 将script标签放在html文件的底部,避免解析DOM时被阻塞。
2. js和html分开场景,js是单独的文件。
方式一:利用HTML5新特性
async 和 defer 属性
注意:只适用于外部脚本
javascript<script type="text/javascript" defer="defer" src="xxx.js"/>
区别:
两种属性用于异步加载脚本,都是采用并行下载,在下载的过程中不会产生阻塞。区别在于执行时机,async 是加载完成后立刻执行,defer 需要等待页面完成后执行。
方式二:创建动态脚本元素
动态创建script标签
设置src属性,指向所需要加载的js路径
加入head中,注意最好加入head中,因为加入body里面,可能会导致IE抛出一个操作已终止的错误信息。
javascriptconst script = document.createElement('script'); script.type = 'text/javascript'; script.src = 'xxxx.js'; document.head.appendChild(script);
3. 百度地图api提供的加载方式
方式一:demo演示,直接使用script标签
javascript<script type="text/javascript" src="https://api.map.baidu.com/api?v=1.0&type=webgl&ak=您的密钥">
- 如果加载时遇到
1 A parser-blocking, cross site (i.e. different eTLD+1) script,
将api换成getscript即可。https://api.map.baidu.com/getscript?v=1.0&type=webgl&ak=您的密钥
- 如果加载时遇到
方式二:使用创建动态脚本元素方式
javascript<script type="text/javascript"> function initialize() { var mp = new BMapGL.Map('map'); mp.centerAndZoom(new BMapGL.Point(121.491, 31.233), 11); } function loadScript() { var script = document.createElement("script"); script.src = "https://api.map.baidu.com/api?v=1.0&type=webgl&ak=您的密钥&callback=initialize"; document.head.appendChild(script); } window.onload = loadScript; </script>
4. 加载百度地图示例
html
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>异步加载</title>
<style type="text/css">
html {
height: 100%
}
body {
height: 100%;
margin: 0px;
padding: 0px
}
#container {
height: 100%
}
</style>
</head>
<body>
<div id="container" />
</body>
<script type="text/javascript">
function initialize() {
// 创建地图实例
var mp = new BMapGL.Map('container');
// 初始化地图,设置中心点坐标和地图级别
mp.centerAndZoom(new BMapGL.Point(121.491, 31.233), 11);
}
function loadScript() {
var script = document.createElement("script");
script.src = "https://api.map.baidu.com/api?v=1.0&type=webgl&ak=m24Wn3uhofXRWnkMgYLyGPY0LKCvKTkt&callback=initialize";
document.head.appendChild(script);
}
window.onload = loadScript;
</script>
</html>
注意点:高度必须设置,否则会显示不出百度地图,如果设置的是100%,那就需要父节点加本身都是100%,如下:
html
<div class="container">
<div id="map" />
</div>
5. 当百度api遇到vue
1. 组件式封装产生的问题
场景:因为你的地图,不可能只是单纯的地图容器,地图下面还有其他的组件。
html<template> <div class="container"> <div class="map_container" ref="map_container" /> <v-switch/> </div> </template>
现象:即使你给所有的父组件的高度设置为100%,依旧无法显示地图
解决方案:在map_container的class样式里加上
绝对定位
。css.map_container { position: absolute; width: 100%; height: 100%; }
2. vue的异步加载
新建bmapGL.js
jsconst ak = 'xxx'; /** * 异步加载百度地图 * @returns { Promise } * @constructor */ const loadBMapGL = () => new Promise((resolve, reject) => { window.init = async () => { resolve(window.BMapGL); }; if (window.BMapGL) { return resolve(window.BMapGL) } const script = document.createElement('script'); script.type = 'text/javascript'; script.src = `//api.map.baidu.com/api?v=1.0&type=webgl&ak=${ak}&callback=init`; script.onerror = reject; document.head.appendChild(script); }); export default loadBMapGL
在对应组件的生命周期函数mounted中调用
js// 引入异步引入地图的方法 import loadBMapGL from "@/utils/bmap"; // 调用加载地图 loadBMapGL().then(() => { // 初始化地图 })