HTML Tag features

interactions

  • Meta Tags: Automatic refresh/jump
<meta http-equiv="Refresh" content="5; URL=page2.html">
Copy the code

Performance optimization

<script>Tag: Adjust the loading order to improve rendering speed

The underlying operating mechanism of the browser is that when the rendering engine parses HTML, if the script tag references the file, it will suspend the parsing process and notify the network thread to load the file. After the file is loaded, it will switch to the JavaScript engine to execute the corresponding code. After the code execution is completed, it will switch to the rendering engine to continue rendering the page.

  • Async attributes. Request the file immediately, but instead of blocking the rendering engine, it blocks the rendering engine and executes the file contents immediately after the file is loaded.
  • The defer attribute. Request the file immediately, without blocking the rendering engine, and wait until the HTML is parsed before executing the file content.
  • HTML5 standard type attribute, corresponding to the value of “module”. Have the browser parse the file as a module according to ECMA Script 6, blocking as defer by default, or with async executing immediately after the request is complete.

Link tags: Speed up rendering with pre-processing

  • Dns-prefetch: When the REL value of the link label is dns-prefetch, the browser will perform DNS resolution for a domain name and cache it. In this way, when the browser requests resources with the same domain name, it saves the process of querying IP addresses from the domain name, thus reducing the time consumption
  • Preconnect: Allows the browser to perform some actions before an HTTP request is formally sent to the server. This includes DNS resolution, TLS negotiation, and TCP handshake, saving the user time by eliminating round-trip latency.
  • Prefetch /preload: Both values allow the browser to pre-load and cache a resource, but prefetch may be ignored when the browser is busy, whereas preload is guaranteed to be pre-loaded.
  • Prerender: The browser not only loads resources, but also parses the execution page for pre-rendering.

The process for the browser to obtain resource files is as follows:

Search optimization

  • Meta tags: Extract key information
  • Link tags: Reduce duplication
  • <link href="https://lagou.com/a.html" rel="canonical">This allows search engines to avoid spending time crawling duplicate pages. Note, however, that it also has a restriction, that is to point to the site is not allowed to cross domain.

Extension: OGP (Open Charting Protocol)

Efficiently manipulate DOM elements

Why are DOM operations time-consuming

thread

The browser contains a rendering engine (also known as the browser kernel) and a JavaScript engine, both of which run single-threaded. The advantage of single thread is that it is easy to develop, avoid the deadlock, competition and other problems under multi-thread, but the disadvantage is that it loses the concurrent ability.

  • To avoid rendering inconsistencies when two engines modify the page at the same time, the browser has added another mechanism. The two engines are mutually exclusive, meaning that only one engine is running at any one time and the other is blocked.
  • During thread switching, the operating system needs to save the state information of the previous thread and read the state information of the next thread, commonly known as context switching. This operation is relatively time-consuming.
  • Each DOM operation causes a context switch of the thread — from the JavaScript engine to the rendering engine to perform the operation, and then back to the JavaScript engine to continue execution, which incurs a performance penalty. A single switch consumes very little time, but if you do a lot of switches frequently, you can have performance problems.

To render

Another more time-consuming factor is re-rendering due to element and style changes. The two most time-consuming steps in the rendering process are Reflow and Repaint.

Operations that might affect the arrangement of other elements cause rearrangement, which in turn causes redraw, such as:

  • Modify element margins and sizes
  • Add and delete elements
  • Resize the window

Doing the opposite only causes a redraw, such as:

  • Setting the background image
  • Modify font color
  • Change the visibility property value

How can I manipulate the DOM efficiently

  • Manipulate elements outside the loop
  • Batch operation element
  • Cache element collection

conclusion

  • Try not to use complex matching rules and styles to reduce the time it takes the rendering engine to calculate the style rules and generate the CSSOM tree;
  • Minimize areas affected by rearrangement and redrawing;
  • Use CSS3 features to achieve animation effects.
  • Use absolute positioning to get out of the document flow, so that operations within the positioning of content do not cause external reordering
  • If animation is available, consider a layered rendering mechanism as well. And will change
  • Dom operations are digitized by JSON, and only one root node can be operated

There are three usage scenarios to help you use DOM events well

Image stabilization

Set a reasonable interval for the execution of functions to avoid frequent events within the interval and ensure that users can see the search results immediately after entering the function.

/ / code 2
const debounce = (func, wait = 0) = > {
  let timeout = null
  let args
  function debounced(. arg) {
    args = arg
    if(timeout) {
      clearTimeout(timeout)
      timeout = null
    }
    // Return the result of the function execution as a Promise
    return new Promise((res, rej) = > {
      timeout = setTimeout(async() = > {try {
          const result = await func.apply(this, args)
          res(result)
        } catch(e) {
          rej(e)
        }
      }, wait)
    })
  }
  // Allow cancellation
  function cancel() {
    clearTimeout(timeout)
    timeout = null
  }
  // Allow immediate execution
  function flush() {
    cancel()
    return func.apply(this, args)
  }
  debounced.cancel = cancel
  debounced.flush = flush
  return debounced
}
Copy the code

The throttle

const throttle = (func, wait = 0, execFirstCall) = > {
  let timeout = null
  let args
  let firstCallTimestamp


  function throttled(. arg) {
    if(! firstCallTimestamp) firstCallTimestamp =new Date().getTime()
    if(! execFirstCall || ! args) {console.log('set args:', arg)
      args = arg
    }
    if (timeout) {
      clearTimeout(timeout)
      timeout = null
    }
    // Return the result of the function execution as a Promise
    return new Promise(async(res, rej) => {
      if (new Date().getTime() - firstCallTimestamp >= wait) {
        try {
          const result = await func.apply(this, args)
          res(result)
        } catch (e) {
          rej(e)
        } finally {
          cancel()
        }
      } else {
        timeout = setTimeout(async() = > {try {
            const result = await func.apply(this, args)
            res(result)
          } catch (e) {
            rej(e)
          } finally {
            cancel()
          }
        }, firstCallTimestamp + wait - new Date().getTime())
      }
    })
  }
  // Allow cancellation
  function cancel() {
    clearTimeout(timeout)
    args = null
    timeout = null
    firstCallTimestamp = null
  }
  // Allow immediate execution
  function flush() {
    cancel()
    return func.apply(this, args)
  }
  throttled.cancel = cancel
  throttled.flush = flush
  return throttled
}
Copy the code

Throttling and stabilization both optimize the performance of frequently called functions by delaying execution and reducing the number of calls. The difference is that, for frequent calls over a period of time, the anti-shake is to delay the execution of a later call, throttling is to delay the timing of multiple calls

The agent

The event triggering process is shown in the figure, which is mainly divided into three stages:

  • Capture, the event object Window is propagated to the target’s parent, as shown in Red in Figure 1;
  • Target, the event object reaches the event target of the event object, the blue process in Figure 1;
  • Bubbling, the event object propagates from the target’s parent node to the Window, as shown in green in Figure 1.

About DOM event standards

1 / / way
<input type="text" onclick="click()"/>
2 / / way
document.querySelector('input').onClick = function(e) {
  // ...
}
3 / / way
document.querySelector('input').addEventListener('click'.function(e) {
  / /...
})
Copy the code
  • Mode 1 and mode 2 both belong to the DOM0 standard. In this way, the event monitor overwrites the previous event listener function.
  • Mode 3 is the DOM2 standard and is recommended. Event listener functions on the same element do not affect each other, and can be cancelled independently, in the same order of call and listening.

How does the browser render the page?

From the HTML to the DOM

  1. Byte stream decoding
  2. Input stream preprocessing
  3. The token is changed

The first step is to convert character data into tokens, and the second step is to parse the HTML to generate a DOM tree.

Handling of script tags when encountered

  • If inline code is encountered, the parsing process is paused and execution permissions are transferred to the JavaScript script engine, which then passes to the rendering engine to continue parsing when the JavaScript script is finished executing.
  • The exception is when the document.write() function that changes the DOM structure is called in the script content, where the rendering engine goes back to step 2, adds the code to the character stream, and parses it again.
  • If an external script is encountered, perform the corresponding operation based on the tag attribute.

Build a DOM tree

The second step in parsing HTML is tree building.

  • The browser creates a Document object when it creates the parser.
  • During the tree construction phase, the Document is constantly modified and expanded as the root node. The token generated by the marker step is sent to the tree builder for processing.
  • The DOM element for each type of token is defined in the HTML 5 standard, and when the tree builder receives a token, it creates the DOM element for that token and inserts it into the DOM tree.
  • New DOM elements created by the tree builder are also inserted into an open element stack to correct misnesting of element tags and to handle open element tags.
              Document
             /        \
DocumentType           HTMLHtmlElement
                      /               \
       HTMLHeadElement                 HTMLBodyElement
                                              |
                                          TextNode
Copy the code

CSSOM from CSS

Unlike DOM trees, nodes in CSSOM trees have inheritance properties, which means they inherit the parent node style as the current style and then supplement or overwrite it.

body { font-size: 12px }
p { font-weight: light }
span { color: blue }
p span { display: none }
img { float: left }
Copy the code

For the above code, the parse generates a DOM tree with a structure similar to the following:

The CSSOM tree in the figure above is not complete. A complete CSSOM tree should also include the default style provided by the browser (also known as the “User Agent style”).

Building a Render tree

  • The structure content of the DOM tree is separate from the style rules contained in the CSSOM tree, and they need to be combined into a rendering tree for easier rendering.
  • This will start at the root of the DOM tree and then find the style for each node in the CSSOM tree.
  • Nodes that do not need to be rendered (such as script tags, meta tags, etc.) and invisible nodes (such as the “display: None” style is set) are automatically ignored during traversal. Some pseudo-class elements that need to be displayed are also added to the render tree.

layout

  • Layout is calculating the size and position of elements.
  • Calculating element layout is a complex operation, including font size, line break position, and so on. These factors affect the size and shape of paragraphs, which in turn affects the position of the next paragraph.
  • The layout is then output with a “box model” that captures the exact location and size of each element, converting all relative values into absolute pixels on the screen

draw

  • Drawing is the process of converting each node in the rendered tree into an actual pixel on the screen. Once you have the layout tree as a “working drawing”, the rendering engine can’t draw it immediately because it doesn’t know what order to draw it in, and if you don’t know what order to draw it, it’s likely that the page will be rendered incorrectly.
    • For example, elements that use the Z-index attribute (such as a mask layer) that are not drawn in the correct order will result in a rendering that is not as expected (losing the mask effect).
  • So the first step in the rendering process is to traverse the layout tree, generate the drawing record, and then the rendering engine will draw the corresponding content based on the drawing record.
  • In the case of no animation effects, you just need to consider the spatial dimension, generate different layers, and then combine these layers. Of course, this drawing process is not static, it will continue to synthesize new graphics as the page scrolls.

Render page summary

  • The first four steps are DOM tree generation process, the last three steps are using DOM tree and CSSOM tree to render the page process
  • Byte → character → token → tree → page

JavaScript data type

  • Null, Undefined, Number, String, Boolean, Symbol, Object
  • The base typeWhen the data is referenced or copied, it is passed by value, that is, a completely equal variable is created.
  • Reference typesJust create a pointer to the original variable, and the two variables actually “share” the data, not create a new data

Undefined

  • Undefined is a special data type that has only one value, namely Undefined. Undefined can be obtained in one of the following ways:
Reference a declared but uninitialized variable; References undefined object properties; Execute a function with no return value; performvoidThe expression; Global constantswindow. Undefined orundefined

var a; // undefined
var o = {}
o.b // undefined
(() = >{}) ()// undefined
void 0 // undefined
window.undefined // undefined
Copy the code

To be continued…