前端性能优化(一)

前言

最近跟同事一直忙于关于前端项目的性能分析以及性能优化,前端性能直接影响了用户的体验,针对于前端性能问题,一直是一个大家热议的话题,也并没有一个比较完整通用的解决方案,以下是我个人的一些认识与实践。

性能优化概述

从输入 URL 到页面加载完成,完整的链路

image.png

1.DNS 解析
2.TCP 连接
3.HTTP 请求抛出
4.服务端处理请求,HTTP 响应返回
5.浏览器拿到响应数据,解析响应内容,把解析的结果展示给用户

整个性能消化

image.png

http层面优化

  • DNS 解析:
    DNS 实现域名到IP的映射。通过域名访问站点,每次请求都要做DNS解析。目前每次DNS解析,通常在200ms以下。一般采用DNS Prefetch 一种DNS 预解析技术,当你浏览网页时,浏览器会在加载网页时对网页中的域名进行解析缓存,这样在你单击当前网页中的连接时就无需进行DNS的解析,减少用户等待时间,提高用户体验。
<link rel="dns-prefetch" href="www.baidu.com" />  
只有部分浏览器支持
  • TCP 连接:
    采用http2.0,可以复用tcp通道,采用二进制格式而非文本格式,使用报头压缩,HTTP/2降低了开销,支持cache push

  • 浏览器并发
    基于端口跟线程切换开销,浏览器不可能无限的并发请求。chrome的并发为6,超过限制数目的请求就会被阻塞;
    对于某些静态资源,图片等等,我们可以对其URL分散处理 ,不同的资源域名(部署在cdn上)。

  • http请求次数
    减少http的请求次数,将多个请求合并成同一个,减少http的开销

  • webpack
    充分利用webpack提供给我们的能力,利用DllPlugin与commonPlugins等插件对我们代码进行
    优化,文件的分割与合并,公共代码的提取,长缓存等策略,webpack是个很好的东西,值得大家仔细研究

  • http压缩
    采用Gzip压缩:HTTP 压缩就是以缩小体积为目的,对 HTTP 内容进行重新编码的过程,原理是找出一些重复出现的字符串、临时替换它们,从而使整个文件变小,文件中代码的重复率越高,那么压缩的效率就越高,使用 Gzip 的收益也就越大

图片优化

image.png

缓存

浏览器缓存

  • 强缓存:
    浏览器在请求某一资源时,会先获取该资源缓存的header信息,判断是否命中强缓存(cache-control和expires信息),若命中直接从缓存中获取资源信息,包括缓存header信息;本次请求根本就不会与服务器进行通信

    • expires:这是http1.0时的规范;它的值为一个绝对时间的GMT格式的时间字符串,如Mon, 10 Jun 2015 21:31:12 GMT,如果发送请求的时间在expires之前,那么本地缓存始终有效,否则就会发送请求到服务器来获取资源
    • cache-control:max-age=number,这是http1.1时出现的header信息,主要是利用该字段的max-age值来进行判断,它是一个相对值;资源第一次的请求时间和Cache-Control设定的有效期,计算出一个资源过期时间,再拿这个过期时间跟当前的请求时间比较,如果请求时间在过期时间之前,就能命中缓存,否则就不行;cache-control除了该字段外,还有下面几个比较常用的设置值:no-cache ,no-store,public,private
  • 协商缓存(对比缓存)

    • Last-Modified/If-Modified-Since:第一次请求,服务端在Response Headers :Last-Modified:Fri, 27 Oct 2017 06:35:57 GMT,也就是服务端最后修改该资源的时间。
      浏览器再次跟服务器请求这个资源时,在request的header上加上If-Modified-Since的header,这个header的值就是上一次请求时返回的Last-Modified的值,服务器进行比较,如果相同则返回304,否则浏览器直接从服务器加载资源时,Last-Modified的Header在重新加载的时候会被更新,下次请求时,If-Modified-Since会启用上次返回的Last-Modified值
    • Etag/If-None-Match: 服务器会为每个资源生成一个唯一的标识字符串,只要文件内容不同,它们对应的 Etag 就是不同的;If-Modified-Since能检查到的精度是s级的,某些服务器不能精确的得到文件的最后修改时间,我们编辑了文件,但文件的内容没有改变。因为服务器是根据文件的最后修改时间来判断的,导致重新请求所以才出现了Etag,Etag对服务器也有性能损耗
      Last-Modified与ETag是可以一起使用的,服务器会优先验证ETag,一致的情况下,才会继续比对Last-Modified,最后才决定是否返回304。
  • 请求过程总结:


    image.png
  • memory cache 与 disk cache
    from memory cache代表使用内存中的缓存,from disk cache则代表使用的是硬盘中的缓存,浏览器读取缓存的顺序为memory –> disk。在浏览器中,浏览器会在js和图片等文件解析执行后直接存入内存缓存中,那么当刷新页面时只需直接从内存缓存中读取(from memory cache);而css文件则会存入硬盘文件中,所以每次渲染页面都需要从硬盘读取缓存(from disk cache)。

  • CDN缓存
    CDN缓存一般是由网站管理员自己部署,为了让他们的网站更容易扩展并获得更好的性能。通常情况下,浏览器先向CDN网关发起Web请求,网关服务器后面对应着一台或多台负载均衡源服务器,会根据它们的负载请求,动态将请求转发到合适的源服务器上。从浏览器角度来看,整个CDN就是一个源服务器,从这个层面来说,浏览器和服务器之间的缓存机制,在这种架构下同样适用

  • 应用缓存
    Cookie:同一个域名下的所有请求,都会携带 Cookie,大小限制4kb
    Session Storage:用来存储生命周期和它同步的会话级别的信息,关闭浏览器就不存在
    Local Storage:持久化缓存 5-10Mb
    Service Worker缓存:
    pwa,会拦截http请求,对资源进行离线缓存、消息推送,无法直接访问dom,
    利用workbox插件非常容易接入pwa技术

浏览器渲染

浏览器渲染机制

  • DOM树:
    解析 HTML 以创建的是 DOM 树(DOM tree ):渲染引擎开始解析 HTML 文档,转换树中的标签到 DOM 节点,它被称为“内容树”。
  • CSSOM树:
    解析 CSS(包括外部 CSS 文件和样式元素)创建的是 CSSOM 树。CSSOM 的解析过程与 DOM 的解析过程是并行的。
    -渲染树:
    CSSOM 与 DOM 结合,之后我们得到的就是渲染树(Render tree )。
  • 布局渲染树:
    从根节点递归调用,计算每一个元素的大小、位置等,给每个节点所应该出现在屏幕上的精确坐标,我们便得到了基于渲染树的布局渲染树(Layout of the render tree)。
  • 绘制渲染树:
    遍历渲染树,每个节点将使用 UI 后端层来绘制。整个过程叫做绘制渲染树(Painting the render tree)。

阻塞

  • 普通模式,JS 会阻塞浏览器,浏览器必须等待 index.js 加载和执⾏完毕才能去做其它事情。一般将此类js放在在<body>标签的底部,减少对整个页面下载的影响
<script src="index.js"></script>
  • async 模式:JS 不会阻塞浏览器做任何其它的事情。它的加载是异步的,当它加载结束,JS 脚本会⽴即执⾏。
<script async src="index.js"></script>
  • defer 模式:JS 的加载是异步的,执⾏是被推迟的。等整个⽂档解析完成DOMContentLoaded 事件即将被触发时,被标记了defer 的 JS ⽂件才会开始依次执⾏
<script defer src="index.js"></script>

⼀般当我们的脚本与 DOM 元素和其它脚本之间的依赖关系不强时,我们会选⽤ async;当脚本依赖于 DOM
元素和其它脚本的执⾏结果时,我们会选⽤ defer。

  • 动态加载脚本:此文件当元素添加到页面之后立刻开始下载。无论在何处启动下载,文件的下载和运行都不会阻塞其他页面处理过程。甚至可以将这些代码放在<head>部分而不会对其余部分的页面代码造成影响
var script = document.createElement ("script");
   script.type = "text/javascript";
   script.src = "script1.js";
   document.getElementsByTagName("head")[0].appendChild(script);

服务器ssr渲染

  • 定义:
    服务端渲染的模式下,当⽤户第⼀次请求⻚⾯时,由服务器把需要的组件或⻚⾯渲染成 HTML字符串,然后把它返回给客户端。客户端拿到⼿的,是可以直接渲染然后呈现给⽤户的 HTML 内容,不需要为了⽣成 DOM 内容⾃⼰再去跑⼀遍 JS 代码。所见即为所得

  • 优缺点:
    SEO :可以有“现成的内容”拿给搜索引擎看
    ⾸屏加载速度:服务端渲染模式下,服务器给到客户端的已经是⼀个服务端处理好的可以拿来呈现给⽤户的⽹⻚

缺点: ⾮常吃硬件资源

css、js性能

编码能力

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,723评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,080评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,604评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,440评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,431评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,499评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,893评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,541评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,751评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,547评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,619评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,320评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,890评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,896评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,137评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,796评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,335评论 2 342