0

0

Js前端性能优化总结

小云云

小云云

发布时间:2018-02-28 13:42:48

|

1925人浏览过

|

来源于php中文网

原创

最好的资源优化就是不加载资源。缓存也是最见效的优化手段。说实话,虽然说客户端缓存发生在浏览器端,但缓存主要还是服务端来控制,与我们前端关系并不是很大。但还是有必要了解一下。

缓存包括服务端缓存和客户端缓存,本文只谈客户端缓存。所谓客户端缓存主要是http缓存。http缓存主要分为强制缓存和协商缓存。

强制缓存

  • Expires(http1.0)

在http1.0中使用Expires来做强制缓存。Exprires的值为服务端返回的数据到期时间。当再次请求时的请求时间小于返回的此时间,则直接使用缓存数据。但由于服务端时间和客户端时间可能有误差,这也将导致缓存命中的误差。

Cache-Control有很多属性,不同的属性代表的意义也不同。

  1. private:客户端可以缓存

  2. public:客户端和代理服务器都可以缓存

  3. max-age=t:缓存内容将在t秒后失效

  4. no-cache:需要使用协商缓存来验证缓存数据

  5. no-store:所有内容都不会缓存。

协商缓存

浏览器第一次请求数据时,服务器会将缓存标识与数据一起响应给客户端,客户端将它们备份至缓存中。再次请求时,客户端会将缓存中的标识发送给服务器,服务器根据此标识判断。若未失效,返回304状态码,浏览器拿到此状态码就可以直接使用缓存数据了。

  • Last-Modified

服务器在响应请求时,会告诉浏览器资源的最后修改时间

  • if-Modified-Since

浏览器再次请求服务器的时候,请求头会包含此字段,后面跟着在缓存中获得的Last-Modified(最后修改时间)。服务端收到此请求头发现有if-Modified-Since,则与被请求资源的最后修改时间进行对比,如果大于被请求资源最后修改时间则返回304,浏览器从缓存获取资源。如果小于被请求资源最后修改时间,则返回200,并返回最新资源,浏览器从服务端获取最新的资源,并缓存。

  • Etag

由服务器生成的每个资源的唯一标识字符串

  • If-None-Match

再次请求服务器时,浏览器的请求报文头部会包含此字段,后面的值为在缓存中获取的标识。服务器接收到次报文后发现If-None-Match则与被请求资源的唯一标识进行对比。如果相同,说明资源没有被修改过,返回304,浏览器从缓存获取资源,如果不同说明资源被修改过,则返回200,并返回最新资源,浏览器从服务端获取最新资源,并缓存。

Last-Modified与ETag是可以一起使用的,服务器会优先验证ETag,一致的情况下,才会继续比对Last-Modified,最后才决定是否返回304。

如果使用前端打包工具,可以在打包文件时候在给文件添加版本号或者hash值,同样可以区分资源是否过期。

减少http请求

  • 使用CDN托管静态资源

  • 可以借助gulp、webpack等打包工具对js、css等文件合并与压缩

  • 图片懒加载、按需加载,当滚动到图片可视区域才去加载图片

  • 小图片并且基本不会改动的图片使用base64编码传输。base64不要滥用,即使小图片经过base64编码之后也会生成很长的字符串,如果滥用base64反而会适得其反

  • 雪碧图,这个也是针对基本不会更改的图片才使用雪碧图,因为如果一张图片修改,会导致整个雪碧图重新生成,如果乱用也会适得其反。

减小http请求资源体积

  • 借助webpack、gulp等工具压缩资源

  • 服务端开启gzip压缩(压缩率非常可观,一般都在30%之上)

  • 如果有用打包工具,打包优化要做好,公共资源、提取第三方代码、不需要打包的库...

渲染优化

读过前面js运行机制的应该知道,从浏览器输入url,到页面出现在屏幕上,都发生了哪些事(tcp握手、dns解析等不在认知范围)。
  • FPS 16ms 小于10ms完成最好  Google devtool 查看帧率

如果浏览器FPS到达60,就会显得比较流畅,大多数显示器的刷新频率是60Hz,浏览器会自动按照这个频率刷新动画。
按照FPS等于60来计算,平均一帧的时间为1000ms/60 = 16.7ms,所以每次渲染时间不能超过16ms,如果超过这个时间就会出现丢帧、卡顿现象。

可以在chrome浏览器开发者工具中的Timeline中查看刷新率,可以查看所有帧率耗时情况以及某一帧的执行情况。Timeline的使用教程:https://segmentfault.com/a/11...

为了保证正常的FPS,有些渲染性能优化还是有必要的。下面所介绍的都是有关渲染优化的策略。

  • 尽量使用css3来做动画

总所周知,css的性能要比js快,所以能使用css,尽量不用js来实现

  • 避免使用setTimeout或setInterval,尽量使用requestAnimationFrame来做动画或者高频Dom操作。

因为setTimeout和setInterval无法保证callback函数的执行时机,很可能在帧结束的时候执行,从而导致丢帧,但是requestAnimationFrame可以保证callback函数在每帧动画开始的时候执行
requestAnimationFrame的中文MDN地址:https://developer.mozilla.org...

  • 复杂的计算操作使用Web Workers

如果有需要复杂的数据操作,比如对一个有一个个元素的数组遍历求和,那么Web Workers在适合不过了。

Web Workers可以让JavaScript脚本运行在后台线程(类似于创建一个子线程),而后台线程不会影响到主线程中的页面。不过,使用Web Workers创建的线程是不能操作DOM树。
有关Web Workers的更多可以查看MDN详解:https://developer.mozilla.org...

  • css放在头部,js放在尾部。

读过前面js运行机制的应该知道页面渲染是怎样一个过程,不再赘述了。css放在头部会避免生成html树之后重新布局的闪屏现象,js一般对页面的影响较大,一般放在尾部最后执行。

  • 事件防抖(debounce)与节流(throttle)

针对高频触发的事件(mousemove、scroll)等事件,如果不加以控制会在短时间内触发很多事件。

函数防抖是指频繁触发的情况下,只有足够的空闲时间,才执行代码一次。场景:注册时邮箱的输入框,随着用户的输入,实时判断邮箱格式是否正确,当第一次输入事件触发,设置定时:在800ms之后执行检查。假如只过了100ms,上次的定时还没执行,此时清除定时,重新定时800ms。直到最近一次的输入,后面没有紧邻的输入了,这最近一次的输入定时计时结束,终于执行了检查代码。

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);  
    }  
}

函数节流是指一定时间内js方法只跑一次。就是本来一秒要执行100次的变成一秒执行10次。
场景:函数节流应用的实际场景,多数在监听页面元素滚动事件的时候会用到。

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

    canRun = false;
    setTimeout(function(){
        console.log("函数节流");
        canRun = true;
    }, 300);
};
  • Dom操作

前端开发人员都知道Do操作是非常耗时的(曾亲测过30*30的表格遍历添加样式)。所以尽量避免频繁的Dom操作,如果避免不了就尽量对DOm操作做优化。

kgogoprime
kgogoprime

KGOGOMall 是一套采用 Php + MySql 开发的基于 WEB 应用的 B/S 架构的B2C网上商店系统。具有完善的商品管理、订单管理、销售统计、新闻管理、结算系统、税率系统、模板系统、搜索引擎优化,数据备份恢复,会员积分折扣功能,不同的会员有不同的折扣,支持多语言,模板和代码分离等,轻松创建属于自己的个性化用户界面。主要面向企业和大中型网商提供最佳保障,最大化满足客户目前及今后的独立

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

2: 合并Dom操作,使用createDocumentFragment()
    var frag = document.createDocumentFragment()
    for (i<10) {
        var li = document.createElement('li')
        frag.appendChild(li)
    }
    document.body.appendChild(frag)
 3: 使用React、Vue等框架的虚拟dom(原理目前还不明白),可以更快的实现dom操作。
  • 尽量避免重绘(rePaint)和回流(reFlow)

如果使用js修改元素的颜色或者背景色就会触发重绘,重绘的开销还是比较昂贵的,因为浏览器会在某一个DOM元素的视觉效果改变后去check这个DOM元素内的所有节点。

如果修改元素的尺寸和位置就会发生回流,回流开销更大,它会在某一个DOM元素的位置发生改变后触发,而且它会重新计算所有元素的位置和在页面中的占有的面积,这样的话将会引起页面某一个部分甚至整个页面的重新渲染。

  • css3硬件加速

浏览器渲染时,会分为两个图层:普通图层和复合图层。

普通文档流内可以理解为一个复合图层,absolute、fixed布局虽然可以脱离普通文档流,但它仍然属于普通图层,不会启动硬件加速。上面说的重绘(rePaint)和回流(reFlow)说的就是普通图层上的重绘和回流。

复合图层会启动硬件加速。和普通图层不在同一个图层,所以复合图层不会影响普通图层,如果一个元素被提升到复合图层,再操作该元素时,就不会引起普通图层的重绘和回流,从而提升渲染性能。

如何启动硬件加速:

1.使用translate3d和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);

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

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

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

-webkit-backface-visibility:hidden;
-webkit-perspective:1000;
如果使用硬件加速,请使用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

所以,如果强制浏览器在执行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');
}

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

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

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

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

我们知道浏览器是一帧一帧的刷新页面的,对于每一帧,上一帧的布局信息都是已知的。
强制布局就是使用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 + 'px';
  }
}
  • DOMContentLoaded与Load

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

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

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

代码性能

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

  • 避免全局查找

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

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

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

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

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

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

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

// good
var a = 12
a = a + ''

这个还有很多类似的,比如使用*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
  • 当判断条件大于3中情况时,使用switch代替if

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

相关推荐:

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

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

web前端性能优化方法


相关文章

数码产品性能查询
数码产品性能查询

该软件包括了市面上所有手机CPU,手机跑分情况,电脑CPU,电脑产品信息等等,方便需要大家查阅数码产品最新情况,了解产品特性,能够进行对比选择最具性价比的商品。

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
html5动画制作有哪些制作方法
html5动画制作有哪些制作方法

html5动画制作方法有使用CSS3动画、使用JavaScript动画库、使用HTML5 Canvas等。想了解更多html5动画制作方法相关内容,可以阅读本专题下面的文章。

515

2023.10.23

HTML与HTML5的区别
HTML与HTML5的区别

HTML与HTML5的区别:1、html5支持矢量图形,html本身不支持;2、html5中可临时存储数据,html不行;3、html5新增了许多控件;4、html本身不支持音频和视频,html5支持;5、html无法处理不准确的语法,html5能够处理等等。想了解更多HTML与HTML5的相关内容,可以阅读本专题下面的文章。

440

2024.03.06

html5从入门到精通汇总
html5从入门到精通汇总

想系统掌握HTML5开发?本合集精选全网优质学习资源,涵盖免费教程、实战项目、视频课程与权威电子书,从基础语法到高级特性(Canvas、本地存储、响应式布局等)一应俱全,适合零基础小白到进阶开发者,助你高效入门并精通HTML5前端开发。

95

2025.12.30

html5新老标签汇总
html5新老标签汇总

HTML5在2026年持续优化网页语义化与交互体验,不仅引入了如<header>、<nav>、<article>、<section>、<aside>、<footer>等结构化标签,还新增了<video>、<audio>、<canvas>、<figure>、<time>、<mark>等增强多媒体与

126

2025.12.30

html5空格代码怎么写
html5空格代码怎么写

在HTML5中,空格不能直接通过键盘空格键实现,需使用特定代码。本合集详解常用空格写法:&nbsp;(不间断空格)、&ensp;(半个中文空格)、&emsp;(一个中文空格)及CSS的white-space属性等方法,帮助开发者精准控制页面排版,避免因空格失效导致布局错乱,适用于新手入门与实战参考。

81

2025.12.30

html5怎么做网站教程
html5怎么做网站教程

想从零开始学做网站?这份《HTML5怎么做网站教程》合集专为新手打造!涵盖HTML5基础语法、页面结构搭建、表单与多媒体嵌入、响应式布局及与CSS3/JavaScript协同开发等核心内容。无需编程基础,手把手教你用纯HTML5创建美观、兼容、移动端友好的现代网页。附实战案例+代码模板,快速上手,轻松迈出Web开发第一步!

159

2025.12.31

HTML5建模教程
HTML5建模教程

想快速掌握HTML5模板搭建?本合集汇集实用HTML5建模教程,从零基础入门到实战开发全覆盖!内容涵盖响应式布局、语义化标签、Canvas绘图、表单验证及移动端适配等核心技能,提供可直接复用的模板结构与代码示例。无需复杂配置,助你高效构建现代网页,轻松上手前端开发!

31

2025.12.31

html5怎么使用
html5怎么使用

想快速上手HTML5开发?本合集为你整理最实用的HTML5使用指南!涵盖HTML5基础语法、主流框架(如Bootstrap、Vue、React)集成方法,以及无需安装、直接在线编辑运行的平台推荐(如CodePen、JSFiddle)。无论你是新手还是进阶开发者,都能轻松掌握HTML5网页制作、响应式布局与交互功能开发,零配置开启高效前端编程之旅!

46

2025.12.31

2026赚钱平台入口大全
2026赚钱平台入口大全

2026年最新赚钱平台入口汇总,涵盖任务众包、内容创作、电商运营、技能变现等多类正规渠道,助你轻松开启副业增收之路。阅读专题下面的文章了解更多详细内容。

54

2026.01.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
React 教程
React 教程

共58课时 | 4.4万人学习

TypeScript 教程
TypeScript 教程

共19课时 | 2.6万人学习

Bootstrap 5教程
Bootstrap 5教程

共46课时 | 3.1万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号