javascript的性能调优

一.前言 cDqj&:$e
^5 ~)m6=2
本文的上一篇 JavaScript 踩坑心得— 为了高速(上) 主要和大家分享的是 JavaScript 使用过程中的基本原则以及编写过程中的心得分享,本文主要和大家聊聊在各个使用场景下的 JavaScript 使用,以及在性能优化方面的优化经验等 n%I9l]
UVaz,bXla
二.各种场景下的 JavaScript Xr$hQbl5D
u,),kj<
1.用于 UI 应用的 JavaScript 73tWeZ8rvx
q($fl7}Y
与大多数 服务端语言一样,用于客户端应用的 JavaScript 框架从来就不缺少。然而,和用在后端应用与服务中一样,笔者偏好使用较小的模块,将这些小模块组合为框架,从而实现可扩展性,可维护性以及较高的重用度。 g@IYD
VO+3@d:
并且,由于小模块的特性,后期拍错或者进行性能优化的时候也会非常方便,现在国内外针对前端 JavaScript 的性能行为分析工具也比较成熟了,例如 Browser Insight、APPdynamic、Ruxit,都是不错的选择 l527>7 eT
GN ?1dwI
2.构建 Web 应用的 JavaScript _~_6qTv-d
\X0wr%I
对于 Web 应用,笔者发现将 React 用于实现 UI,Redux 用于状态管理,Joi 用于 数据验证,是建立可扩展客户端应用的最有效技术基础。这样建立起来的应用,往往易于操纵,测试以及调试。 HK!Vd_&9,
Z=CY6Zu7
笔者非常喜爱该组合的一点,是他们使得遵循「 JavaScript 的两大支柱」变得更加简单。从 0.14 版本开始,React 增加了对纯函数的支持,Redux 也使用了纯函数与可组合的 reducers。看来,使用典型面向对象模式的脆弱应用已经一去不复返了。 a#i%7mfn
aFVd}RO0
该组合的另一大优点是可用的工具很多。React 与 Redux 都有 Chrome 开发者工具插件,使得调试与 操作应用变得极为简单。而诸多支持模块,比如 React Hot Loader 与 Webpack 也使得反馈更加及时。笔者建议你仔细了解一下这两个模块。 Cd51. Sk(l
+)QA!g$
3.构建移动应用 qr[+^*Ha
P'q . _U
显而易见,如果是构建移动平台的应用,笔者肯定会推荐 React Native。目前,React Native 仅支持 iOS 与 Android 平台,因此,除非你真的需要 Windows 支持,笔者会统一推荐 React Native。 8I|2yvhP
hV>@qOl '
还有一个值得一说的就是,现在无论安卓还是 ios 的 APP 性能优化 也非常重要,但是很多公司只注重后端架构、代码质量等 问题,却忽视了前端编写时可能存在的影响因素。并且,尽管 JS 测试对于确保应用如期运行非常重要,但人们却也常常在测试中花去太多时间,并不是说不应该编写测试代码,只是,要小心过度测试与过度模拟,所以上文提到过的 Browser Insight、newrelic、APPdynamic 等真心都是优化前端不错的选择。 /e4#D H
`-[+(+["
三.测试用 JavaScript (y{nD~k
\J?5K l[*c
1.仅测试公共 APIs QW1d&Gb.(
V;SXa|,
通过不专注于内部程序,只要不破坏模块内的公共 API,我们就能随心所欲地改变他们。这意味着,测试的变化无需那么频繁,而且你可以确保 己接收的数据正是应该收到的数据。 x
)./.rtP|4
2.建立测试框架 Hxzdxwz%$
lg!{?xM
说到实际应用的测试模块,笔者最近迷上了 tape 与 nock。有了这两个模块,笔者就能覆盖 99% 的测试(有时候,笔者必须自行监控一些数据,并使用Sinon)。Browser Insight 这款产品无论是线上还是线下,针对前端页面的 JS 错误都能准确的定位到,精确到代码行,非常方便。 60St99@O
A`qb5LLJ)
3.测试用户体验(UX) J>Uzd, /
!%_H1jk
如果你在打造 Web 应用,可能会想在尽可能多的设备与浏览环境下测试用户体验。为了获得更为直接的反馈,笔者采用了 Browser Insight,这个工具的好处就是基于真实的用户体验,多维度的定位分析 网站的性能问题,例如脚本错误、ajax调用、响应时间分布等板块,而且,这个工具支持 PC 端、移动浏览器、移动 微信页面、APP 等多个使用场景,基本上能满足绝大多数场景的使用需求。 U?:
a,U@ !}K
四.JavaScript 性能优化误区 MOEB{~v`;
!rMl" Y[
1.JavaScript 模块化使用误区 C6`
9#AsSbBpf
加快 JavaScript 加载和执行的速度,一直是前端优化的一个热点。因此我们先来说下 JavaScript 模块化技术的相关知识,希望通过实践来体现模块化技术在使用时的注意事项,避免滥用。 k(v8zDq*
,Cckp! 6
为什么会有模块化技术? :,^pLAt
)!``P?3?
长久以来,编写 JavaScript 一直以文件为单位,一般一个类型的 JavaScript 功能代码会被放在同一个文件里。在一个页面里,引用的文件一般是写死的,也就是不管页面用不用,只要你引入了这个文件,这个文件就会被加载。 JV#)?/a$z
(~>L \]!
举个例子,我们开发了一个内容复杂、功能强大的页面,JavaScript 文件大到 500K,当页面费劲的把这 500K 加载下来,然而用户真正只使用了这 500K 里极少的一部分功能,但我们又不得不把这 500K 加载下来,因为不同的用户使用的功能点可能不一样,我们必须满足所有需求。 n/3gx4.g
: *Nvy={c
而模块化技术提出 按需加载,也就是当用户触发该功能的时候,那个功能才真正的被加载。好比 500K 被拆成了 50 个模块,每个模块 10K,当用户触发一个功能时,加载 10K,再触发再加载,以这样懒加载的方式来加载模块,可以很大的提高响应速度。这样,管理模块懒加载的技术也随之诞生。 T8i9
= ?hx+-'
模块化技术并非到处靠谱!! Gv,0{DVX<
l&d 6G0
之前笔者在网上搜索到了一个模块化技术: SeaJS。它是一个遵循 CommonJS 规范的 JavaScript 模块加载框架,可以实现 JavaScript 的模块化开发及加载机制。与 JQuery 等 JavaScript 框架不同,SeaJS 不会扩展封装语言特性,而只是实现 JavaScript 的模块化及按模块加载。 J0U9zI4
Pe !eID8
SeaJS 的主要目的是令 JavaScript 开发模块化并可以轻松愉悦进行加载,将前端工程师从繁重的 JavaScript 文件及对象依赖处理中解放出来,可以专注于代码本身的逻辑。说白了就是有 Lazy Load 的特性,用到某模块时,SeaJS 才会去加载模块的 JS 文件。我们可以按功能划分多个模块,触发模块功能时,SeaJS 先加载功能模块的文件,然后执行相应的功能。 *eO@
MKdBqnM(F
这个 SeaJS 拥有的特性,初看非常吸引人,它可以说是新定义了一种开发和管理 JavaScript 文件的模式。遵循这个模式,你会享受起 JavaScript 的开发。 xwj%X%2
Upr:sB
实践证明,它也的确可以使 JavaScript 模块化,根据功能划分模块,每个模块对应一个 JavaScript 文件,当执行到模块的功能,或者你需要加载模块时,模块才会被下载,同时不会造成重复下载。这一切看起来如此的合理,如此的顺畅。。。。。 q(Y
6SMGXy*]^
但是在使用后发现了一些 问题:由于当时开发的网站功能相对简单,JavaScript 文件并不是非常大,过多的模块,反而会导致总加载的时间变多了。 =$g8"[4
~7!J/LHg
由于是 Lazy Load 特性,不适合的模块划分导致网站出现反应慢的现象,原因是得先加载模块的文件,才能执行模块的功能。当网络情况不好时,该现象表现的更为严重!!! ]rDf3_!m(
-P5VE0
可以说,问题出在了对新技术的不了解上,从而出现了问题,预期是 SeaJS 可以处理 JavaScript 优化的问题,因为它具有避免加载不必要模块的功能,结果反而南辕北辙。 &CiUU
QK\QvU2y
根据 大功能来划分模块 也是一个不错的尝试。 0:**uion
ih?_ fW
笔者尝试将所有模块划分为 基础模块功能模块 ,基础模块包括页面头部,尾部相关的公共部分,功能模块则根据前后台划分,前台部分,又根据具体的页面来划分,能合并到一起的,就合并成一个模块,增加粒度。结果 JavaScript 文件减少,也达到了预期的效果。 buRXzSR
3R?7&oXvH
从实际体验来看,对于流量不大的网站来说,没有必要使用懒加载 JavaScript 的相关技术,因为本身 JavaScript 文件就不是非常大。 因此在网页加载时,就可以先加载所需要的模块。避免不必要的延迟。 `BH8v
)@3ce'
2.JavaScript 的位置问题 Etj*3/n|
&j/ WjZPF
这一部分,我们来说说 JavaScript 的位置问题对网页网站性能的影响。 'jeGERMr'
0gVylQ
为什么要考虑位置问题? e+=Ojo#
A0M)*9 f
其实不管是 CSS 还是 JavaScript,都需要考虑位置的问题,因为 HTML 的渲染和加载顺序是从上往下,也就是如果前面插入了 JavaScript 的引用,那么必须等到这个 JavaScript 下载完毕才会渲染后续的部分。 /Z>#lMg\.
-) $$4
因此 JavaScript 的插入位置就成为一个值得考虑的问题,因为不适合的位置可能引起渲染的延迟等,造成不好的用户体验。 c\.4I4uy
!$St=!
GS~jNZx
传统方案带来的问题和思考 !yH&l6s
]BCH9%zLj
CSS 放在头部,JavaScript 放在尾部,这是传统的经验,它的好处是可以让页面优先渲染, 从而页面可以快速显示。 /bVU^vo
J}KATpHs
但有事实往往没有我们预想的那么美好。 -sGfpLy<6
;04doub
有的时候会出现这么一种情况:当页面已经渲染完毕时,我们立刻去使用网站的功能,但很多时候 功能按钮会没有反应。原因也很简单,就是 JavaScript 放在页面的尾部,还没来得及加载。。。。 }9>W41
=4/lJm``
w^NE`4 -
这就纠结了。。。。 ar=uDb;
+K;(H']Z<-
两种 JavaScript 放置方式,一种放在头部,一种放在尾部(暂时忽略部分放在头部,部分放在尾部的方式),一个牺牲了渲染速度,一个牺牲了用户体验。所以很多时候 js 的问题我们需要做权衡。 6\g]Y
@xB"9s
对一般的小型网站来说,用户体验问题要远远大于页面渲染的问题,就比如上文提到的那种功能按钮不可用的情况。而且,如果 JavaScript 不是很大的话,放在头部就很好,既不会有太久的页面空白,也能让其优先加载,二者得到了很好的平衡。 !u~( \ Rb;
O|#^&d
因此,很多经验上的东西并不是绝对的,一定要根据实际的情况,包括功能特点、服务器网络情况等来综合考虑。 UbJ_'>hK6
%Ox*?l _
为此,笔者写下一个自认为较为合理的位置选择方案,仅供参考。 !tmY_[\
a*NcL(OC
图 1. 判断 JavaScript 放置位置决策表 L=VJl[DL
Bh"o{-$p8`
[font='PingFang SC', 'Hiragino Sans GB', 'Microsoft Yahei', 'WenQuanYi Micro Hei', sans-serif]从上面的分类介绍,我们也可以看出,将功能代码按类型归类到不同的 JavaScript 文件是多么的重要,比如应该放头部和应该放尾部的代码,最好不要合并在一起,不要等到出问题要优化的时候再去整理和重构,这样会增加很多不必要的工作量。 B:a&)L wp0
+I5@Gys
y0M^oLx
这不仅仅是为自己工作负责,也是为后面要读你代码的新人负责。养成好的设计编码习惯,也是技术积累的一部分。最后再根据 JavaScript 文件的功能类型,来决定是放在页面的头部还是尾部。 !CTchk<{(
55 Y BO$
五.怎样确定是不是 JavaScript 的问题? g,7`emOX
pz6fL=Xd
这个问题笔者在之前看过的的前端高性能优化(一)、(二)中 get 到了新的技能点,在这里分享给大家。 Aj;Z &
.4^Ep\\
k!>MZ
随着 信息爆炸时代的到来,网站本身性能也深刻影响着公司的形象、利益等问题。但是大多数前端测试工具都太碎片化,没有办法针对多个使用场景,而且很多都是像 yslow 这样简单打个分,也不是真实的用户体验。前一段时间在网上找到了一款 前端性能优化分析工具——Browser Insight,里面的功能相当全面,而且可以针对多个使用场景,包括:PC端,移动微信,移动浏览器,移动webview,还是 真实的用户体验,也就是说,用户访问你的网页是什么样的,从这个工具中体现出的就是什么样子的。 *ELbz}Q
/^G1wz2
p./zW )7+
基于 JavaScript 这个维度 Bi 做的也是相当丰富了。 >>Z.]
0ym>Hbax)
* h!gjbi
首先是 脚本错误 板块。Bi 里面可以从不同的时间维度查看被监控页面出现过的脚本错误,具体信息包括:发生时间、设备类型、报错的浏览器及其版本号、错误堆栈信息都可以看到,不论是 线上还是线下测试或者页面维护 都是够用了。 7;) T;X
ZC@ 33Q(
(g`G(K_
不但能看到时间、 系统、浏览器等,还可以具体定位到出错的代码行,这个确实很方便。 A/|To!R
Z O5_n
1\=)b< y
图 2.Bi 脚本错误 Waj6.PCFm
Ya
@Z&El:]3>
其次是页面响应时间板块,这个算是意外的收获了。通过响应时间板块里面的慢加载追踪,可以看到本次慢加载的页面资源加载情况,然后我们就知道该优化哪个页面的哪些 js 、css、img等。 zp:kdN7!^
+)h*)
'X d_8.
图 3.Bi 资源列表-时序图 pwtB{6)VH{
hCVe05
@E %:ALJ
六.结语 Anr''J&9`H
kU{+@MA;
JavaScript 具备许多独特的优势,笔者甚至敢说,JavaScript 很可能是目前最重要的语言,因为它能在几乎所有平台上运行,而且可以通过高度可重用、可组合的方式实现。 {AUhF}O
r"sK@
然而,不熟悉 JavaScript 性能与问题的开发者可能很快就会发现,对其代码库进行更改变得越发困难,而且这些改变可能会导致出其不意的逆反效果。 @M-i$ q[4
n}/?nP\%
笔者建议,不要像用其他语言写程序那样编写 JavaScript 程序。尽可能利用 JavaScript 独有的性能,创建小而简单的模块。这有助于你保持冷静,并爱上 JavaScript 的强大功能。 W/DSj :
_;L%? -2c
Happy JavaScripting! y (@j;Q3(r
h+=xG|1R[5
注:本文翻译自 Kurtis Kemple 的一篇文章,由小编加了一些自己的意见和看法。 W^#HR
kDbDG,O
原文地址:https://labs.mlssoccer.com/javascript-at-scale-achieving-high-velocity-160c7d78af03#.egfwqqz0a A#;6~f
TgMa! Vz
cCx@VT`0
Browser Insight 是一个基于真实用户的 Web 前端性能监控平台,能够帮大家定位网站性能瓶颈,网站加速效果可视化;支持浏览器、微信、App 浏览 HTML 和 HTML5 页面。想阅读更多技术文章,请访问OneAPM 官方技术博客。 Sk7l&B
%3b;`Oa
yvR3|
本文转自 OneAPM 官方博客

你可能感兴趣的:(优化,学习)