`
frank1998819
  • 浏览: 752015 次
  • 性别: Icon_minigender_1
  • 来自: 南京
文章分类
社区版块
存档分类

前端性能优化小纪(转)

    博客分类:
  • Html
 
阅读更多

天下武功,无坚不破,唯快不破。对前端而言,快意味着要求资源体量更小、数量更精简、内容更早呈现、交互更加人性化。当项目做到一定程度,就应该考虑性能的问题,前端的性能优化有诸多有迹可循的理论和方法,比如 Yahoo!性能军规、Google PageSpeed Insights Rules。 

我们团队一个比较老的项目首屏加载大概需要20多秒,这严重影响了用户体验,于是进行了一次首屏加载的性能优化。 

浏览器渲染过程 

首先,稍微了解一下,浏览器接收到HTML/CSS/JavaScript等资源后的渲染过程: 


浏览器在收到 HTML 文档之后会对文档进行解析开始构建 DOM (Document Object Model) 树,进而在文档中发现样式表,开始解析 CSS 来构建 CSSOM(CSS Object Model)树,这两者都构建完成后,开始构建渲染树。

DOM树描述了文档的结构与内容,CSSOM树则描述了对文档应用的样式规则,想要渲染出页面,就需要将DOM树与CSSOM树结合在一起,这就是渲染树。渲染树构建完毕后,浏览器得到了每个可见节点的内容与其样式,下一步工作则需要计算每个节点在窗口内的确切位置与大小,也就是布局阶段。当Layout布局事件完成后,浏览器会立即发出Paint Setup与Paint事件,开始将渲染树绘制成像素,绘制所需的时间跟CSS样式的复杂度成正比,绘制完成后,用户就可以看到页面的最终呈现效果了。 

暂缓JavaScript解析 

在上图构建DOM树时,<script>标签可能会阻塞html解析,从而影响首页加载速度,可以使用async进行异步加载或者用defer进行延迟加载。 

async属性表示脚本会在下载后尽快执行,但不能保证脚本会按照顺序执行。 

defer属性表示脚本会先下载,但会在整个页面都解析完成后再运行,并且按照脚本出现的先后顺序执行。 

用网上一张图能比较明显得看出两者的不同之处。 


蓝色线代表网络读取,红色线代表执行时间,这俩都是针对脚本的;绿色线代表 HTML 解析。 

用这两个属性可以很好解决由<script>引起地加载缓慢问题。 

减少不必要的HTML标签 

从浏览器渲染的流程可以看出,如果HTML中有很多不必要的标签会影响DOM解析速度并且增加了HTML文件的大小,可以对嵌套过深的结构进行优化,去除不必要的标签。 

减少CSS嵌套 

CSS嵌套过深,会影响浏览器查找选择器的速度,一定程度上产出了很多冗余的字节,一般最多嵌套3层。 

启用CSS Sprite 

CSS Sprites在国内很多人叫css精灵,是一种网页图片应用处理方式。它允许你将一个页面涉及到的所有零星图片都包含到一张大图中去,这样一来,当访问该页面时,载入的图片就不会像以前那样一幅一幅地慢慢显示出来了。 

该项目首页有有三张svg的图片,参考SVG Sprite对这三张照片进行了svg sprite的简单处理,后续在angular/cli中也可以参照这个SVG icon system with angular-cli对项目中的svg图片进行统一的处理。 

进行css sprite处理时,注意以下几点: 

  • 把图片横向合并,这样图片大小更小
  • 间距不要太大,这对图片大小影响不是很大,但对客户端解压时需要的内存更少

进行css sprite处理后,降低了首页资源请求次数。 

对于图标类的图片,最好用iconfont来减少图片的额外请求。 

压缩静态资源 

合并打包后的js、css、图片文件体积一般会比较大,这个时候要对它们进行压缩处理。gulp和webpack都有相应的压缩插件。 

针对个别图片,有时候也可以单独拿出来处理,可以去tinypng 进行在线压缩。 

使用lazyload和preloading 

在Angular中,可以在路由中用loadChildren来实现lazyload,这样可以实现按需加载,加快加载速度。 

代码 
  1. {  
  2.   path: 'home',  
  3.   loadChildren: 'app/home/home.module#HomeModule',  
  4. },  


首页显示的模块不应该过大,我们项目中首页加载的模块虽然使用了lazyload,但是模块太大,以至于严重影响了加载速度,于是对模块进行了切割,分成2个模块,对于第二个模块进行了preloading,这样在首页加载完毕后,会对该模块进行预加载,加快了路由切换时的速度。关于preloading可以参考Angular官网的自定义预加载策略。 

Nginx启用Gzip压缩 
HTTP协议上的gzip编码是一种用来改进web应用程序性能的技术,web服务器和客户端(浏览器)必须共同支持gzip。目前主流的浏览器,Chrome,firefox,IE等都支持该协议。常见的服务器如Apache,Nginx,IIS同样支持gzip。 

gzip压缩比率在3到10倍左右,可以大大节省服务器的网络带宽。而在实际应用中,并不是对所有文件进行压缩,通常只是压缩静态文件。 

在Nginx中,启用gzip: 

代码 
  1. # 开启gzip  
  2.     gzip on;  
  3.     # 启用gzip压缩的最小文件,小于设置值的文件将不会压缩  
  4.     gzip_min_length 1k;  
  5.     # gzip 压缩级别,1-10,数字越大压缩的越好,也越占用CPU时间  
  6.     gzip_comp_level 5;  
  7.     # 进行压缩的文件类型。javascript有多种形式。其中的值可以在 mime.types 文件中找到。  
  8.     gzip_types   
  9.         application/atom+xml  
  10.         application/javascript  
  11.         application/json  
  12.         application/ld+json  
  13.         application/manifest+json  
  14.         application/rss+xml  
  15.         application/vnd.geo+json  
  16.         application/vnd.ms-fontobject  
  17.         application/x-font-ttf  
  18.         application/x-web-app-manifest+json  
  19.         application/xhtml+xml  
  20.         application/xml  
  21.         font/opentype  
  22.         image/bmp  
  23.         image/svg+xml  
  24.         image/x-icon  
  25.         text/cache-manifest  
  26.         text/css  
  27.         text/plain  
  28.         text/vcard  
  29.         text/vnd.rim.location.xloc  
  30.         text/vtt  
  31.         text/x-component  
  32.         text/x-cross-domain-policy;  
  33.     # 是否在http header中添加Vary: Accept-Encoding,建议开启  
  34.     gzip_vary on;  
  35.     # 禁用IE 6 gzip  
  36.     gzip_disable "MSIE [1-6]\.";  


不同gzip_comp_level的压缩率可以参考下图: 


gzip对svg和x-icon的压缩效果比较明显,一般可以达到50%以上的压缩效果,但是对于压缩过的PNG、GIF格式图片启用Gzip,反而会因为添加标头、压缩字典,增大了图片的大小。 

启用压缩后,首页请求的资源大小由原来的10M降低到2.8M,效果还是比较明显的。 

启用http缓存 

每次访问网页时80%的时间都会花在资源下载上,因此使用缓存可以大大提高网页访问时的响应速度。 

参考H5BP配置目录下的expires.conf,作为Nginx服务器配置: 

代码 
  1. # Expire rules for static content  
  2. # No default expire rule. This config mirrors that of apache as outlined in the  
  3. # html5-boilerplate .htaccess file. However, nginx applies rules by location,  
  4. # the apache rules are defined by type. A consequence of this difference is that  
  5. # if you use no file extension in the url and serve html, with apache you get an  
  6. # expire time of 0s, with nginx you'd get an expire header of one month in the  
  7. # future (if the default expire rule is 1 month). Therefore, do not use a  
  8. # default expire rule with nginx unless your site is completely static  
  9. # cache.appcache, your document html and data  
  10. location ~* \.(?:manifest|appcache|html?|xml|json)$ {  
  11.   add_header Cache-Control "max-age=0";  
  12. }  
  13. # Feed  
  14. location ~* \.(?:rss|atom)$ {  
  15.   add_header Cache-Control "max-age=3600";  
  16. }  
  17. # Media: images, icons, video, audio, HTC  
  18. location ~* \.(?:jpg|jpeg|gif|png|ico|cur|gz|svg|mp4|ogg|ogv|webm|htc)$ {  
  19.   access_log off;  
  20.   add_header Cache-Control "max-age=2592000";  
  21. }  
  22. # Media: svgz files are already compressed.  
  23. location ~* \.svgz$ {  
  24.   access_log off;  
  25.   gzip off;  
  26.   add_header Cache-Control "max-age=2592000";  
  27. }  
  28. # CSS and Javascript  
  29. location ~* \.(?:css|js)$ {  
  30.   add_header Cache-Control "max-age=31536000";  
  31.   access_log off;  
  32. }  
  33. # WebFonts  
  34. # If you are NOT using cross-domain-fonts.conf, uncomment the following directive  
  35. # location ~* \.(?:ttf|ttc|otf|eot|woff|woff2)$ {  
  36. #  add_header Cache-Control "max-age=2592000";  
  37. #  access_log off;  
  38. # }  


上述配置禁用manifest,appcache,html,xml和json文件的缓存。 它将RSS和ATOM订阅文件缓存1小时,Javascript和CSS文件1年,以及其他静态文件(图像和媒体)1个月。 

缓存全部设置为public,所以任何系统都可以缓存它们。 将它们设置为私有将限制它们被私有缓存(例如我们的浏览器)缓存。 

关于缓存中资源的新鲜度控制可以看这篇文章HTTP缓存控制小结。 

总结 

这次只是很简单地对首屏加载进行了性能优化,减少了10个http请求,总资源大小从10.4MB降到2.8MB,首屏DOMContentLoaded时间从12秒左右降到2秒左右,load时间从22秒左右降到6秒左右,效果还是很明显的。 

参考文章 

Google Developers中performance系列文章 
Front-End Performance Checklist 2018 
前端那些事儿」② 极限性能优化 
前端性能优化相关 
HTTP缓存控制小结 
Nginx缓存最佳实践

 

分享到:
评论

相关推荐

    婚纱照微信小程序源代码

    4. 测试调试:对小程序进行功能测试和性能优化。 5. 上线发布:提交微信审核,通过后发布到微信小程序平台。 6. 后期维护:持续更新迭代,修复问题,增加新功能。 总的来说,"婚纱照微信小程序源代码"是一个集婚纱...

    整页滑动的手机版微网页

    综上所述,"整页滑动的手机版微网页"不仅涉及到前端的UI/UX设计,还涵盖了JavaScript编程、响应式布局、性能优化等多个方面的技术知识。理解和掌握这些知识点,对于创建出类似婚礼纪那样吸引人的移动网页至关重要。

    模仿婚礼季

    10. **性能优化**:关注应用的响应速度和资源消耗,可能需要进行性能调优,比如减少HTTP请求、压缩图片、缓存策略等。 通过以上这些知识点的学习和实践,开发者不仅可以掌握多种技术,还能了解软件开发的完整流程,...

    精品源码 / 炫酷特效 / 抖音超火 / 罗盘时钟 / 复古时钟

    5. **性能优化**:为了保证在各种设备上流畅运行,需要进行性能优化,比如使用requestAnimationFrame进行动画更新,避免过度绘制等。 6. **响应式设计**:确保罗盘时钟在不同屏幕尺寸和分辨率的设备上都能正常显示...

    sassport-svgo:Sass文件中的内联优化SVG

    这个工具利用了SVGO(SVG Optimizer)库的强大功能,对SVG代码进行压缩和清理,以减小文件大小,提高网页加载速度,并优化前端性能。 1. **什么是SVG?** SVG(Scalable Vector Graphics)是一种基于XML的矢量图形...

    莽荒纪积分签到系统

    最后,系统部署和运维也是重要环节,包括服务器配置、负载均衡、数据备份、性能优化等,以保证系统在高并发场景下也能稳定运行。 通过以上分析,我们可以看出《莽荒纪积分签到系统》1.0集成了多种IT技术,从后端...

    中频通信文章合集.rar

    这篇论文可能深入研究了微波频率上下变频组件的性能优化和实现方法,对于提高通信系统的整体性能至关重要。 7. **数字中频技术的研究与FPGA实现**(杨星): FPGA(现场可编程门阵列)是实现数字信号处理的常用...

    yogurt:node express前端集成解决方案

    基于这些标签后端可以自动完成对页面的性能优化。基于 widget 标签,可以轻松实现让 widget 以 BigPipe 模式渲染,详情请查看这里。提供便利的环境、数据和页面模拟。tpl 自动与 json 数据文件关联,本地就能预览...

    圆弧型布局控件

    6. **性能优化**:由于自定义布局可能会涉及到复杂的计算和绘图,因此要注意性能优化。例如,使用硬件加速、避免不必要的绘制和计算,以及利用缓存提高重绘效率。 在实际开发中,"PathButton"可能是一个实现圆弧型...

    FrontEnd-Wiki:前端Wiki,学习JavaScript,Vue.js,Node.js,其他信息等

    前端开发的知识体系广泛,包括Web标准、前端架构、工程化实践、性能优化、无障碍访问(WCAG)等。现代前端开发还涉及到模块化(如ES6模块)、状态管理、服务端渲染、TypeScript等高级话题。了解并掌握这些知识点,...

    MY_HW:2021年的前端

    这可能包括响应式设计、交互设计、性能优化、无障碍性以及对移动设备的支持等。 【标签】"HTML"表明此项目的核心内容之一是超文本标记语言(HTML)。HTML是网页内容的基础,定义了页面结构和元素。2021年的HTML不仅...

    php纯文字游戏源码,寻仙记源码

    4. **性能优化**:调整数据库查询、减少不必要的服务器负载,确保游戏流畅运行。 5. **移动端适配**:优化WAPgame,使其更适合手机和平板设备,提高移动用户的体验。 总的来说,"寻仙记"源码提供了一个基础框架,...

    landx-ai:Landx的前端回购

    随着项目的进展和用户反馈的积累,前端回购功能可能逐步完善,增加更多智能化和个性化的特性,提升用户满意度和平台的整体性能。同时,随着技术的发展,如WebAssembly、Web Components等新兴技术的引入,未来Landx-...

    i2q:通过 I2P 的类似 ICQ 的信使。 前端转ip2d

    "前端转ip2d"可能是指i2q的用户界面(UI)部分与后端I2P通信模块的交互。ip2d可能是一个单独的组件,负责处理I2P网络的底层通信,而i2q的前端则专注于提供用户友好的界面。这种分离的设计有助于提高软件的可维护性和...

    javascript 高级技巧

    10. **性能优化**:包括DOM操作优化、减少HTTP请求、使用事件委托、缓存策略等,这些都是提升JavaScript应用性能的重要手段。 11. **调试技巧**:了解如何使用浏览器的开发者工具进行断点调试、性能分析和内存检测...

    FrontEndMentor:Pasta de Desafios前端

    10. **性能优化**:学习如何通过减少重绘和回流、使用minify和压缩工具、以及合理加载CSS资源来提高页面性能。 通过这个"FrontEndMentor-main"压缩包,你将有机会实践这些CSS技巧,并逐步提升自己的前端开发技能。...

    app-ICAF:国际民航组织会议管理工具的前端

    应用程式 国际民航组织会议管理工具的前端 npm start 在开发模式下运行应用程序... 它在生产模式下正确捆绑了React,并优化了构建以获得最佳性能。 生成被最小化,并且文件名包括哈希值。 您的应用已准备好进行部署!

    时光轴 - TimeLine

    时光轴(TimeLine)是一种常见的数据可视化工具,它以时间为基础,通过垂直或水平的轴线展示事件或数据的...在开发时光轴功能时,需要综合考虑设计美学、交互体验和性能优化,确保其在不同场景下都能发挥出应有的作用。

    前端

    它在生产模式下正确捆绑了React,并优化了构建以获得最佳性能。 最小化构建,文件名包含哈希。 您的应用已准备好进行部署! 有关更多信息,请参见有关的部分。 npm run eject 注意:这是单向操作。 eject ,您将...

    myblog:网站原始码,包括前端跟后台

    为了保证数据安全性和性能,他们还需要关注认证、授权、错误处理以及数据库优化等方面。 在开源的背景下,"myblog-master"这个文件名可能表示这是项目的主分支,按照Git版本控制的习惯,master分支通常是开发的主要...

Global site tag (gtag.js) - Google Analytics