当前位置:网站首页>DOM -- page rendering, style attribute operation, preloading and lazy loading, anti shake and throttling
DOM -- page rendering, style attribute operation, preloading and lazy loading, anti shake and throttling
2022-07-28 07:02:00 【Hahaha~】
One 、 Rendering of the page
( One ) The browser loads a HTML Loading process of documents
1、 Put the label 、 Text 、 notes 、 Properties, etc html The code is parsed into a node tree (DOM Tree)
2、 Put all styles (css Code and browser comes with ) Resolve to structure
3、 hold css The style structure is combined with the node tree to become a presentation tree / Render tree (Render Tree)
4、 According to the rendering tree Render Tree Draw page

( Two ) Redraw with backflow
1) backflow :
- When render tree Because of the number of elements 、 Layout 、 Hiding and other changes that need to be rebuilt is called backflow or backtracking
- Each page needs at least one reflow, that is, when the page is first loaded
2) Repaint :
- When render tree Some of the elements in the , These attributes only affect the appearance of the element 、 style 、 Styles that do not affect the layout are called redrawing
3) Relationship :
- Any right render tree The operation of elements in will cause reflow or redrawing
- Reflow must cause redrawing Redrawing does not necessarily cause reflow
4) Common reflow and redraw operations :
- Add or remove elements ( backflow + Repaint )
- Hidden elements : Such as display:none( backflow + Repaint ) visibility:hidden( Redraw only , No reflow )
- Move elements : Such as change top,left(jquery Of animate The way is , change top,left It doesn't necessarily affect the return flow ), Or move elements to something else 1 Of the parent elements ( Repaint + backflow )
- Yes style The operation of ( Operate on different properties , The impact is different )
- User's operation : Such as changing the size of browser or browser font ( backflow + Repaint )
Example :
<style>
.box {
width: 200px;
height: 200px;
background-color: red;
/* visibility: hidden; */
/* display: none; */
}
</style>
<div class="box">hello</div>
<button onclick="fn()">change</button>
<script>
function fn() {
var box = document.querySelector(".box")
box.innerHTML = "6666" // Changed the result reflow of the document tree
box.style.visibility = "hidden"; // Elements are just hidden Position reserved => Redraw without reflow
box.style.display = "none"; // The element will disappear Its position will not be preserved in the document tree => backflow
}
</script>5) influence :
- Frequent redrawing / Reflux will cause Computer consumption is too high It leads to poor performance and user experience of the page
6) terms of settlement :
- Try to avoid redrawing
- Create a fragment
fragment:
Add content to fragment Inside It itself is not added to the document tree for rendering After adding the contents to the document tree, it will disappear That is, the child element to be added ---> Added to the fragment---> take fragment Add to the target parent element ---> The child element enters the parent element ,fragment disappear ( Redraw only 、 Reflux once )
stay dom It's called in Chinese => fragment In the wechat applet => block stay vue in => template stay react in => </>
Case study : add to 1 Ten thousand squares on the page Each grid shows the time (ms)
<style>
#box td {
border: 1px gainsboro solid;
}
</style>
<table id="box">
</table>
<script>
let tb=document.querySelector(".box")
for(let i=0;i<100;i++){
let tr=document.createElement("tr")
tb.appendChild(tr) // Add elements to the document tree multiple times Lead to frequent reflow and redrawing
for(let j=0;j<100;j++){
let dt=new Date().getTime()
let td=document.createElement("td")
td.innerHTML=dt
tr.appendChild(td) // Add elements to the document tree multiple times Lead to frequent reflow and redrawing
}
}
// Multiple reflow redraws
</script>Optimize :
<style>
#box td {
border: 1px gainsboro solid;
}
</style>
<table id="box"></table>
<script>
// Create a fragment Element to host the element to be rendered
let tb=document.querySelector("#box")
let fra1=document.createDocumentFragment() // It's in memory, not in the document
for(let i=0;i<100;i++){
let tr=document.createElement("tr")
fra1.appendChild(tr)
for(let j=0;j<100;j++){
let dt=new Date().getTime()
let td=document.createElement("td")
td.innerHTML=dt
tr.appendChild(td)
}
}
tb.appendChild(fra1) // It will not be added to the document tree itself for rendering But its descendants will be added
// Added to the document tree only once So only reflux 1 Time
</script>Two 、style The operation of
( One ) The problem of getting elements
Cited example :
<style>
.box {
width: 400px;
height: 300px;
background-color: aqua;
cursor: pointer;
}
</style>
<div class="box" style="color: red;"> This is a div1</div>
<script>
var body1 = document.body
var box2 = document.querySelector(".box2")
var color1 = document.querySelector(".box").style.color
var width1 = document.querySelector(".box").style.width
console.log(body1) //body
console.log(box2) //null The node has not been loaded Can't access the back
console.log(color1) //red
console.log(width1) // Nothing is empty
</script>
<div class="box2"> This is a div2</div>Print the results :
reflection : Why? div2 yes null?
reason :
- I can't get it script Element node loaded after script node , Because documents are loaded in the order of the document tree
Solution :
- Scheme 1 : When the page is loaded, the event is triggered Then go to the method of obtaining nodes
function fn() {
var box2 = document.querySelector(".box2")
console.log(box2)
}
window.onload = fn
//window.onload It will be executed after the page is loaded namely fn Also execute after the page is loaded You can access div2
- Option two : By introducing script Labeled defer、async( modification src Load external js Resources ) Asynchronous properties
Write the code externally js In file
//index.js In file :
<script>
var box2 = document.querySelector(".box2")
console.log(box2)
</script>
//html In file :
<script defer src="index.js"></script>
<div class="box2"> This is a div2</div>async and defer
Asynchronous loading of scripts
1.<script src="script.js"></script>
No, defer or async, The browser loads and executes the specified script immediately ,“ immediately ” It means rendering the script Before the document element under the tag , That is, not waiting for subsequent document elements to load , Load and execute as soon as you read it .2.<script async src="script.js"></script>
Yes async, The process of loading and rendering subsequent document elements will follow script.js Load and execute in parallel ( asynchronous ).3.<script defer src="myscript.js"></script>
Yes defer, The process of loading subsequent document elements will be the same as script.js The loading is done in parallel ( asynchronous ), however script.js After all elements are parsed ,DOMContentLoaded Before the event triggers .
From a practical point of view : First, throw all the scripts into </body> It was best practice before , Because it's the only optimization option for old browsers , This method can ensure that all other non script elements can be loaded and parsed with the fastest speed .
( Two )style Attribute problem
1. Inline style :el.style.xx ele.currentStyle (IE Lower version of )
- You can only manipulate inline styles No compatibility issues
- Can only be set to string The style must use hump nomenclature
- Encountered the same style as reserved words , It should be preceded by “css”(eg:float—>el.style.cssFloat)
- In fact, it is the attribute value of the element in the obtained document tree
2. Final drawing style :window.getComputedStyle(el)
- In fact, it is the attribute value of the element in the rendering tree
3. expand :window.getComputedStyle(ele,"after")
- The second parameter is to get the pseudo element style
3、 ... and 、 Anti shake and throttling
1) Shake proof :
- After triggering a high frequency event n The function will only execute once per second , If n High frequency events are triggered again within seconds , Then recalculate the time
- Ideas : Every time an event is triggered, the previous delay call method is cancelled
Case study :
document.onclick = fangdou(function(e) {
console.log(6666)
}, 1000)
function fangdou(cb, delay) {
var timer = null;
return function() {
//return This function has a high frequency Find a way to make cb() Slow down the execution : Shake proof
clearTimeout(timer)
timer = setTimeout(function() {
cb()
}, delay)
}
}Optimize :
document.onclick = fangdou2(function(e) {
console.log(6666,e,this)
}, 1000)
function fangdou2(cb, delay) {
var timer = null;
return function() {
//return This function has a high frequency Find a way to make cb() Slow down the execution : Shake proof
let arg=arguments
clearTimeout(timer)
timer = setTimeout(()=>{
cb.apply(this,arg)
}, delay)
}
}
2) throttle :
- High frequency events trigger , But in n Only once per second , So throttling dilutes the frequency of function execution
- Ideas : Every time an event is triggered, it is judged whether there is a delay function waiting for execution
Case study :
document.onmousemove=jieliu(function(){console.log(666)},20)
function jieliu(cb,daley){
var timer=null;
return function(){
if(!timer){
timer=setTimeout(()=>{
cb();
timer=null
},daley)
}
}
}Optimize :
function jieliu2(cb,daley){
var timer=null;
return function(){
// console.log(66666,timer)
// this Is an event function this
let arg=arguments
if(!timer){
timer=setTimeout(()=>{
cb.apply(this,arg); // It was originally window But the hope is cb
timer=null
},daley)
}
}
}Four 、 Preloading and lazy loading
1) Preloading : Load resources ahead of time -- Optimization of homologous loading
Case study :
- After loading the same image once, it will be saved in the browser's local , Don't load more than once
<!-- Load three identical pictures at the same time -->
<img src="https://img2.baidu.com/it/u=1814268193,3619863984&fm=253&app=138&size=w931&n=0&f=JPEG&fmt=auto?sec=1658422800&t=d974afe62dd1225c4faa14b1538bf7f5">
<img src="https://img2.baidu.com/it/u=1814268193,3619863984&fm=253&app=138&size=w931&n=0&f=JPEG&fmt=auto?sec=1658422800&t=d974afe62dd1225c4faa14b1538bf7f5">
<img src="https://img2.baidu.com/it/u=1814268193,3619863984&fm=253&app=138&size=w931&n=0&f=JPEG&fmt=auto?sec=1658422800&t=d974afe62dd1225c4faa14b1538bf7f5">
effect :

2) Lazy loading : Don't load it yet Wait until a certain condition is true before loading resources
Case study :
- When the condition is true, the image under the page is loaded Make sure that it is loaded when you slide to the image position Can see the picture
<p>hello</p><p>hello</p><p>hello</p><p>hello</p><p>hello</p>
<p>hello</p><p>hello</p><p>hello</p><p>hello</p><p>hello</p>
<!-- Many are omitted here p label -->
<p>hello</p><p>hello</p><p>hello</p><p>hello</p><p>hello</p>
<p>hello</p><p>hello</p><p>hello</p><p>hello</p><p>hello</p>
<script>
window.onload=function(){
document.onscroll=function(e){
let top=window.pageYOffset||document.body.scrollTop||document.documentElement.scrollTop
let h=cHeight =window.innerHeight||document.body.clientHeight;
console.log(top,img2.offsetTop-h-100)
if(top>=(img2.offsetTop-h-100)){
img2.src=img2.dataset.src1 // If the condition is true, load the picture
}
}
}
</script>
<img id="img2" data-src1="https://img1.baidu.com/it/u=1966616150,2146512490&fm=253&app=138&size=w931&n=0&f=JPEG&fmt=auto?sec=1658422800&t=f99225a791b634226dcd5ee47c8b5f3f">effect :

边栏推荐
- Hdu-1159-commonsubsequence (LCS longest common subsequence)
- iptables防火墙
- Technology sharing | how to simulate real use scenarios? Mock technology to help you
- Icc2 analysis timing artifact analyze_ design_ violations
- MOOC翁恺C语言第七周:数组运算:1.数组运算2.搜索3.排序初步
- VMware Workstation 配置net模式
- Ubuntu18.04+centos7 configure redis master-slave [learning notes]
- Wechat applet custom compilation mode
- Life cycle (process) of software testing
- MySQL常用命令
猜你喜欢

What's a good gift for Tanabata? Niche and advanced product gift recommendation

一、PXE概述和安装

FTP service

shell脚本——sort、uniq、tr、数组排序、cut、eval命令配置

Icc2 analysis timing artifact analyze_ design_ violations

Vmware workstation configuration net mode

Custom component -- data listener

PXE无人值守安装管理

MySQL installation and use

LNMP搭建过程详解
随机推荐
Shell script - sort, uniq, TR, array sort, cut, Eval command configuration
What's a good gift for Tanabata? Niche and advanced product gift recommendation
Shell script -- program conditional statements (conditional tests, if statements, case branch statements, echo usage, for loops, while loops)
shell脚本——正则表达式
JSON notes
RAID disk array
Custom components -- slots
360 compatibility issues
On cookies and session
Technology sharing | how to simulate real use scenarios? Mock technology to help you
Wechat applet custom compilation mode
Use powercli to create a custom esxi ISO image
Tcp/ip five layer model
[learning notes] coding ability
iptables防火墙
What kind of air conduction Bluetooth headset with good configuration is recommended
Escape character notes
Hdu-1159-commonsubsequence (LCS longest common subsequence)
Wechat applet custom compilation mode
Ubuntu18.04搭建redis集群【学习笔记】
