As we all know, the
Script tag location
In the past, all
<! DOCTYPE html> <html> <head> <title>Example HTML Page</title> <script src="example1.js"></script> <script src="example2.js"></script> </head> <body> <! </body> </ HTML >Copy the code
The main purpose of this practice is to keep external CSS and JavaScript files in one place. However, putting all JavaScript files in means that all JavaScript code must be downloaded, parsed, and interpreted before the page can start rendering (the page starts rendering when the browser parses to the start tag of ). For pages that require a lot of JavaScript, this causes a significant delay in page rendering, during which the browser window is completely blank.
To solve this problem, modern Web applications typically place all JavaScript references after the page content in the element, as shown in the following example:
<! DOCTYPE html> <html> <head> <title>Example HTML Page</title> </head> <body> <! </script> <script SRC ="example1.js"></script> <script SRC ="example2.js"></script> </body> </ HTML >Copy the code
This way, the page renders the page completely before processing the JavaScript code. The user will feel that the page loads faster because the browser displays a blank page for less time.
The attribute of the script
1. src
Optional property. This is probably familiar, and can contain external files of the code to be executed. There should be no more embedded scripts in script element tags that specify SRC attributes. Possible values:
- Absolute URL – points to another web site (such as SRC = “www.example.com/example.js”…
- Relative URL – points to a local file (e.g. SRC =”/scripts/example.js”)
2.charset
Optional property. The code character set specified with the SRC attribute. If present, the value must match “UTF-8” case – insensitive. Of course, declaring charset is unnecessary because the page document must use UTF-8, and the script element inherits this property from the page document.
3.async
Optional property. This applies only to external script files.
First of all, what do browsers do when they parse a normal
First, it pauses parsing of the current HTML, sends a network request to load and execute the script, and resumes parsing the HTML when it’s done. In other words, the
What does the browser do when it encounters a
The web request for the script is asynchronous and does not block the browser from parsing the HTML. Once the web request is complete (that is, after the script is loaded), if the HTML has not been parsed, the browser will pause parsing, let the JAVASCRIPT script execute first, and then parse the HTML. As shown in the figure below
If the HTML has been parsed before the script request completes, the JS script code is executed immediately.
Therefore async is uncontrollable because the execution time is uncertain. If a DOM element is obtained in an asynchronous JS script, it may or may not be obtained. In addition, if there are multiple asyncs, the execution sequence between them is also uncertain. The second script may be executed before the first one, depending on the network transmission result and who is executed first.
<! DOCTYPE html> <html> <head> <title>Example HTML Page</title> <script async src="example1.js"></script> <script async src="example2.js"></script> </head> <body> <! </body> </ HTML >Copy the code
In this case, the second script might be executed before the first.
Because of this, asynchronous scripts should not modify the DOM during loading. Asynchronous scripts are guaranteed to be executed before the page’s load event, but may be executed before or after DOMContentLoaded (explained below).
For XHTML documents, the async attribute should be specified as async=”async”.
4.defer
Optional property. Also only for external script files.
When the browser encounters
This means that the browser will start downloading the script as soon as it is parsed, but execution should be delayed until the page is parsed:
<! DOCTYPE html> <html> <head> <title>Example HTML Page</title> <script defer src="example1.js"></script> <script defer src="example2.js"></script> </head> <body> <! </body> </ HTML >Copy the code
Although the
For XHTML documents, the defer attribute should be specified as defer=”defer”.
OK, let’s rearrange the differences between defer and Async:
-
When the defer attribute is present in a script, the loading of the script and the HTML will happen asynchronously, and the script will not be executed until the HTML has been parsed.
-
When a script has an async property, the loading of the script and the loading of the HTML also happens asynchronously. However, after the script is downloaded, THE HTML parsing stops and the script is executed. After the script is parsed, the HTML parsing continues.
-
When a script has both async and defer properties, the effect is the same as async.
5.crossorigin
Optional property. CORS (Cross-domain resource sharing) Settings used to configure related requests. CORS is not used by default.
Crossorigin =”anonymous” profile requests do not have to set credential flags.
Crossorigin =”use-credentials” sets the credential flag, which means that outbound requests contain credentials.
6.language
Has been abandoned. Most browsers ignore this property and should not use it again. Replace this attribute with the Type attribute.
7.type
Optional property, used instead of language, that represents the content type of the scripting language in the code block (also known as the MIME type Multipurpose Internet Mail Extensions).
By convention, this value is always “text/javascript”, although both “text/javascript” and “text/ecmascript” are deprecated. The MIME type of a JavaScript file is usually “application/ X-javascript “, although giving this value to the type attribute can cause the script to be ignored. Other values that work in non-IE browsers are “application/javascript” and “application/ecmascript”.
If the value is module, the code is treated as an ES6 module, and only then can the import and export keywords appear in the code.
8.integrity
Optional property. It allows comparisons between received resources and specified signatures to be used to verify the integrity of sub-resources (SRI, Subresource Intergrity). If the received resource signature does not match the signature specified by this property, an error message is displayed and the script is not executed.
This property can be used to ensure that a Content Delivery Network (CDN) does not serve malicious Content.
9.text
Used to set the text content of the element. This property is parsed into executable code after the node is inserted into the DOM.
DOMContentLoaded with the load
DOMContentLoaded: The DOMContentLoaded event is fired when pure HTML is fully loaded and parsed, without waiting for the stylesheet, image, or subframe to complete loading. That is, the page is triggered as soon as the DOM is loaded, without waiting for the dependent resource to load.
Load: The Load event is triggered when the entire page and all dependent resources such as stylesheets and images have finished loading.
There is a website can intuitively show the difference between these two events: testdrive-archive.azurewebsites.net/HTML5/DOMCo…
You can also go to the web section of the console and see it visually, and the vertical blue and red lines are the DOMContentLoaded and Load events, respectively.
Sync script with DOMContentLoaded:
(1) In the case of neither JS nor CSS, the parsing process of HTML documents:
As can be seen from the figure, DOMContentLoaded is triggered after DOM
(2) with CSS without JS, HTML document parsing process:
As can be seen from the figure, the trigger time of DOMContentLoaded is still after DOM, regardless of whether the process of CSS parsing into CSSOM is completed.
(3) In the case of both CSS and JS, HTML document parsing process:
As can be seen from the figure,DOMContentLoaded
The trigger is still behind the DOM. To sum up, in synchronized script tag code only,DOMContentLoaded
The execution time is as follows:
Script with async and DOMContentLoaded:
The loading of async scripts is not counted in the DOMContentLoaded event statistics, which means that the following two situations are possible:
- Before the HTML is parsed, the async script has finished loading. Then the HTML stops parsing and the script is executed. When the script is finished, the async script is triggered
DOMContentLoaded
Events.
- After the HTML is parsed, the async script is loaded, and then the script is executed. In this case, the async script will be triggered when the HTML is parsed and the async script is not loaded
DOMContentLoaded
Events.
Script and DOMContentLoaded with defer:
When the document is parsed, the script set to defer will be downloaded in the background, but the rendering of the document will not be prevented. When the page is parsed and rendered, the DOMContentLoaded event will be triggered after all the defer scripts are loaded and executed in sequence. This means that both of the following scenarios are possible:
- The script has finished loading while the HTML has not been parsed. Then wait until the HTML has been parsed and execute the script
DOMContentLoaded
Events.
- After the HTML has been parsed, defer script has loaded and then executed, which is triggered
DOMContentLoaded
Events.
Dynamically loading scripts
There are other ways to load scripts besides the
let script = document.createElement('script');
script.src = 'gibberish.js';
document.head.appendChild(script);
Copy the code
Of course, the request will not be sent until the HTMLElement element is added to the DOM and this code is executed. By default,
Therefore, if you want to unify the loading behavior of dynamic scripts, you can explicitly set it to synchronous loading:
let script = document.createElement('script');
script.src = 'gibberish.js';
script.async = false;
document.head.appendChild(script);
Copy the code
Resources obtained in this way are not visible to the browser preloader. This can seriously affect their priority in the resource acquisition queue. Depending on how the application works and how it is used, this can have a significant impact on performance. To let the preloader know of the existence of these dynamic request files, declare them explicitly in the document header:
<link rel="preload" href="gibberish.js">
Copy the code
Precautions for the script tag
1. tags. If both are provided, the browser simply downloads and executes the script file, ignoring the inline code.
is not restricted by the same origin policy of the browser, allowing us to request resources across domains to obtain the corresponding resources. Code from an external domain is loaded and interpreted as part of the page that loaded it. This capability allows us to distribute JavaScript across different domains. However, be careful when referencing a JavaScript file that sits on someone else’s server, because malicious programmers can replace the file at any time. When you include JavaScript files for an external domain, make sure that the domain is your own or that it is a trusted source. The integrity property of the
3. When using inline JavaScript code, be careful not to include the string in your code. For example, the following code causes the browser to report an error:
<script>
function sayScript() {
console.log("</script>");
}
</script>
Copy the code
The way the browser parses the inline script determines that when it sees the string , it will treat it as a closing tag. To avoid this problem, just escape the character “\” :
<script>
function sayScript() {
console.log("<\/script>");
}
</script>
Copy the code
Noscript tags
To address the problem of early browsers not supporting JavaScript, a solution to gracefully degrade pages was needed. Eventually, the
A
- Browsers do not support scripting;
- Browser support for scripts is turned off.
If any of these conditions are met, the content contained in
For example, the index.html file in the Vue scaffolding development environment uses this tag:
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
Copy the code
Here’s another tip: How do I disable JavaScript in the browser?
(PS: Use this trick if you want to copy large chunks of text from a library for free.)
Open the console and click the gear shown
Scroll down to find the debugger and hit Deactivate
That’s all for this article
This is my first nuggets article, if you have a little help, I hope to support more ~
reference
DOMContentLoaded: blog.csdn.net/qq_32682137… Async and defer properties in the illustrated Script tag: juejin.cn/post/689462…