Where should I put <script> tags in HTML markup?

When embedding JavaScript in an HTML document, where is the proper place to put the <script> tags and included JavaScript?

I seem to recall that you are not supposed to place these in the <head> section, but placing at the beginning of the <body> section is bad, too, since the JavaScript will have to be parsed before the page is rendered completely (or something like that). This seems to leave the end of the <body> section as a logical place for <script> tags.

So, where is the right place to put the <script> tags?

(This question references this question, in which it was suggested that JavaScript function calls should be moved from <a> tags to <script> tags. I'm specifically using jQuery, but more general answers are also appropriate.)

解答

Here's what happens when a browser loads a website with a <script> tag on it:

  1. Fetch the HTML page (e.g. index.html)
  2. Begin parsing the HTML
  3. The parser encounters a <script> tag referencing an external script file.
  4. The browser requests the script file. Meanwhile, the parser blocks and stops parsing the other HTML on your page.
  5. After some time the script is downloaded and subsequently executed.
  6. The parser continues parsing the rest of the HTML document.

Step #4 causes a bad user experience. Your website basically stops loading until you've downloaded all scripts. If there's one thing that users hate it's waiting for a website to load.

Why does this even happen?

Any script can insert its own HTML via document.write() or other DOM manipulations. This implies that the parser has to wait until the script has been downloaded & executed before it can safely parse the rest of the document. After all, the script could have inserted its own HTML in the document.

However, most JavaScript developers no longer manipulate the DOM while the document is loading. Instead, they wait until the document has been loaded before modifying it. For example:

<!-- index.html -->
<html>
<head>
<title>My Page</title>
<script type="text/javascript" src="my-script.js"></script>
</head>
<body>
<div id="user-greeting">Welcome back, user</div>
</body>
</html>

JavaScript

// my-script.js
document.addEventListener("DOMContentLoaded", function() {
// this function runs when the DOM is ready, i.e. when the document has been parsed
document.getElementById("user-greeting").textContent = "Welcome back, Bart";
});

Because your browser does not know my-script.js isn't going to modify the document until it has been downloaded & executed, the parser stops parsing.

Antiquated recommendation 过时的做法

The old approach to solving this problem was to put <script> tags at the bottom of your <body>, because this ensures the parser isn't blocked until the very end.

This approach has its own problem: the browser cannot start downloading the scripts until the entire document is parsed. For larger websites with large scripts & stylesheets, being able to download the script as soon as possible is very important for performance. If your website doesn't load within 2 seconds, people will go to another website.

In an optimal solution, the browser would start downloading your scripts as soon as possible, while at the same time parsing the rest of your document.

The modern approach

Today, browsers support the async and defer attributes on scripts. These attributes tell the browser it's safe to continue parsing while the scripts are being downloaded.

async

<script type="text/javascript" src="path/to/script1.js" async></script>
<script type="text/javascript" src="path/to/script2.js" async></script>

Scripts with the async attribute are executed asynchronously. This means the script is executed as soon as it's downloaded, without blocking the browser in the meantime.
This implies that it's possible that script 2 is downloaded & executed before script 1.

According to http://caniuse.com/#feat=script-async, 94.57% of all browsers support this.

defer

<script type="text/javascript" src="path/to/script1.js" defer></script>
<script type="text/javascript" src="path/to/script2.js" defer></script>

Scripts with the defer attribute are executed in order (i.e. first script 1, then script 2). This also does not block the browser.

Unlike async scripts, defer scripts are only executed after the entire document has been loaded.

According to http://caniuse.com/#feat=script-defer, 94.59% of all browsers support this. 94.92% support it at least partially.

An important note on browser compatibility: in some circumstances IE <= 9 may execute deferred scripts out of order. If you need to support those browsers, please read this first!

Conclusion

The current state-of-the-art is to put scripts in the <head> tag and use the async or defer attributes. This allows your scripts to be downloaded asap without blocking your browser.

The good thing is that your website should still load correctly on the 6% of browsers that do not support these attributes while speeding up the other 94%.

解答2

Non-blocking script tags can be placed just about anywhere:

<script src="script.js" async></script>
<script src="script.js" defer></script>
<script src="script.js" async defer></script>
  • async script will be executed asynchronously as soon as it is available
  • defer script is executed when the document has finished parsing
  • async defer script falls back to the defer behavior if async is not supported

Such scripts will be executed asynchronously/after document ready, which means you cannot do this:

Where should I put <script> tags in HTML markup?的更多相关文章

  1. JavaScript Madness: Dynamic Script Loading

    Introduction I've developed some pretty seriously Javascript intensive sites, where the sheer quanti ...

  2. [Javascript]2. Improve you speed! Script Execution

    Let's take a closer look at how a browser retrieves and acts on scripts.modern browser can parallel ...

  3. how to use coffee script

    TABLE OF CONTENTS TRY COFFEESCRIPT ANNOTATED SOURCE CoffeeScript is a little language that compiles ...

  4. Java Script 学习笔记 -- Ajax

    AJAX 一 AJAX预备知识:json进阶 1.1 什么是JSON? JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式.JSON是用字符串来表示Javas ...

  5. Building Applications with Force.com and VisualForce (DEV401) (二十):Visualforce Pages: Visualforce Componets (Tags)

    Dev401-021:Visualforce Pages: Visualforce Componets (Tags) Module Agenda1.Tag Basics2.Tag Bindings T ...

  6. Building Applications with Force.com and VisualForce(Dev401)(十九):Visualforce Pages: Visualforce Componets (Tags)

    Dev401-020:Visualforce Pages: Visualforce Componets (Tags) Module Agenda1.Tag Basics2.Tag Bindings T ...

  7. Ajax及跨域

    概念 Ajax Ajax,Asynchronous JavaScript and XML,字面意思:异步的 JavaScript 和 XML,是指一种创建交互式网页应用的网页开发技术. 用于异步地去获 ...

  8. jQuery-1.9.1源码分析系列(十六)ajax——jsonp原理

    json jsonp 类型 "json":  把响应的结果当作 JSON 执行,并返回一个JavaScript对象.如果指定的是json,响应结果作为一个对象,在传递给成功处理函数 ...

  9. jQuery的$.ajax

    在介绍JSONP之前,先简单的介绍一些JSON.JSON是JavaScript Object Notation的缩写,是一种轻量的.可读的基于文本的数据交换开放标准.源于JavsScript编程语言中 ...

随机推荐

  1. Oracle基本操作练习(一)

    --创建表空间 create tablespace test datafile 'c:\test.dbf' size 100m autoextend on next 10m; --删除表空间 drop ...

  2. 什么是php工厂模式

    工厂模式是我们最常用的实例化对象模式了,是用工厂方法代替new操作的一种模式.著名的Jive论坛 ,就大量使用了工厂模式,工厂模式在Java程序系统可以说是随处可见.今天我们就为大家介绍一下PHP中的 ...

  3. Arrays -数组工具类,数组转化字符串,数组排序等

    package cn.learn.basic; import java.util.Arrays; /* java.util.Arrays是一个与数组相关的工具类,含有大量静态方法,用来实现数组常见的操 ...

  4. MySQL-第五篇视图

    1.视图看上去像是表,但它又不是,它并不能存储数据.视图只是一个或者多个表的逻辑显示.使用视图的好处: 1>可以限制对数据的访问 2>可以使复杂的查询变得简单 3>提供了数据的独立性 ...

  5. Linux-第一篇linux基本认识

    1.在Linux世界中,一切皆是文件,Linux文件采用级层式的树状目录结构,在此结构中根目录是“/”. 一般linux系统的目录结构如下 目录结构说明 目录 说明 bin 存放二进制可执行文件(ls ...

  6. 【五一qbxt】day7-2 选择客栈

    停更20天祭qwq(因为去准备推荐生考试了一直在自习qwq) [noip2011选择客栈] 这道题的前置知识是DP,可以参考=>[五一qbxt]day3 动态规划 鬼知道我写的是什么emm 这道 ...

  7. NGUI的anchors属性的使用

    一,anchors锚点 我们需要明白target目标的使用,这时是你下面使用left,right,bottom和top的距离,比如我们使用目标为UI Root,这个就是摄像机的视野,所以,我们使用an ...

  8. js IntersectionObserver api

    API const options = { root: null, threshold: [0, 0.5, 1], rootMargin: '30px 100px 20px' } var io = n ...

  9. Ajax爬取百度图片

    目标网址 分析网址:http://image.baidu.com/search/index?tn=baiduimage&ipn=r&ct=201326592&cl=2& ...

  10. JavaScript—— 案例:表单验证

    QQ号:<input type="text" id="txtQQ"><span></span><br> 邮箱:& ...