When loading a script on an HTML page, you need to be careful not to harm the loading performance of the page. Depending on where and how you add your scripts to an HTML page will influence the loading time
When loading a script on an HTML page, you need to be careful not to harm the loading performance of the page.
A script is traditionally included in the page in this way:
<scriptsrc="script.js"></script>
whenever the HTML parser finds this line, a request will be made to fetch the script, and the script is executed.
Once this process is done, the parsing can resume, and the rest of the HTML can be analyzed.
As you can imagine, this operation can have a huge impact on the loading time of the page.
If the script takes a little longer to load than expected, for example if the network is a bit slow or if you’re on a mobile device and the connection is a bit sloppy, the visitor will likely see a blank page until the script is loaded and executed.
THE POSITION MATTERS
When you first learn HTML, you’re told script tags live in the <head> tag:
As I told earlier, when the parser finds this line, it goes to fetch the script and executes it. Then, after it’s done with this task, it goes on to parse the body.
This is bad because there is a lot of delay introduced. A very common solution to this issue is to put the script tag to the bottom of the page, just before the closing </body> tag.
Doing so, the script is loaded and executed after all the page is already parsed and loaded, which is a huge improvement over the head alternative.
This is the best thing you can do, if you need to support older browsers that do not support two relatively recent features of HTML: async and defer.
ASYNC AND DEFER
Both async and defer are boolean attributes. Their usage is similar:
<scriptasyncsrc="script.js"></script>
<scriptdefersrc="script.js"></script>
if you specify both, async takes precedence on modern browsers, while older browsers that support defer but not async will fallback to defer.
These attributes make only sense when using the script in the head portion of the page, and they are useless if you put the script in the body footer like we saw above.
PERFORMANCE COMPARISON
NO DEFER OR ASYNC, IN THE HEAD
Here’s how a page loads a script without neither defer or async, put in the headportion of the page:
The parsing is paused until the script is fetched, and executed. Once this is done, parsing resumes.
NO DEFER OR ASYNC, IN THE BODY
Here’s how a page loads a script without neither defer or async, put at the end of the body tag, just before it closes:
The parsing is done without any pauses, and when it finishes, the script is fetched, and executed. Parsing is done before the script is even downloaded, so the page appears to the user way before the previous example.
WITH ASYNC, IN THE HEAD
Here’s how a page loads a script with async, put in the head tag:
The script is fetched asynchronously, and when it’s ready the HTML parsing is paused to execute the script, then it’s resumed.
WITH DEFER, IN THE HEAD
Here’s how a page loads a script with defer, put in the head tag:
The script is fetched asynchronously, and it’s executed only after the HTML parsing is done.
Parsing finishes just like when we put the script at the end of the body tag, but overall the script execution finishes well before, because the script has been downloaded in parallel with the HTML parsing.
So this is the winning solution in terms of speed 🏆
BLOCKING PARSING
async blocks the parsing of the page while defer does not.
BLOCKING RENDERING
Neither async nor defer guarantee anything on blocking rendering. This is up to you and your script (for example, making sure your scripts run after the onLoad) event.
DOMINTERACTIVE
Scripts marked defer are executed right after the domInteractive event, which happens after the HTML is loaded, parsed and the DOM is built.
CSS and images at this point are still to be parsed and loaded.
Once this is done, the browser will emit the domComplete event, and then onLoad.
domInteractive is important because its timing is recognized as a measure of perceived loading speed. See the MDN for more.
KEEPING THINGS IN ORDER
Another case pro defer: scripts marked async are executed in casual order, when they become available. Scripts marked defer are executed (after parsing completes) in the order which they are defined in the markup.
TL;DR, TELL ME WHAT’S THE BEST
The best thing to do to speed up your page loading when using scripts is to put them in the head, and add a defer attribute to your script tag:
<scriptdefersrc="script.js"></script>
This is the scenario that triggers the faster domInteractive event.
Considering the pros of defer, is seems a better choice over async in a variety of scenarios.
Unless you are fine with delaying the first render of the page, making sure that when the page is parsed the JavaScript you want is already executed.
Regular expressions are patterns used to match character combinations in strings. In JavaScript, regular expressions are also objects. These patterns are used with the exec and test methods of RegExp, and with the match, replace, search, and splitmethods of String. This chapter describes JavaScript regular expressions.
You construct a regular expression in one of two ways:
Using a regular expression literal, which consists of a pattern enclosed between slashes, as follows:
var re =/ab+c/;
Regular expression literals provide compilation of the regular expression when the script is loaded. If the regular expression remains constant, using this can improve performance.
Or calling the constructor function of the RegExp object, as follows:
var re =newRegExp('ab+c');
Using the constructor function provides runtime compilation of the regular expression. Use the constructor function when you know the regular expression pattern will be changing, or you don't know the pattern and are getting it from another source, such as user input.
A regular expression pattern is composed of simple characters, such as /abc/, or a combination of simple and special characters, such as /ab*c/ or /Chapter (\d+)\.\d*/. The last example includes parentheses which are used as a memory device. The match made with this part of the pattern is remembered for later use, as described in Using parenthesized substring matches.
Simple patterns are constructed of characters for which you want to find a direct match. For example, the pattern /abc/ matches character combinations in strings only when exactly the characters 'abc' occur together and in that order. Such a match would succeed in the strings "Hi, do you know your abc's?" and "The latest airplane designs evolved from slabcraft." In both cases the match is with the substring 'abc'. There is no match in the string 'Grab crab' because while it contains the substring 'ab c', it does not contain the exact substring 'abc'.
When the search for a match requires something more than a direct match, such as finding one or more b's, or finding white space, the pattern includes special characters. For example, the pattern /ab*c/ matches any character combination in which a single 'a' is followed by zero or more 'b's (* means 0 or more occurrences of the preceding item) and then immediately followed by 'c'. In the string "cbbabbbbcdebc," the pattern matches the substring 'abbbbc'.
The following table provides a complete list and description of the special characters that can be used in regular expressions.
A backslash that precedes a non-special character indicates that the next character is special and is not to be interpreted literally. For example, a 'b' without a preceding '\' generally matches lowercase 'b's wherever they occur. But a '\b' by itself doesn't match any character; it denotes a word boundary.
A backslash that precedes a special character indicates that the next character is not special and should be interpreted literally. For example, the pattern /a*/ relies on the special character '*' to match 0 or more a's. By contrast, the pattern /a\*/denotes the '*' as not special, enabling matches with strings like 'a*'.
Do not forget to escape \ itself while using the RegExp("pattern") notation because \ is also an escape character in strings.
Matches beginning of input. If the multiline flag is set to true, also matches immediately after a line break character.
For example, /^A/ does not match the 'A' in "an A", but does match the 'A' in "An E".
The '^' has a different meaning when it appears as the first character in a character set pattern. See complemented character setsfor details and an example.
Matches the preceding expression 0 or 1 time. Equivalent to {0,1}.
For example, /e?le?/ matches the 'el' in "angel" and the 'le' in "angle" and also the 'l' in "oslo".
If used immediately after any of the quantifiers *, +, ?, or {}, makes the quantifier non-greedy (matching the fewest possible characters), as opposed to the default, which is greedy (matching as many characters as possible). For example, applying /\d+/to "123abc" matches "123". But applying /\d+?/ to that same string matches only the "1".
Also used in lookahead assertions, as described in the x(?=y) and x(?!y) entries of this table.
Matches 'x' and remembers the match, as the following example shows. The parentheses are called capturing parentheses.
The '(foo)' and '(bar)' in the pattern /(foo) (bar) \1 \2/ match and remember the first two words in the string "foo bar foo bar". The \1 and \2 denote the first and second parenthesized substring matches - foo and bar, matching the string's last two words. Note that \1, \2, ..., \n are used in the matching part of the regex, for more information, see \n below. In the replacement part of a regex the syntax $1, $2, ..., $n must be used, e.g.: 'bar foo'.replace(/(...) (...)/, '$2 $1'). $& means the whole matched string.
Matches 'x' but does not remember the match. The parentheses are called non-capturing parentheses, and let you define subexpressions for regular expression operators to work with. Consider the sample expression /(?:foo){1,2}/. If the expression was /foo{1,2}/, the {1,2} characters would apply only to the last 'o' in 'foo'. With the non-capturing parentheses, the {1,2} applies to the entire word 'foo'. For more information, see Using parentheses below.
Matches 'x' only if 'x' is followed by 'y'. This is called a lookahead.
For example, /Jack(?=Sprat)/ matches 'Jack' only if it is followed by 'Sprat'. /Jack(?=Sprat|Frost)/ matches 'Jack' only if it is followed by 'Sprat' or 'Frost'. However, neither 'Sprat' nor 'Frost' is part of the match results.
Matches 'x' only if 'x' is not followed by 'y'. This is called a negated lookahead.
For example, /\d+(?!\.)/ matches a number only if it is not followed by a decimal point. The regular expression /\d+(?!\.)/.exec("3.141") matches '141' but not '3.141'.
Matches 'x', or 'y' (if there is no match for 'x').
For example, /green|red/ matches 'green' in "green apple" and 'red' in "red apple." The order of 'x' and 'y' matters. For example a*|b matches the empty string in "b", but b|a* matches "b" in the same string.
Where n and m are positive integers and n <= m. Matches at least n and at most m occurrences of the preceding expression. When m is omitted, it's treated as ∞.
For example, /a{1,3}/ matches nothing in "cndy", the 'a' in "candy," the first two a's in "caandy," and the first three a's in "caaaaaaandy". Notice that when matching "caaaaaaandy", the match is "aaa", even though the original string had more a's in it.
Character set. This pattern type matches any one of the characters in the brackets, including escape sequences. Special characters like the dot(.) and asterisk (*) are not special inside a character set, so they don't need to be escaped. You can specify a range of characters by using a hyphen, as the following examples illustrate.
The pattern [a-d], which performs the same match as [abcd], matches the 'b' in "brisket" and the 'c' in "city". The patterns /[a-z.]+/ and /[\w.]+/ match the entire string "test.i.ng".
A negated or complemented character set. That is, it matches anything that is not enclosed in the brackets. You can specify a range of characters by using a hyphen. Everything that works in the normal character set also works here.
For example, [^abc] is the same as [^a-c]. They initially match 'r' in "brisket" and 'h' in "chop."
Matches a word boundary. A word boundary matches the position between a word character followed by a non-word character, or between a non-word character followed by a word character, or the beginning of the string, or the end of the string. A word boundary is not a "character" to be matched; like an anchor, a word boundary is not included in the match. In other words, the length of a matched word boundary is zero. (Not to be confused with [\b].)
Examples using the input string "moon": /\bm/ matches, because the `\b` is at the beginning of the string; the '\b' in /oo\b/ does not match, because the '\b' is both preceded and followed by word characters; the '\b' in /oon\b/ matches, because it appears at the end of the string; the '\b\ in /\w\b\w/ will never match anything, because it is both preceded and followed by a word character..
Note: JavaScript's regular expression engine defines a specific set of characters to be "word" characters. Any character not in that set is considered a non-word character. This set of characters is fairly limited: it consists solely of the Roman alphabet in both upper- and lower-case, decimal digits, and the underscore character. Accented characters, such as "é" or "ü" are, unfortunately, treated as non-word characters for the purposes of word boundaries, as are ideographic characters in general.
Matches a white space character, including space, tab, form feed, line feed. Equivalent to [ \f\n\r\t\v\u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff].
Where n is a positive integer, a back reference to the last substring matching the n parenthetical in the regular expression (counting left parentheses).
For example, /apple(,)\sorange\1/ matches 'apple, orange,' in "apple, orange, cherry, peach."
(only when u flag is set) Matches the character with the Unicode value hhhh (hexadecimal digits).
Escaping user input that is to be treated as a literal string within a regular expression—that would otherwise be mistaken for a special character—can be accomplished by simple replacement:
function escapeRegExp(string) {
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
}
The g after the regular expression is an option or flag that performs a global search, looking in the whole string and returning all matches. It is explained in detail below in Advanced Searching With Flags.
Parentheses around any part of the regular expression pattern causes that part of the matched substring to be remembered. Once remembered, the substring can be recalled for other use, as described in Using Parenthesized Substring Matches.
For example, the pattern /Chapter (\d+)\.\d*/ illustrates additional escaped and special characters and indicates that part of the pattern should be remembered. It matches precisely the characters 'Chapter ' followed by one or more numeric characters (\d means any numeric character and + means 1 or more times), followed by a decimal point (which in itself is a special character; preceding the decimal point with \ means the pattern must look for the literal character '.'), followed by any numeric character 0 or more times (\d means numeric character, * means 0 or more times). In addition, parentheses are used to remember the first matched numeric characters.
This pattern is found in "Open Chapter 4.3, paragraph 6" and '4' is remembered. The pattern is not found in "Chapter 3 and 4", because that string does not have a period after the '3'.
To match a substring without causing the matched part to be remembered, within the parentheses preface the pattern with ?:. For example, (?:\d+) matches one or more numeric characters but does not remember the matched characters.
Regular expressions are used with the RegExp methods test and exec and with the String methods match, replace, search, and split. These methods are explained in detail in the JavaScript reference.
A String method that uses a regular expression or a fixed string to break a string into an array of substrings.
When you want to know whether a pattern is found in a string, use the test or searchmethod; for more information (but slower execution) use the exec or match methods. If you use exec or match and if the match succeeds, these methods return an array and update properties of the associated regular expression object and also of the predefined regular expression object, RegExp. If the match fails, the exec method returns null (which coerces to false).
In the following example, the script uses the exec method to find a match in a string.
var myRe =/d(b+)d/g;var myArray = myRe.exec('cdbbdbsbz');
If you do not need to access the properties of the regular expression, an alternative way of creating myArray is with this script:
var myArray =/d(b+)d/g.exec('cdbbdbsbz');// similar to "cdbbdbsbz".match(/d(b+)d/g); however,// "cdbbdbsbz".match(/d(b+)d/g) outputs Array [ "dbbd" ], while // /d(b+)d/g.exec('cdbbdbsbz') outputs Array [ 'dbbd', 'bb', index: 1, input: 'cdbbdbsbz' ].
If you want to construct the regular expression from a string, yet another alternative is this script:
var myRe =newRegExp('d(b+)d','g');var myArray = myRe.exec('cdbbdbsbz');
With these scripts, the match succeeds and returns the array and updates the properties shown in the following table.
Results of regular expression execution.
Object
Property or index
Description
In this example
myArray
The matched string and all remembered substrings.
['dbbd', 'bb', index: 1, input: 'cdbbdbsbz']
index
The 0-based index of the match in the input string.
1
input
The original string.
"cdbbdbsbz"
[0]
The last matched characters.
"dbbd"
myRe
lastIndex
The index at which to start the next match. (This property is set only if the regular expression uses the g option, described in Advanced Searching With Flags.)
5
source
The text of the pattern. Updated at the time that the regular expression is created, not executed.
"d(b+)d"
As shown in the second form of this example, you can use a regular expression created with an object initializer without assigning it to a variable. If you do, however, every occurrence is a new regular expression. For this reason, if you use this form without assigning it to a variable, you cannot subsequently access the properties of that regular expression. For example, assume you have this script:
var myRe =/d(b+)d/g;var myArray = myRe.exec('cdbbdbsbz');
console.log('The value of lastIndex is '+ myRe.lastIndex);// "The value of lastIndex is 5"
However, if you have this script:
var myArray =/d(b+)d/g.exec('cdbbdbsbz');
console.log('The value of lastIndex is '+/d(b+)d/g.lastIndex);// "The value of lastIndex is 0"
The occurrences of /d(b+)d/g in the two statements are different regular expression objects and hence have different values for their lastIndex property. If you need to access the properties of a regular expression created with an object initializer, you should first assign it to a variable.
Including parentheses in a regular expression pattern causes the corresponding submatch to be remembered. For example, /a(b)c/ matches the characters 'abc' and remembers 'b'. To recall these parenthesized substring matches, use the Array elements [1], ..., [n].
The number of possible parenthesized substrings is unlimited. The returned array holds all that were found. The following examples illustrate how to use parenthesized substring matches.
The following script uses the replace() method to switch the words in the string. For the replacement text, the script uses the $1 and $2 in the replacement to denote the first and second parenthesized substring matches.
var re =/(\w+)\s(\w+)/;var str ='John Smith';var newstr = str.replace(re,'$2, $1');
console.log(newstr);// "Smith, John"
Regular expressions have five optional flags that allow for global and case insensitive searching. These flags can be used separately or together in any order, and are included as part of the regular expression.
Regular expression flags
Flag
Description
g
Global search.
i
Case-insensitive search.
m
Multi-line search.
u
unicode; treat a pattern as a sequence of unicode code points
y
Perform a "sticky" search that matches starting at the current position in the target string. See sticky
To include a flag with the regular expression, use this syntax:
var re =/pattern/flags;
or
var re =newRegExp('pattern','flags');
Note that the flags are an integral part of a regular expression. They cannot be added or removed later.
For example, re = /\w+\s/g creates a regular expression that looks for one or more characters followed by a space, and it looks for this combination throughout the string.
var re =/\w+\s/g;var str ='fee fi fo fum';var myArray = str.match(re);
console.log(myArray);// ["fee ", "fi ", "fo "]
You could replace the line:
var re =/\w+\s/g;
with:
var re =newRegExp('\\w+\\s','g');
and get the same result.
The behavior associated with the 'g' flag is different when the .exec() method is used. (The roles of "class" and "argument" get reversed: In the case of .match(), the string class (or data type) owns the method and the regular expression is just an argument, while in the case of .exec(), it is the regular expression that owns the method, with the string being the argument. Contrast str.match(re) versus re.exec(str).) The 'g' flag is used with the .exec() method to get iterative progression.
var xArray;while(xArray = re.exec(str)) console.log(xArray);// produces: // ["fee ", index: 0, input: "fee fi fo fum"]// ["fi ", index: 4, input: "fee fi fo fum"]// ["fo ", index: 7, input: "fee fi fo fum"]
The m flag is used to specify that a multiline input string should be treated as multiple lines. If the m flag is used, ^ and $ match at the start or end of any line within the input string instead of the start or end of the entire string.