When you think about improving website loading speed, you will probably try optimizing backend code, optimizing database queries, etc.But one of the easiest ways to improve speed page load is to slightly change the way a page loads JavaScript using the script
tag in its page.
The problem with the usual way of Loading JavaScript
When you load JavaScript into an HTML page, you probably often add script
tags to the head
of the page. However, there is a problem here, to understand better you need to understand how a website is rendered.
When the browser opens a web page, it will start to render the page tab by tab and start building the DOM. And whenever the renderer encounters a tag that needs to load an image or css, those requests are handled in parallel with the rendering.
But when the renderer encounters a script tag, the HTML rendering stops and waits until all scripts have been downloaded and executed. Then the render process continues to process the next parts. You can understand this process in a better way with the example below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <span class="token doctype"><!DOCTYPE html></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> html</span> <span class="token attr-name">lang</span> <span class="token attr-value"><span class="token punctuation">=</span> <span class="token punctuation">"</span> en <span class="token punctuation">"</span></span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> head</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> meta</span> <span class="token attr-name">charset</span> <span class="token attr-value"><span class="token punctuation">=</span> <span class="token punctuation">"</span> UTF-8 <span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> title</span> <span class="token punctuation">></span></span> Script in the head tag <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> title</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> script</span> <span class="token attr-name">src</span> <span class="token attr-value"><span class="token punctuation">=</span> <span class="token punctuation">"</span> index.js <span class="token punctuation">"</span></span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> script</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> head</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> body</span> <span class="token punctuation">></span></span> <span class="token comment"><!-- All the HTML content here --></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> body</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> html</span> <span class="token punctuation">></span></span> |
The impact of page loading when encountering the script tag can be quite large and mainly the impact of the script’s execution. And the actual content of the HTML page may be greater in some cases. So all the load and render times can affect the user experience because the timeout is too long.
Then we can use some of the following ways to optimize the JavaScript loading of the website.
1. Place the script tag at the bottom of the page
Putting the script
tag at the bottom of the page – after all the main content – will give you some performance improvements. The main content of the page will load and render seamlessly and will not be blocked because of the script
tag in the middle of rendering. Download and execution will be executed eventually, when all content has been rendered completely.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <span class="token doctype"><!DOCTYPE html></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> html</span> <span class="token attr-name">lang</span> <span class="token attr-value"><span class="token punctuation">=</span> <span class="token punctuation">"</span> en <span class="token punctuation">"</span></span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> head</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> meta</span> <span class="token attr-name">charset</span> <span class="token attr-value"><span class="token punctuation">=</span> <span class="token punctuation">"</span> UTF-8 <span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> title</span> <span class="token punctuation">></span></span> Script at the end of page <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> title</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> head</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> body</span> <span class="token punctuation">></span></span> <span class="token comment"><!-- All the HTML content here --></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> script</span> <span class="token attr-name">src</span> <span class="token attr-value"><span class="token punctuation">=</span> <span class="token punctuation">"</span> index.js <span class="token punctuation">"</span></span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> script</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> body</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> html</span> <span class="token punctuation">></span></span> |
Putting the script
tag at the bottom improves the load speed more than placing the head
section of the page. Here you will still have time to wait as the download of the script will not stop until the page has fully loaded. However, we will benefit from having the entire content of the web page loaded and displayed to the user, while waiting for the script to be downloaded and executed eventually. Then when the entire HTML page is completely rendered, the script is downloaded and executed, and finally the event document ready
is executed.
2. Add the async attribute to the script tag
When the render encounters a script
tag with attribule async
, the script download will be run in parallel with the HTML rendering. And the script execution will be performed immediately after the download completes, immediately pausing the rendering. Once script execution is complete, rendering resumes.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <span class="token doctype"><!DOCTYPE html></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> html</span> <span class="token attr-name">lang</span> <span class="token attr-value"><span class="token punctuation">=</span> <span class="token punctuation">"</span> en <span class="token punctuation">"</span></span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> head</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> meta</span> <span class="token attr-name">charset</span> <span class="token attr-value"><span class="token punctuation">=</span> <span class="token punctuation">"</span> UTF-8 <span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> title</span> <span class="token punctuation">></span></span> Script with async attribute <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> title</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> script</span> <span class="token attr-name">async</span> <span class="token attr-name">src</span> <span class="token attr-value"><span class="token punctuation">=</span> <span class="token punctuation">"</span> index.js <span class="token punctuation">"</span></span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> script</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> head</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> body</span> <span class="token punctuation">></span></span> <span class="token comment"><!-- All the HTML content here --></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> body</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> html</span> <span class="token punctuation">></span></span> |
However because of the size difference between the different script files and async
executing scripts as soon as they are fully loaded, there’s no guarantee they are executed one after another in the order they were written. in code. So if there are any dependencies between scripts, for example if one script needs to be executed after another, then you should avoid using this attribute. In this case, you cannot be sure of a particular time when the render is complete and when the document ready
event is triggered.
3. Add the defer attribute to the script tag
When the render encounters a script
tag containing the defer
attribute, the download will be done in parallel with the rendering of the HTML page. Script execution will be performed only after the HTML rendering has been completed.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <span class="token doctype"><!DOCTYPE html></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> html</span> <span class="token attr-name">lang</span> <span class="token attr-value"><span class="token punctuation">=</span> <span class="token punctuation">"</span> en <span class="token punctuation">"</span></span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> head</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> meta</span> <span class="token attr-name">charset</span> <span class="token attr-value"><span class="token punctuation">=</span> <span class="token punctuation">"</span> UTF-8 <span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> title</span> <span class="token punctuation">></span></span> Script with defer attribute <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> title</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> script</span> <span class="token attr-name">defer</span> <span class="token attr-name">src</span> <span class="token attr-value"><span class="token punctuation">=</span> <span class="token punctuation">"</span> index.js <span class="token punctuation">"</span></span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> script</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> head</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> body</span> <span class="token punctuation">></span></span> <span class="token comment"><!-- All the HTML content here --></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> body</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> html</span> <span class="token punctuation">></span></span> |
When you use the defer
attribute, the script execution order will be guaranteed in the order in which the script was declared. Adding this property will help execute scripts after all HTML has been rendered and before document ready
is triggered.
summary
Let’s summarize the things above:
- Place the
script
tag at the bottom of the page to avoid blocking rendering, then load the script and execute each one when rendering is complete. - Use the
async
attribute in thescript
tag to download the script in parallel with the HTML element rendering and execute it as soon as it is ready. - Use the
defer
attribute in thescript
tag to download the script in parallel with the HTML element rendering and execute it only the entire HTML page has been completely rendered.