为了尝试异步加载谷歌地图,我看了google's async page
基本上我正在寻找API中的document.write的替代方案,并且根据this google group post上的一些用户,使用异步版本将处理这种情况。
我的问题是为什么会这个剧本:
<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&sensor=SET_TO_TRUE_OR_FALSE"
type="text/javascript"></script>
与...不同:
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&sensor=TRUE_OR_FALSE&callback=initialize";
document.body.appendChild(script);
当第一个和第二个都调用同一个显然有document.write的js文件时?另外,如果写入通常违反内容安全策略,为什么更新后的API会考虑使用document.write over append?
作为一个小背景信息,我正在尝试使用Google的打包应用,而csp不允许使用document.write。
答案 0 :(得分:4)
异步/动态加载脚本(或其他资源)的一个主要优点是它可以大大加快页面加载时间。
来自Google的开发者最佳做法:
https://developers.google.com/speed/docs/best-practices/rtt#PreferAsyncResources
当浏览器解析传统的脚本标记时,它必须等待 在呈现任何HTML之前下载,解析和执行的脚本 来之后。但是,使用异步脚本,浏览器可以 继续解析并呈现异步脚本之后的HTML, 无需等待该脚本完成。加载脚本时 异步,它是尽快获取,但它的执行 延迟到浏览器的UI线程不忙于执行某些操作 否则,例如渲染网页。
我用来决定是否异步加载脚本(例如Google Maps API)的另一个技巧是,我问自己,“用户是否有可能看不到,受益或与结果互动加载的脚本?“如果答案是肯定的,那么我通常会将脚本加载到一些DOM事件(例如按钮点击等)。
换句话说,如果用户必须点击我网页上的按钮才能查看我的Google地图;如果用户有可能永远不会看到它,为什么还要加载所有额外的脚本呢?而是在单击按钮时异步加载脚本,然后加载我的地图。
答案 1 :(得分:1)
实际上,maps.googleapis.com/maps/api/js上的javascript文件是动态文件。服务器使用不同的js文件响应不同的参数。要了解其中的差异,只需从浏览器地址栏中加载以下文件即可。
https://maps.googleapis.com/maps/api/js?v=3.exp 和 https://maps.googleapis.com/maps/api/js?v=3.exp&callback=initialize
你会注意到有一个&#34; document.write&#34;在第一个js文件中引用如下
function getScript(src) {
document.write('<' + 'script src="' + src + '"' +
' type="text/javascript"><' + '/script>');
}
而第二种情况下有一个document.createElement,如下所示
function getScript(src) {
var s = document.createElement('script');
s.src = src;
document.body.appendChild(s);
}
不同之处在于,当同步加载脚本时,浏览器会等待它完全加载,当脚本调用document.write时,文本会附加到正在加载的文档中。但是,一旦文档完全加载,就会进行异步调用。因此,document.write将替换现有文档,因此浏览器会忽略来自异步加载脚本的此类调用。使用&#34; callback = initialize&#34;加载js时,自执行函数已经包含了对初始化的回调,以及一个可以异步加载其他脚本的修改函数。
答案 2 :(得分:0)
您需要做的就是设置一个在地图脚本加载后执行的回调:
然后在您应用的主.js
文件中,定义回调:
window.myCallbackFuction = function() {
return console.log("Loaded Google Maps!");
// the rest of the maps initialization goes here, per the docs
};
棘手的部分是重构您的代码,以便在您确定myCallbacFuction()
已执行之前,不会执行任何与地图相关的代码。
答案 3 :(得分:-1)
how to load Google maps asynchronously上有一个例子。基本思想是像你一样创建一个脚本标签,让这个函数在onload上执行。