3

为了尝试异步加载谷歌地图,我查看了谷歌的异步页面

本质上,我正在寻找 API 中 document.write 的替代方案,并且根据此 google 群组帖子中的一些用户的说法,使用异步版本将处理这种情况。

我的问题是为什么这个脚本:

<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);

当第一个和第二个都调用同一个 js 文件时,其中显然包含 document.write?另外,如果写入通常违反内容安全策略,为什么更新的 API 要考虑使用 document.write 而不是 append?

作为一些背景信息,我正在尝试使用 Google 的打包应用程序,并且他们的csp不允许 document.write。

4

4 回答 4

4

异步/动态加载脚本(或其他资源)的主要优点之一是它可以显着加快页面加载时间。

来自谷歌的开发者最佳实践:

https://developers.google.com/speed/docs/best-practices/rtt#PreferAsyncResources

当浏览器解析一个传统的脚本标签时,它必须等待脚本下载、解析和执行,然后再渲染它之后的任何 HTML。但是,使用异步脚本,浏览器可以继续解析和呈现异步脚本之后的 HTML,而无需等待该脚本完成。当一个脚本被异步加载时,它会尽快被获取,但它的执行被推迟到浏览器的 UI 线程不忙于做其他事情,比如渲染网页。

我用来决定是否异步加载脚本(例如 Google Maps API)的另一个技巧是,我问自己,“用户是否有可能看不到、受益或与加载的结果交互?脚本?”。如果答案是肯定的,那么我通常会将脚本的加载与一些 DOM 事件(例如按钮单击等)联系起来。

换句话说,如果用户必须单击我网页上的按钮才能查看我的 Google 地图;如果用户有可能永远看不到它,为什么还要加载所有额外的脚本呢?相反,单击按钮时异步加载脚本,然后加载我的地​​图。

于 2013-02-02T06:09:08.207 回答
1

实际上,maps.googleapis.com/maps/api/js 上的 javascript 文件是动态文件。服务器使用不同的 js 文件响应不同的参数。要知道区别,只需从浏览器地址栏中加载以下文件。

https://maps.googleapis.com/maps/api/js?v=3.exphttps://maps.googleapis.com/maps/api/js?v=3.exp&callback=initialize

您会注意到第一个 js 文件中有一个“document.write”,如下所示

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 将替换现有文档,因此浏览器会忽略来自异步加载脚本的此类调用。当你用“callback=initialize”加载js时,自执行函数已经包含了初始化的回调,以及一个可以异步加载更多脚本的修改函数。

于 2014-06-14T11:38:11.787 回答
0

您所要做的就是设置一个在地图脚本加载后执行的回调:

然后在您的应用程序的主.js文件中,定义回调:

window.myCallbackFuction = function() {
  return console.log("Loaded Google Maps!");
  // the rest of the maps initialization goes here, per the docs
};

棘手的部分是重构您的代码,以便在您确定已执行之前不会执行任何与地图相关的代码myCallbacFuction()

于 2014-12-17T15:12:04.653 回答
-1

有一个关于如何异步加载谷歌地图的例子。基本思想是像你一样创建一个脚本标签,让这个函数在加载时执行。

于 2012-09-14T07:55:00.507 回答