We use browsers a lot in development, but we don’t know much about the mechanics of browsers. How does code work in a browser? How do I render the layout? What is the browser doing when the event is triggered? A lot of what we know about browsers may not be perfect, but let’s dig into that.
1. What happens when the browser enters the URL to the display page?
The old question, everyone should have been asked this kind of question in the interview, this is also the basic knowledge we should grasp, the answer on the Internet is a little general, I sorted out a more detailed version.
1.1 Enter the URL in the Browser
The user enters a URL, such as www.feng.com. Where HTTP is the protocol, www.feng.com is the network address, and indicates which computer the resources are needed. A network address can be a domain name or an IP address. Here is the domain name. The domain name is for memorization, it’s a bunch of numbers that we can easily misremember, but in order for the computer to understand this address it has to be resolved into an IP address.
1.2 Viewing the Browser Cache
If the URL is accessed, the browser cache (which stores a copy of the resource locally) is first checked for the requested file.
When the browser finds that a copy of the requested resource already exists in the browser cache, it intercepts the request, returns a copy of the resource, and ends the request without going back to the source server to download it again. If the cache lookup fails, it goes into the network request process.
Whether the request was made on the server or in the browser cache is marked in the network.
A DNS record for a domain name is cached locally in two types: the browser cache and the operating system (OS) cache.
1.2.1 Browser Cache – The browser caches DNS records for a period of time. It usually takes anywhere from 2 minutes to 30 minutes. Browser caches are searched in the following order: Service Worker–>Memory Cache–>Disk Cache–>Push Cache.
The Service Worker:
Is a separate thread that runs behind the browser and is generally used to implement caching. To use a Service Worker, the transport protocol must be HTTPS. Because request interception is involved in the Service Worker, the HTTPS protocol must be used for security. The Service Worker’s caching is different from the browser’s other built-in caching mechanisms in that it gives us the freedom to control which files are cached, how the cache matches, how the cache is read, and that the caching is continuous.
The Memory Cache:
The cache in memory mainly contains the resources that have been captured in the current page, such as the downloaded styles, scripts, pictures and so on. Reading data from memory is definitely faster than disk. Although memory cache reads efficiently, it has a short cache duration and is released as the process is released. Once we close the Tab page, the in-memory cache is freed.
Disk Cache:
A Cache stored in a hard disk is slower to read, but can store everything on disk, which is better than Memory Cache in terms of size and time.
The Disk Cache has the largest coverage of any browser Cache. It uses the fields in the HTTP Herder to determine which resources need to be cached, which resources can be used without a request, and which resources have expired and need to be rerequested. And even in the case of cross-site, resources at the same address, once cached by the hard disk, will not be asked for data again. Most of the Cache is from the Disk Cache.
Push the Cache:
Push Cache is the content of HTTP/2 and is only used when none of the above three caches is hit. It exists only in sessions and is released once the Session is over. It is also cached for a very short time, around 5 minutes in Chrome, and it does not strictly implement the caching instructions in THE HTTP header.
1.2.2 System Cache – If the required record is not found in the browser cache, the browser makes a system call to get the record in the system cache (gethostbyname in Windows).
1.2.3 Router Cache – The previous query is then sent to the router, which typically has its own DNS cache.
1.2.4 ISP DNS Cache – The next thing to check is the server on which ISP DNS is cached. You can usually find the corresponding cache record here.
1.2.5 Recursive search – Your ISP’s DNS server performs a recursive search starting with the DNS server, from the.com TOP-LEVEL DNS server to the Facebook DNS server. Most DNS servers have the domain names from the.com DNS server in the cache, so the matching process to the top-level server is not necessary.
1.3 DNS Domain name resolution
If the URL is not accessed, the DOMAIN name will be resolved by DNS.
IP addresses and domain names are used as network identifiers. Domain names and IP addresses are mapped one to one.
DNS: Domain Name System (based on the RFC specification) is a distributed database on the World Wide Web as Domain names and IP addresses map to each other, enabling users to more easily access the Internet, without having to remember the IP number string that can be read directly by the machine.
DNS resolution process:
1.3.1 The CLIENT running DNS on the user host refers to the CLIENT running DNS on our PC or mobile phone.
1.3.2 The browser extracts the domain name field from the received URL, that is, the accessed host name, such as www.feng.com, and sends the host name to the CLIENT of the DNS application.
1.3.3 THE DNS client sends a query packet to the DNS server. The packet contains the host name field to be accessed (including some cache queries and the work of the distributed DNS cluster).
1.3.4 The DNS client finally receives a reply packet containing the IP address corresponding to the host name.
1.3.5 Once the browser receives the IP address from the DNS, it can send a TCP connection to the HTTP server located at the IP address.
1.4 Obtaining the Port Number
The domain name may have multiple port numbers corresponding to different network functions. Therefore, the browser will obtain the port number after DNS resolution.
1.5 Setting up A TCP Connection
TCP connection, is the familiar three handshake good friends, four waving passers-by.
TCP connection process:
1.5.1 The server is ready to accept external connections through the socket, bind, and LISTEN. In this case, the server is in the LISTEN state.
1.5.2 The client initiates an active connection by calling connect, causing the client TCP to send a SYN byte, telling the server the initial sequence number of the data that the client will send in the connection (to be established). The client state is SYN_SENT.
1.5.3 The server acknowledges (ACK) the client’s SYN and sends a SYN of its own, which contains the initial sequence number that the server will send data on the same connection.
1.5.4 The Client acknowledges the ACK and SYN of the service and sends an ACK to the server in the ESTABLISHED state.
1.5.5 The server receives ACK, the server status is ESABLISHED.
1.6 the HTTP request
Now that the handshake is successful and we are connected to the Web server, the browser will make an HTTP request based on the resolved IP address and port number.
1.6.1 HTTP protocol sends requests to the server. During the process of sending requests, the browser will transmit data to the Web server in the form of Stream and tell the Web server which Web application Web resource to access in the server.
1.6.2 After the server receives the data transmitted by the browser, it begins to parse the received data. When the server parses the content in the request, it knows which Web resource the client browser wants to access in the application, and then the server reads the content in the Web resource. The read content is then transferred to the browser as a Stream.
1.7 shut down the TCP
TCP connection termination process:
1.7.1 An end first calls CLOSE to become the active close end and sends A FIN section to the other end to indicate that data is sent. In this case, the status of the active close end is FIN_WAIT_1;
1.7.2 The passive close end receives a FIN. The FIN is acknowledged by TCP and sends an ACK to the active close end as an end-of-file to the application process at the receiving end (after any other data has been queued up for the application process to receive). Because the receiving of FIN means that the application process on the receiving end has no additional data to receive on the corresponding connection, the status of the receiving end is CLOSE_WAIT; The status of ACK received by the active close end changes to FIN_WAIT_2.
1.7.3 After a period of time, the application process receiving the end of the file calls CLOSE to close the socket and sends FIN to the active end. The status of the receiving end is LAST_ACK;
1.7.4 The terminal that actively closes the FIN function confirms that the FIN function is in TIME_WAIT state and sends an ACK to the receiver. The receiver closes TCP after receiving an ACK, and then closes TCP after actively closes the FIN function for a period of time;
1.8 Browser Rendering
When the browser gets an HTML file, it loads it from the top down, parsing and rendering as it loads.
1. The browser will parse the HTML into a DOM tree. The building process of the DOM tree is a deep traversal process: all the children of the current node are built before the next sibling of the current node is built.
2. Parse the CSS into a CSS Rule Tree.
3. Construct Rendering Tree according to DOM Tree and CSSOM. Note: The Rendering Tree is not the same as the DOM Tree, because something like Header or display: None is not necessarily in the Rendering Tree.
4. With Render Tree, the browser can already know which nodes are in the web page, the CSS definition of each node, and their affiliation. The next step is called Layout, which, as the name implies, calculates the position of each node on the screen.
-
The next step is to draw, which is to walk through the Render tree and draw each node using the UI backend layer
2. How does the browser parse code?
So that’s a little bit of an overview, so let’s dig a little bit deeper, and then we can think about how we can write code that will save the browser a little bit of work.
2.1 parse HTML
HTML is parsed line by line.
The browser’s rendering engine parses the HTML document and converts the tags into DOM nodes in the content tree.
It parses the style element and the style data in the external file. The style data and the display controls in the HTML are used together to create another tree, the render tree.
The rendering engine will try to display the content as quickly as possible. It does not wait for all the HTML to be parsed before creating and laying out the render tree. It will process the following content while processing the local content first.
Browsers’ parsers typically divide the work between two components — the word segmentation program, which slices the input into legal symbol sequences, and the parser, which analyzes the document structure and builds the syntax tree according to the syntactic rules. The lexical analyzer knows how to filter for extranet characters like Spaces, newlines, and so on.
The tree output by the parser is made up of DOM elements and attribute nodes.
There is almost a one-to-one correspondence between the DOM and tags, such as the following tags
< HTML > < body > < p > Hello maple < / p > < div > < img SRC = "feng. PNG" / > < / div > < / body > < / HTML >Copy the code
Will be converted to a DOM tree like:
2.2 analytical CSS
CSS selectors are read from right to left.
#molly div.haha span{color:#f00}
Copy the code
In the code above, the browser reads the selectors in right-to-left order.
Go to “span” and then go up to the div with class “haha” and then find the element with THE ID “Molly”.
A successful match is added to the result set. If there is no match up to the root HTML element, the path is no longer traversed and the process is repeated starting at the next span.
The whole process results in an index tree that conforms to the rule. The top to bottom nodes of the tree are the nodes of the rule that match the selectors from right to left.
If a file is read from left to right and no matching tag is found on the left branch, the file will go back to the previous node and continue until a matching tag is found or no matching tag is found.
It takes a lot of performance when you have 100 or even 1000 branches. Conversely, searching from right to left greatly reduces the search scope and improves performance.
This explains why the ID selector is greater than the class selector and the class selector is greater than the element selector.
2.3 analytical JS
There is a js parser tool in the browser, which is used to parse our JS code.
When the browser encounters JS code, it immediately calls the “JS parser” to work.
The parser finds all the variables, functions, arguments, and so on in js and assigns the variables undefined (undefined).
Take the function out as a function block and store it in the warehouse. Once this is done, the code is parsed line by line (top down, left to right) and then matched to the repository.
<script> alert(a); //undefined var a = 1; alert(a); //1 </script> <script> a = 1; alert(a); // This is an error. </script> </script>Copy the code
Look at this code again
<script>
alert(a); //function a(){alert(4)}
var a = 1;
alert(a); //1
function a(){alert(2)}
alert(a); //1
var a = 3;
alert(a); //3
function a(){alert(4)}
alert(a); //3
</script>
Copy the code
In js preparsing, only function blocks are retained when a variable has the same name as a function. Expressions (+, -, *, /, %, ++, -, argument…) while parsing code line by line Will change the corresponding value in the repository.
We know the word “scope.” Now break the word down. Function: Read, write operation Domain: space, scope, region… Connect is a region that can be read and written. “Domain” : function, JSON,…… It’s all in one scope. Global variables, local variables, and global functions are also domains. In domain resolution, resolution also starts from the top down. This explains why references to external public JS files (e.g., jquery) should be placed above the custom JS.
Take a look at the code again
<script>
var a = 1;
function fn(){
alert(a); //undefined
var a = 2;
}
fn();
alert(a); //1
</script>
Copy the code
To keep track of the parser’s parsing process, first a outside fn() is a global variable, and a inside fn() is a local variable. The fn() function is also a scope, and as long as it is a scope, it must do both pre-parsing and line-by-line parsing. So the first alert prints the variable a that the fn() scoped repository points to, which is undefined. The second alert prints the global variable A, which is 1.
I’m going to move on to the code, which is basically the same code, but I’m going to change a little bit of it.
<script>
var a = 1;
function fn(){
alert(a); //1
a = 2;
}
fn();
alert(a); //2
</script>
Copy the code
There is no variable in fn(), so we don’t store anything in the repository. At this point, the repository is empty, nothing. But the parsing doesn’t end at this point, it starts from inside the function and looks out, and finds the global variable a. The value of the official global variable a is printed at this point.
Here comes the problem of a chain of scope. The whole parsing process is like a chain. Top down, inside out. The local can read and write the global, but the global cannot read and write the local.
So, let’s go back to the code, which is basically the same code, and I’ll change a little bit of it again.
<script>
var a = 1;
function fn(a){
alert(a); //undefined
a = 2;
}
fn();
alert(a); //1
</script>
Copy the code
Don’t forget that during pre-parsing the browser needs to find parameters in addition to variables and functions, and assign them undefined values. So fn(a) here is the same thing as FN (var a), and the logic is the same as the first instance code.
Keep doing things, keep looking at the code, basically the same code, and I change a little bit of it again.
<script>
var a = 1;
function fn(a){
alert(a); //1
a = 2;
}
fn(a);
alert(a); //1
</script>
Copy the code
When the code is executed to fn(a); And passes in the global variable a as an argument.
Function fn(a) is equal to function fn(var a), so a=2; The local variable a is changed, and the global variable A is not affected, so the second print is still 1.
3. Garbage collection mechanism of the browser
Since strings, objects, and arrays have no fixed size, they can only be dynamically allocated when their size is known. Every time a JavaScript program creates a string, array, or object, the interpreter must allocate memory to store that entity. Whenever memory is dynamically allocated like this, it eventually has to be freed so that it can be reused. Otherwise, the JavaScript interpreter will use up all the available memory in the system, causing the system to crash.
The JavaScript interpreter can detect when an object is no longer used by the program. When it determines that an object is useless, it knows that it is no longer needed and can free up its memory.
var a = "before"; var b = "override a"; var a = b; / / rewrite aCopy the code
After this code runs, the string “before” loses its reference (it was previously referenced by A), and when the system detects this fact, it frees up the string’s storage so that it can be reused.
Browsers typically use two methods of garbage collection: tag cleanup and reference counting.
3.1 Mark Clearing
This is the most commonly used garbage collection method in javascript. When a variable enters the execution environment, it is marked as “entering the environment”. Logically, the memory occupied by variables entering the environment can never be freed, because they are likely to be used as soon as the execution flow enters the appropriate environment. When a variable leaves the environment, it is marked “out of the environment.”
When the garbage collector runs, it marks all variables stored in memory. It then removes the markup of variables in the environment and those referenced by variables in the environment. Variables tagged after that are considered to be ready to be deleted because they are no longer accessible to variables in the environment. At last. The garbage collector does the cleanup, destroying the tagged values and reclaiming the memory space they occupy.
When an object cannot be traversed by reference from the root object, that is, unreachable, it is cleared. For the above example, the a and b in fn() are not accessible from the outside context after the function is executed, so they can be cleared.
This is the current mainstream GC algorithm, which is used in V8.
Whether it's a high level language or a low level language. Memory management is: allocate memory use memory (read or write) free memory first two steps, everyone is not too big disagreement. The key is freeing up memory. Every language has its own garbage collection (GC) mechanism.Copy the code
In most application scenarios, a newly created object has a very short life cycle. Therefore, in V8, GC processing is divided into two categories: the new generation and the old generation.
The heap space of the new generation is 1M to 8M and is divided into two parts (to-space and from-space). Usually, the memory of a newly created object is allocated to the new generation. When to-space is full, to-space and form-space swap places (in this case, to is empty, from is full) and GC is performed. If an object is determined to be unreferenced, it is cleared; If there is a reference, the number of escapes is +1 (if the number of escapes is 2, move to old generation, otherwise move to to-space).
The old generation has large heap space, and GC is not suitable for the new generation, which divides space into two Spaces. The old generation of garbage collection, in two stages: marking, cleaning (there are two ways of both Sweeping and Compacting).
3 colors: black, white and gray. The steps are as follows:
GC starts, so the object is marked white.
The root object is marked in black, and the child node (the referenced object) is traversed.
The node currently traversed is greyed and put into a stack called marking bitmap. In the stack, the currently traversed node is marked black and removed from the stack, while its children (if any) are marked gray and pushed onto the stack. (Large objects are special, so I won’t expand them here.)
When all the objects have been traversed, only black and white are left. By way of Sweeping or Compacting, clean up the whiteness to complete GC.
3.2 Count times for references
The meaning of reference counting is to keep track of the number of times each value has been referenced. When a variable is declared and a reference type is assigned to it, the number of references to that value is 1. Conversely, if the variable containing the reference to this value takes another value, the number of references to that value is reduced by one. When the number of references goes to zero, the value is no longer accessible and can be reclaimed. This way, the next time the garbage collector runs, it frees the memory occupied by the values that are referenced zero times.
But there is a problem with this approach. Let’s look at the code:
function problem() {
var objA = new Object();
var objB = new Object();
objA.someOtherObject = objB;
objB.anotherObject = objA;
}
Copy the code
In this example, objA and objB refer to each other through their properties; In other words, the number of references to both objects is 2. In a reference-counting strategy, since both objects are out of scope after the function is executed, objA and objB will continue to exist after the function is executed because their number of references will never be zero. Such cross-references can cause a lot of memory leaks if they exist in large numbers.
Most browsers have abandoned this recycling approach.
4. Local storage of the browser
If I were to ask you what caches are in browsers, I’m sure most people would say there are three: cookie, sessionStorage, and localStorage.
But, I don’t know why people call these three caches, they are called caches, Memory Cache and so on, and the browser puts them in storage, which translates to storage.
One more thing, there are five: Cookies, Local Storage, Session Storage, WebSQL, and IndexedDB.
4.1 the cookie
Cookies are the earliest local storage, provided by the browser, and open to the server and JS, which means we can save Cookies through the server and client. However, the total amount of data that can be stored is only 4KB, and if it exceeds this limit, it will be ignored and cannot be saved.
The HTTP protocol itself is stateless. What is stateless? That is, the server cannot determine the identity of the user. A Cookie is actually a small piece of text information (key-value format). The client initiates a request to the server. If the server needs to record the status of the user, it issues a Cookie to the browser of the client using the response. The client browser saves the Cookie. When the browser requests the site again, the browser submits the requested URL to the server along with the Cookie. The server checks the Cookie to identify the user’s status.
4.2 Local Storage Session Storage
Both the Local Storage and Session Storage belong to the Web Storage. Web Storage is similar to Cookies, the difference is that it has a larger Storage capacity. Local Storage is a persistent Local Storage. Data will always be stored locally unless we actively delete it. Session Storage only exists in Session sessions. That is, only the pages of the same Session can be used. When the Session ends, the data is automatically released.
4.3 Cookie Local Storage Session Storage Comparison
When we interview, the interviewer will ask what is the difference between cookie Local Storage Session Storage.
features
Cookie
Local Storage
Session Storage
The lifetime of the data
You can set the expiration time. By default, the expiration time is after the browser is closed
Stored permanently unless explicitly cleared
Session-level storage is valid only for the current session and is cleared when the session ends and the page or browser is closed
Storage data size
About 4 KB
5MB to 10MB(depending on the browser)
5MB to 10MB(depending on the browser)
Communicates with the server
They are carried in HTTP headers every time, and using cookies to store too much data can cause performance and security problems
Only saved in the client (i.e., the browser), does not participate in the communication with the server
Only saved in the client (i.e., the browser), does not participate in the communication with the server
Ease of use
The source Cookie interface is not friendly, developers need to be based on the needs of encapsulation
The source interface is good and can be encapsulated again to provide better support for Objects and arrays
The source interface is good and can be encapsulated again to provide better support for Objects and arrays
Application scenarios
When a user logs in, an encrypted code returned by the server that uniquely identifies a single user is saved to determine the current login status of the user, or the previous e-commerce site used to save the user’s shopping cart information.
Local Storage can replace cookies to complete the front-end saving function of users’ shopping cart information, and can be used as the Local data Storage space of HTML5 games.
When multiple forms exist on a page, Session Storage can be used to split form pages and optimize user experience.
Pay attention to
Do not save system sensitive data to Cookie, Local Storage, Session Storage to prevent the risk of XSS injection. Because XSS injection can modify your property values via the console, see another blog post I wrote about, Front-end hacking techniques.
4.4 WebSQL
WebSQL and IndexedDB are the latest HTML5 Local caching technologies. Compared to Local Storage and Session Storage, WebSQL and IndexedDB are more powerful and support more data types, such as pictures and videos.
WebSQL is more accurately called WebSQL DB API, it is a web API interface to operate the local database, through the API can complete the operation of the client database. When we use WebSQL, you can easily use SQL to add, delete, change and check the data. These browser clients, such as Chrome and Safari, use SQLite for local storage. Wechat uses SQLite for local chat records.
4.5 with IndexedDB
IndexedDB is a local database provided by the browser that can be created and manipulated by web scripts. It can store large amounts of data, provides a lookup interface, and can build indexes. It is not a relational database (it does not support SQL queries and is more like a NoSQL database).
IndexedDB features:
- Key-value pair storage: The IndexedDB uses an Object Store to store data. All types of data can be stored directly, including JavaScript objects. In object warehouse, data is stored in the form of “key and value pairs”. Each data record has its own primary key, which is unique and will throw an error if repeated.
- Asynchronous: The IndexedDB operation does not lock the browser, and users can still perform other operations. Unlike the synchronous operation of Local Storage, the asynchronous operation is designed to read and write large amounts of data, slowing down page performance and reducing user experience.
- Support for transactions: IndexedDB supports transactions, which means that if one of the steps in the list fails, the entire transaction disappears and the database is rolled back to the state before the transaction occurred. There is no such thing as writing only part of the data.
- Same-origin restriction: IndexedDB is subject to same-origin restriction, with each database corresponding to the domain name for which it was created. The web page can only access the database under its own domain name, and cannot access the cross-domain IndexedDB database.
- Large storage space: the storage space of an IndexedDB is usually no less than 250MB or larger.
- Support for binary storage: IndexedDB can store not only strings but also binary data (ArrayBuffer objects and Blob objects).
Transaction is a database concept. A transaction is a sequence of database operations that access and may operate on various data items. These operations are either all or none, and are an indivisible unit of work. A transaction consists of all database operations performed between the start and end of a transaction.
5. Browser threads
When we use JavaScript, we know that JS is single threaded, whereas browsers are multi-threaded.
5.1 the CPU
The CPU is the core of the computer, which is responsible for the computing tasks of the computer. Here we think of it as a factory.
5.2 process
A process is a dynamic execution process of a program with certain independent functions on a data set. It is an independent unit of the operating system to allocate and schedule resources, and a carrier of application program running.
We are comparing a process here to the workshop of a factory, which represents the individual tasks that the CPU can handle. At any given time, the CPU is always running one process and the other processes are not running.
5.3 the thread
Thread is a single sequence control flow in program execution, and it is the smallest unit of program execution flow.
Here the thread is likened to a workshop workers, that is, a workshop can be allowed by multiple workers to complete a task.
5.4 Multithreading in the browser
The browser kernel is multi-threaded. Threads work together to keep in sync under the control of the kernel. A browser usually consists of the following resident threads:
- GUI rendering thread
- JavaScript engine threads
- Event-triggered thread
- Timed trigger thread
- Asynchronous HTTP request threads
5.4.1 GUI rendering thread
The GUI rendering thread is responsible for rendering browser interface HTML elements, parsing HTML, CSS, building DOM and RenderObject trees, layout and rendering, and more.
This thread executes when the interface needs to be repainted or when some operation causes reflow.
While the Javascript engine is running the script, the GUI rendering thread is suspended, that is, “frozen,” and GUI updates are stored in a queue until they are executed as soon as the Javascript engine is idle.
5.4.2 JavaScript engine threads
The JavaScript engine, also known as the JS kernel, handles JavaScript scripts, such as the V8 engine.
The JS engine waits for the arrival of tasks in the task queue and then processes them. There is only one JS thread running the JS program in a Tab (renderer process) at any time (single thread).
Note: GUI rendering threads and JavaScript engine threads are mutually exclusive.Copy the code
Since JavaScript manipulates the DOM, if the interface is rendered while modifying these element attributes (i.e., the JavaScript thread and the UI thread are running simultaneously), then the element data obtained before and after the rendering thread may be inconsistent.
Therefore, to prevent unexpected results from rendering, the browser sets the GUI rendering thread to be mutually exclusive with the JavaScript engine. The GUI thread is suspended while the JavaScript engine is executing, and GUI updates are stored in a queue until they are executed immediately when the engine thread is idle.
If the JS execution takes too long, this will cause the rendering of the page to be incoherent, causing the page rendering load to be blocked.
5.4.3 Event-triggered threads
When an event is triggered, the thread will add the event to the end of the queue to be processed by the JS engine.
These events can be blocks of currently executing code such as scheduled tasks, or other threads from the browser kernel such as mouse clicks, AJAX asynchronous requests, etc., but due to the single-threaded relationship of JS all these events have to be queued up for the JS engine to process.
5.4.4 Timed trigger threads
Thread where setInterval and setTimeout reside
The browser timing counter is not counted by the JavaScript engine, because the JavaScript engine is single-threaded, and if it is in a blocked thread state, the timing is not accurate.
Timing and triggering by a separate thread (when finished, add to the event queue and wait for the JS engine to idle)
Note that the W3C states in the HTML standard that any interval of less than 4ms in setTimeout is required to count as 4ms.
5.4.5 Asynchronous HTTP Request threads
After the XMLHttpRequest is connected, it opens a new thread request through the browser.
When a state change is detected and a callback function is set, the asynchronous thread generates a state change event, puts the callback in the event queue, and is executed by the JavaScript engine.
6. Browser compatibility
Browser compatibility issues have always been a headache. I was struggling with IE compatibility for qiankun a while ago.
6.1 Why does our code have compatibility problems in the browser?
Because different browsers have different interpretations of the same code, resulting in inconsistent page display. In most cases, we want a uniform display no matter what browser the user is using to view our site or log into our system.
The higher the browser version, the more features it supports. A plugin that we use may use a feature that is supported by a higher version of the browser but not by an earlier version.
6.2 How can we solve this problem?
6.2.1 Hack,
On the CSS side, we can use CSS hacks. A CSS hack is an attempt to apply different styles of CSS by adding special symbols, known as browser prefixes, to make different browsers recognize different symbols (there is a standard for what browsers recognize, and a CSS hack is to make you remember this standard).
6.2.2 polyfill
On the JS side, we can use a polyfill. A polyfill is a piece of code (or plug-in) that provides functionality that developers want browsers to support natively. The library first checks to see if the browser supports an API, and if it does not, loads the corresponding Polyfill. For example, HTML5 storage. Different browsers, different versions, some support, some do not support. A polyfill is a type of shim.
Shim means that a new API is simulated in an old environment and implemented only by means of the old environment so that all browsers behave the same.Copy the code
6.2.3 PostCSS
PostCSS is a tool that uses JS plug-ins to transform CSS. These plug-ins are so powerful that they can do anything. Autoprefixer is one of the most popular PostCSS plug-ins.
Autoprefixer automatically prefixes our browsers.
6.2.4 none. Js
Modernizr.js is very powerful in that it allows you to patch older browsers and ensure that the new browsers are progressively enhanced.
Modernizr does very little by default other than (if you choose) append a bit of HTML5 gasket scripting by Remy Sharp to browsers that don’t support HTML5 tags such as IE6, 7 and 8
7. Browser security
Refer to my other post:
Hacking and Security techniques in Web Front-end Development