前言
最近在优化之前写的网站,FP 大概要半分钟才能加载出来,emmm,我写的。。。
这个也是之前文章优化的一部分,因为我的网页中有用到地图,之前用的 vue-amap
组件,后来觉得这个引用 cdn 不知道怎么下手,就改成了直接用节点渲染,不用组件了。然后又查了异步加载的方式,发现了一个解决方案,但是后期又发现了这个解决方案的一些 bug,一通百度加自己尝试修改了一下。
正文
先贴一下原文的解决方案:
1. 创建一个 AMap.js,路径’src/assets/js/AMap.js'
// src/assets/js/AMap.js
export default function MapLoader() {
// <-- 原作者这里使用的是module.exports
return new Promise((resolve, reject) => {
if (window.AMap) {
resolve(window.AMap)
} else {
var script = document.createElement('script')
script.type = 'text/javascript'
script.async = true
script.src =
'http://webapi.amap.com/maps?v=1.3&callback=initAMap&key=yourkey'
script.onerror = reject
document.head.appendChild(script)
}
window.initAMap = () => {
resolve(window.AMap)
}
})
}
2. 在任何.vue 文件中使用
// test.vue
<template>
<div class="test">
<div id="container" class="h300 w300"></div>
</div>
</template>
<script>
import MapLoader from '@/assets/js/AMap.js'
export default {
name: 'test',
data() {
return {
map: null,
}
},
mounted() {
let that = this
MapLoader().then(
(AMap) => {
console.log('地图加载成功')
that.map = new AMap.Map('container', {
center: [117.000923, 36.675807],
zoom: 11,
})
},
(e) => {
console.log('地图加载失败', e)
}
)
},
}
</script>
遇到的问题
- 我 copy 代码之后,回调函数中获取不到
AMap
。 不清楚 window.init 这个事件或是函数是什么意思。这里参考文档给出的异步加载方案,其中有用到 window.init ,我在网页中打印 window 并没有 init 这个属性,这里是不是还需要再进行调用? 然后,我就将 window.init 修改为 window.onload,等 js 资源加载完成后再将 AMap 对象返回给回调函数。然后就能获取到了。 等我后来调试的时候,又遇到了 bug2 号。 - 若首次打开的页面不包含加载了地图的组件,经路由跳转后追加的脚本,回调函数也拿不到 AMap 对象。 因为 window.onload 只在首次页面资源加载完成后调用。vue 切换路由只是切换了节点中的内容,并未刷新页面。所以追加了 script 标签后,并不会再执行 window.onload 了,就拿不到脚本解析后 AMap 对象了。 恰好我上午看到了相关内容就又做了修改,将 window.onload 替换为 script.onload (意思为脚本资源加载完成),目前暂时解决问题了。 load 的文档。
参考文献
(ps: 点击文献都可以直达文章)
-
load 事件: 当一个资源及其依赖资源已完成加载时,将触发 load 事件。
-
window 的 onload 事件和 domcontentloaded 执行顺序
onload 事件支持
我们首先来看一下都有哪些支持onload事件。
- 支持该事件的 HTML 标签:
<body>
,<frame>
,<frameset>
,<iframe>
,<img>
,<link>
,<script>
; - 支持该事件的 JavaScript 对象:image, layer, window
- 支持该事件的 HTML 标签:
-
<!DOCTYPE HTML> <html> <head> <meta charset="utf-8"> <title>img - load event</title> </head> <body> <img id="img1" src="http://pic1.win4000.com/wallpaper/f/51c3bb99a21ea.jpg"> <p id="p1">loading...</p> <script type="text/javascript"> img1.onload = function() { p1.innerHTML = 'loaded' } </script> </body> </html>
以上。😆