Home > Web Front-end > JS Tutorial > Summary of Js front-end performance optimization

Summary of Js front-end performance optimization

小云云
Release: 2018-02-28 13:42:48
Original
1787 people have browsed it

The best resource optimization is not to load resources. Caching is also the most effective optimization method. To be honest, although client-side caching occurs on the browser side, caching is mainly controlled by the server and has little to do with our front-end. But it is still necessary to understand.

Caching includes server-side caching and client-side caching. This article only talks about client-side caching. The so-called client cache is mainly http cache. HTTP caching is mainly divided into forced caching and negotiated caching.

Forced caching

  • Expires (http1.0)

Use Expires in http1.0 to do forced caching. The value of Exprires is the expiration time of the data returned by the server. When the request time when requesting again is less than the returned time, the cached data will be used directly. However, since the server time and client time may be different, this will also lead to cache hit errors.

  • Cache-Control

Cache-Control has many attributes, and different attributes have different meanings.

  1. private: The client can cache

  2. public: Both the client and the proxy server can cache

  3. max-age=t: cached content will expire after t seconds

  4. no-cache: Negotiation cache is required to verify cached data

  5. no-store: All content will not be cached.

Negotiate Cache

When the browser requests data for the first time, the server will respond to the client with the cache ID and data, and the client will back them up in the cache. . When requesting again, the client will send the identifier in the cache to the server, and the server will judge based on this identifier. If it has not expired, a 304 status code will be returned. The browser can use the cached data directly after receiving this status code.

  • Last-Modified

When the server responds to the request, it will tell the browser the last modification time of the resource

  • if-Modified-Since

When the browser requests the server again, the request header will contain this field, followed by the Last-Modified (last modification time) obtained in the cache ). When the server receives this request header and contains if-Modified-Since, it compares it with the last modification time of the requested resource. If it is greater than the last modification time of the requested resource, it returns 304, and the browser obtains the resource from the cache. If it is less than the last modification time of the requested resource, 200 is returned and the latest resource is returned. The browser obtains the latest resource from the server and caches it.

  • Etag

A unique identifying string generated by the server for each resource

  • If -None-Match

When requesting the server again, the browser's request message header will contain this field, and the subsequent value is the identifier obtained in the cache. After receiving the message, the server finds If-None-Match and compares it with the unique identifier of the requested resource. If they are the same, it means that the resource has not been modified, return 304, and the browser obtains the resource from the cache. If they are different, it means that the resource has been modified, then return 200, and return the latest resource. The browser obtains the latest resource from the server and caches it.

Last-Modified and ETag can be used together. The server will verify the ETag first. If they are consistent, it will continue to compare Last-Modified and finally decide whether to return 304.

If you use a front-end packaging tool, you can add a version number or hash value to the file when packaging the file, and you can also distinguish whether the resource has expired.

Reduce http requests

  • Use CDN to host static resources

  • ##You can use packaging tools such as gulp and webpack to package js and css Wait for files to be merged and compressed

  • Pictures are loaded lazily and on demand, and pictures are loaded only when scrolling to the visible area of ​​the picture

  • Small pictures And pictures that will basically not change are transmitted using base64 encoding. Don't abuse base64. Even small pictures will generate a long string after base64 encoding. If you abuse base64, it will be counterproductive.

  • Sprite pictures, this is also for pictures that basically will not change. I only use sprite images because if one image is modified, the entire sprite image will be regenerated. If used indiscriminately, it will be counterproductive.

Reduce the size of http request resources

  • Use webpack, gulp and other tools to compress resources

  • Turn on gzip compression on the server (the compression rate is very impressive, generally above 30%)

  • If you use packaging tools, packaging optimization must be done well, public resources, third-party code extraction, No packaged libraries are required...

Rendering Optimization

Those who have read the previous js running mechanism should know that from the time the url is entered in the browser to the page appearing on the screen , what happened (tcp handshake, dns resolution, etc. are not within the scope of knowledge).
  • FPS 16ms, less than 10ms is best. Google devtool to check the frame rate

If the browser FPS reaches 60, it will appear smoother. The refresh frequency of most monitors is 60Hz, and the browser will automatically refresh animations at this frequency.
Calculated based on FPS equal to 60, the average frame time is 1000ms/60 = 16.7ms, so each rendering time cannot exceed 16ms. If this time is exceeded, frame loss and lag will occur.

You can check the refresh rate in Timeline in the Chrome browser developer tools, and you can check the time consumption of all frame rates and the execution status of a certain frame. Timeline usage tutorial: https://segmentfault.com/a/11...

In order to ensure normal FPS, some rendering performance optimization is still necessary. The following are all strategies related to rendering optimization.

  • Try to use css3 for animation

As we all know, the performance of css is faster than js, so you can use css and try not to use js To achieve

  • avoid using setTimeout or setInterval, try to use requestAnimationFrame for animation or high-frequency Dom operations.

Because setTimeout and setInterval cannot guarantee the execution timing of the callback function, it is likely to be executed at the end of the frame, resulting in frame loss, but requestAnimationFrame can guarantee that the callback function will be executed at the beginning of each frame of animation. When executing
requestAnimationFrame Chinese MDN address: https://developer.mozilla.org...

  • Complex calculation operations use Web Workers

If you need complex data operations, such as traversing and summing an array of elements, then Web Workers are perfect.

Web Workers can allow JavaScript scripts to run in background threads (similar to creating a child thread), and the background thread will not affect the page in the main thread. However, threads created using Web Workers cannot operate the DOM tree.
For more information about Web Workers, you can view the MDN detailed explanation: https://developer.mozilla.org...

  • css is placed at the head and js is placed at the tail.

Those who have read the previous js running mechanism should know the process of page rendering, so I won’t go into details. Placing css at the head will avoid the splash screen phenomenon caused by re-layout after generating the html tree. js generally has a greater impact on the page and is generally placed at the end for last execution.

  • Event debounce and throttling

For high-frequency triggered events (mousemove, scroll) and other events, If not controlled it can trigger many events in a short period of time.

Function anti-shake means that when triggered frequently, the code will only be executed once if there is enough free time. Scenario: In the email input box during registration, as the user inputs, it is judged in real time whether the email format is correct. When the first input event is triggered, set the timing: perform the check after 800ms. If only 100ms has passed and the last timer has not been executed, clear the timer and retime it to 800ms. Until the latest input, there is no adjacent input, the timing of this latest input ends, and the check code is finally executed.

const filter  = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;  
$("#email").on("keyup",checkEmail());  
function checkEmail(){  
    let timer=null;  
    return function (){  
        clearTimeout(timer);  
        timer=setTimeout(function(){  
            console.log('执行检查');  
        },800);  
    }  
}
Copy after login

Function throttling means that the js method only runs once within a certain period of time. That is, what was originally executed 100 times per second becomes 10 times per second.
Scenario: The actual scenario of function throttling application, most of which will be used when listening to scrolling events of page elements.

var canRun = true;
document.getElementById("throttle").onscroll = function(){
    if(!canRun){
        // 判断是否已空闲,如果在执行中,则直接return
        return;
    }

    canRun = false;
    setTimeout(function(){
        console.log("函数节流");
        canRun = true;
    }, 300);
};
Copy after login
  • Dom operation

Front-end developers all know that Do operation is very time-consuming (I have personally tested a 30*30 table traversal add style). So try to avoid frequent Dom operations. If you can't avoid it, try to optimize the DOm operations.

1.:缓存Dom查询,比如通过getElementByTagName('p')获取Dom集,而不是逐个获取。

2: 合并Dom操作,使用createDocumentFragment()
Copy after login
    var frag = document.createDocumentFragment()
    for (i<10) {
        var li = document.createElement(&#39;li&#39;)
        frag.appendChild(li)
    }
    document.body.appendChild(frag)
Copy after login
 3: 使用React、Vue等框架的虚拟dom(原理目前还不明白),可以更快的实现dom操作。
Copy after login
  • Try to avoid repaint (rePaint) and reflow (reFlow)

It will be triggered if you use js to modify the color or background color of the element Redrawing is relatively expensive because the browser will check all nodes within a DOM element after the visual effect of the DOM element changes.

If you modify the size and position of the element, reflow will occur. Reflow is more expensive. It will be triggered after the position of a certain DOM element changes, and it will recalculate the position of all elements and the content on the page. The occupied area will cause a certain part of the page or even the entire page to be re-rendered.

  • css3 hardware acceleration

When the browser renders, it will be divided into two layers: ordinary layers and composite layers.

The ordinary document flow can be understood as a composite layer. Although the absolute and fixed layout can be separated from the ordinary document flow, it still belongs to the ordinary layer and hardware acceleration will not be activated. The repaint and reflow mentioned above refer to redraw and reflow on ordinary layers.

Composite layers will enable hardware acceleration. It is not in the same layer as the ordinary layer, so the composite layer will not affect the ordinary layer. If an element is promoted to the composite layer, and then the element is operated, it will not cause the ordinary layer to be redrawn and reflowed. This improves rendering performance.

How to start hardware acceleration:

1. Use translate3d and translateZ

webkit-transform: translateZ(0);
-moz-transform: translateZ(0);
-ms-transform: translateZ(0);
-o-transform: translateZ(0);
transform: translateZ(0);

webkit-transform: translate3d(0,0,0);
-moz-transform: translate3d(0,0,0);
-ms-transform: translate3d(0,0,0);
-o-transform: translate3d(0,0,0);
transform: translate3d(0,0,0);
Copy after login

2.使用opacity
需要动画执行的过程中才会创建合成层,动画没有开始或结束后元素还会回到之前的状态

3.使用will-chang属性
这个属性比较不常用,一般配合opacity与translate使用

针对webkit浏览器,启用硬件加速有些时候可能会导致浏览器频繁闪烁或抖动,可以使用下面方法消除:

-webkit-backface-visibility:hidden;
-webkit-perspective:1000;
Copy after login
如果使用硬件加速,请使用z-index配合使用, 因为如果这个元素添加了硬件加速,并且index层级比较低, 那么在这个元素的后面其它元素(层级比这个元素高的,或者相同的,并且releative或absolute属性相同的), 会默认变为复合层渲染,如果处理不当会极大的影响性能
  • 避免强制同步布局和布局抖动

浏览器渲染过程为:js/css(javascript) > 计算样式(style) > 布局(layout) > 绘制(paint) > 渲染合并图层(Composite)

JavaScript:JavaScript实现动画效果,DOM元素操作等。
Style(计算样式):确定每个DOM元素应该应用什么CSS规则。
Layout(布局):计算每个DOM元素在最终屏幕上显示的大小和位置。
Paint(绘制):在多个层上绘制DOM元素的的文字、颜色、图像、边框和阴影等。
Composite(渲染层合并):按照合理的顺序合并图层然后显示到屏幕上。

在js中如果读取style属性的某些值就会让浏览器强行进行一次布局、计算,然后再返回值,比如:

offsetTop, offsetLeft, offsetWidth, offsetHeight

scrollTop/Left/Width/Height

clientTop/Left/Width/Height

width,height

请求了getComputedStyle(), 或者 IE的 currentStyle
Copy after login

所以,如果强制浏览器在执行JavaScript脚本之前先执行布局过程,这就是所谓的强制同步布局。
比如下面代码:

requestAnimationFrame(logBoxHeight);

// 先写后读,触发强制布局
function logBoxHeight() {
    // 更新box样式
    box.classList.add('super-big');

    // 为了返回box的offersetHeight值
    // 浏览器必须先应用属性修改,接着执行布局过程
    console.log(box.offsetHeight);
}

// 先读后写,避免强制布局
function logBoxHeight() {
    // 获取box.offsetHeight
    console.log(box.offsetHeight);

    // 更新box样式
    box.classList.add('super-big');
}
Copy after login

在JavaScript脚本运行的时候,它能获取到的元素样式属性值都是上一帧画面的,都是旧的值。因此,如果你在当前帧获取属性之前又对元素节点有改动,那就会导致浏览器必须先应用属性修改,结果执行布局过程,最后再执行JavaScript逻辑。

如果连续多次强制同步布局,就会导致布局抖动
比如下面代码:

function resizeAllParagraphsToMatchBlockWidth() {
  for (var i = 0; i < paragraphs.length; i++) {
    paragraphs[i].style.width = box.offsetWidth + &#39;px&#39;;
  }
}

作者:SylvanasSun
链接:https://juejin.im/post/59da456951882525ed2b706d
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
Copy after login

我们知道浏览器是一帧一帧的刷新页面的,对于每一帧,上一帧的布局信息都是已知的。
强制布局就是使用js强制浏览器提前布局,比如下面代码:

// bed  每次循环都要去获取left ,就会发生一次回流
function logBoxHeight() {
  box.style.left += 10
  console.log(box.style.left)
}

// goog 
var width = box.offsetWidth;

function resizeAllParagraphsToMatchBlockWidth() {
  for (var i = 0; i < paragraphs.length; i++) {
    // Now write.
    paragraphs[i].style.width = width + &#39;px&#39;;
  }
}
Copy after login
  • DOMContentLoaded与Load

DOMContentLoaded 事件触发时,仅当DOM加载完成才触发DOMContentLoaded,此时样式表,图片,外部引入资源都还没加载。而load是等所有的资源加载完毕才会触发。

1. 解析HTML结构。
2. 加载外部脚本和样式表文件。
3. 解析并执行脚本代码。
4. DOM树构建完成。//DOMContentLoaded
5. 加载图片等外部文件。
页面加载完毕。//load
Copy after login
  • 视觉优化

等待加载时间可以合理使用loading gif动图一定程度上消除用户等待时间的烦躁感

代码性能

代码对性能的影响可大可小,但是养成一个良好的写代码习惯和高质量的代码,会潜移默化的提高性能,同时也能提高自己的水平。废话不多说,直接看我总结的部分要点(因为这一部分知识点太多,需要大家写代码的时候多多总结)。

  • 避免全局查找

访问局部变量会比访问全局变量快,因为js查找变量的时候现在局部作用局查找,找不到在逐级向上找。

// bad
function f () {
    for (...){
        console.log(window.location.href)
    }
}

//good
function f () {
    var href = window.location.href
    for (...){
        console.log(href)
    }
}
Copy after login
  • 循环技巧

// bed 
for(var i = 0; i < array.length; i++){
    ....
}
// good
for(var i = 0, len = array.length; i < len; i++){
    ....
}
// 不用每次查询长度
Copy after login
  • 不要使用for in 遍历数组

for in是最慢的,其他的都差不多,其中直接使用for循环是最快的。for in只是适合用来遍历对象。

  • 使用+''代替String()吧变量转化为字符串

var a = 12
//bad
a = String(a)

// good
var a = 12
a = a + &#39;&#39;
Copy after login

这个还有很多类似的,比如使用*1代替parseInt()等都是利用js的弱类型,其实这样对性能提升不是很大,网上有人测试过,进行十几万次变量转换,才快了零点几秒。

  • 删除dom

删除dom元素要删除注册在该节点上的事件,否则就会产生无法回收的内存,在选择removeChild和innerHTML=''二者之间尽量选择后者,据说removeChild有时候无法有效的释放节点(具体原因不明)

  • 使用事件代理处理事件

任何可以冒泡的事件都可以在节点的祖先节点上处理,这样对于子节点需要绑定相同事件的情况就不用分别给每个子节点添加事件监听,而是都提升到祖先节点处理。

  • 通过js生成的dom对象必须append到页面中

在IE下,js创建的额dom如果没有添加到页面,这部分内存是不会被回收的

  • 避免与null比较

可以使用下面方法替换与null比较
1.如果该值为引用类型,则使用instanceof检查其构造函数
2.如果该值为基本类型,使用typeof检查类型

  • 尽量使用三目运算符代替if else

if(a>b){num = a}
else{num = b}

// 可以替换为
num = a > b ? a : b
Copy after login
  • 当判断条件大于3中情况时,使用switch代替if

因为switch的执行速度比if要快,也别是在IE下,速度大约是if的两倍。

相关推荐:

CSS解读前端性能优化的具体分析

在HTML5中如何提高网站前端性能的示例代码分析

web前端性能优化方法


The above is the detailed content of Summary of Js front-end performance optimization. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template