问题
The Google Maps javascript does some heavy DOM manipulation. Even so, the fine docs suggest to load it with the defer flag:
<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap" async defer></script>
Why would the defer flag be suggested for a script that performs DOM manipulations? I ask to learn both about the defer flag and to learn about the Google Maps API as I seem to have a misunderstanding about what one of them is doing.
回答1:
Normally, a script tag tells the browser to stop parsing the HTML, fetch the script, run it, and only then continue parsing the HTML. This is because the script code may use document.write to output to the HTML token stream.
async and defer are both mechanisms for telling the browser that it's okay to go ahead and keep parsing the HTML in parallel with downloading the script file, and to run the script file later, not right away.
They slightly different, though; this diagram from the script section of the WHAT-WG version of the HTML spec is useful for envisioning the differences:
Full details in the linked spec above, but in brief, for "classic" scripts (the kind you're used to; but module scripts are coming soon!):
- Both
asyncanddeferallow the parsing of the HTML to continue without waiting for the script to download. deferwill make the browser wait to execute the script until the parsing is complete.asyncwill only make the browser wait until the script download is complete, which means it may run the script either before parsing is complete or afterward, depending on when download finishes (and remember it could come from cache).- If
asyncis present and supported by the browser, it takes precedence overdefer. asyncscripts may be run in any order, regardless of the order in which they appear in the HTML.deferscripts will be run in the order they appear in the HTML, once parsing is complete.asyncanddeferare well-supported in even semi-modern browsers, but are not properly supported in IE9 and earlier, see here and here.
Why would the
deferflag be suggested for a script that performs DOM manipulations?
Two reasons:
- It allows the parsing to continue while the script is downloaded, and
- It means the script isn't run until parsing is complete.
If you didn't use defer and you placed your script tags non-optimally, using defer helps the API script behave properly by letting the browser finish building the DOM before the script tries to manipulate it.
A lot of people still put script tags in the head section of the document, even though that's usually the worst place to put them unless you use defer (or async). In most cases, the best place (unless you have a reason to do something else) is at the very end, just before the closing </body> tag, so that A) Your site renders quickly, without waiting for scripts; and B) The DOM is fully built before you try to manipulate it. Recommending defer may be saving them support hassles from people putting their script tags too early in the HTML.
回答2:
The google maps examples use both async and defer flags.
- The
asyncflag allows the script to load in parallel to the DOM parsing, and to execute as soon as the API is ready. - The
deferflag allows the script to load in parallel to the DOM parsing, but guarantees that the script will not execute until the DOM is finished parsing.
async is supported by modern HTML5 browsers, while defer support is universal. When the tags are used together, defer is just a fallback for older browsers, and will be ignored if async is supported.
In these simple examples, either async or defer will work, though neither are necessary. In this case it's for performance only.
Refs:
Speed up Google Maps(and everything else) with async & defer
async vs defer attributes - Growing with the Web
来源:https://stackoverflow.com/questions/36909380/why-use-defer-with-google-maps-javascript