浏览器工作原理:https://www.cnblogs.com/thonrt/p/10008220.html

浏览器渲染原理: https://www.cnblogs.com/thonrt/p/10008742.html

基于上面这两篇文章,我们可以把web性能优化分为两大方面:

  1. 网络传输性能优化
  2. 页面渲染性能优化

本文主要介绍网络传输性能优化。

本人总结网络传输性能优化主要有以下几个点:

  • 减少请求数
  • 减小请求资源体积
  • 提升网络传输速率

下面我们来逐一击破。

1.资源打包和压缩

想要实现首屏渲染优化,必须对资源进行打包和压缩

  • 对css/js进行压缩,就是减小请求资源体积。
  • 对css/js进行资源合并,就是减少请求数

一般会把公共库合并,因为公共库不会经常改变

把不同的页面合并,但还是遵循见机行事,随机应变

至于对css和js压缩合并的工具,本人比较倾向webpack,毕竟从版本2用到版本4的。

2.浏览器缓存

浏览器缓存主要有两个缓存:

  • 强缓存:不会向服务器发送请求
  • 协商缓存: 304状态码

用户行为对浏览器缓存:

  • 地址栏访问,触发缓存机制
  • 新开窗口,前进后退,触发缓存机制
  • F5跳过强缓存,进入协商缓存
  • F5 + Ctrl 跳过强缓存和协商缓存

下面通过文字来解释下这个图

2.1 强缓存,与强缓存有关的header字段:expires和cache-control

1.expires,它的值是一个绝对时间的GMT格式的字符串。如果发送请求的时间在expires之前,那么本地缓存始终有效,否则会发送请求到服务器来获取资源

2.cache-control:max-age,主要是利用max-age值来判断,它是一个相对值。资源第一次请求的时间个cache-control设定的有效期,计算出一个资源过期时间,再拿这个过期时间和当前的请求时间对比,如果请求时间在过期时间之前,就能命中缓存,否则就会发请求到服务器请求资源。

如果Cache-control和expires同时存在,cache-control优先级较高

2.2 协商缓存,与协商缓存有关的header字段:Last-Modified和If-Modified-Since

这两组是成对出现的。即第一次请求的响应带上某个字段(Last-Modified或者Etag),则后续请求则会带上对应的请求字段(If-Modified-Since或者If-None_match)。

如响应头没有Last-Modified或者Etag字段,则请求头也不会有对应的字段。

1.Last-Modified/If-Modified-Since

  • 浏览器第一个请求资源时,服务器在返回资源的同时,在respone的header加上Last-Modified的header,这个header表示在资源服务器上的最后的修改时间
  • 浏览器再次请求这个资源时,在request的header中加上If-Modified-Since的header,这个header就是上一次请求返回的Last-Modified的值
  • 服务器再次受到资源请求时,根据浏览器传过来的If-Modified-Since和服务器上最后的修改资源时间判断资源是否变化。如果没有变化就返回304 Not Modified,但是不会返回资源内容。如果有变化,就正常返回资源内容。当返回304时,不会再添加Last-Modified的header。
  • 浏览器收到304响应后,就会从缓存中加载资源
  • 如果协商缓存没有命中,浏览器直接从服务器加载资源,Last-Modified会更新返回到respone的header中

2.Etag/If-None-Match

  • 浏览器第一个请求资源时,服务器在返回资源的同时,在respone的header加上Etag的header,这个header表示在资源服务器上的最后的标志
  • 浏览器再次请求这个资源时,在request的header中加上If-None-Match的header,这个header就是上一次请求返回的Etag的标志
  • 服务器再次受到资源请求时,根据浏览器传过来的If-None-Match和服务器上最后的修改资源的Etag,判断资源是否变化。如果没有变化就返回304 Not Modified,但是不会返回资源内容。如果有变化,就正常返回资源内容。当返回304时,会再次添加Etag的header。
  • 浏览器收到304响应后,就会从缓存中加载资源
  • 如果协商缓存没有命中,浏览器直接从服务器加载资源,Last-Modified会更新返回到respone的header中

2.3  那有了Last-Modified,为什么还要Etag?

Etag的出现主要是解决last-modified比较难解决的问题:

某些服务器不能精准的获取文件最后的修改时间

某些文件修改频繁,比如在一秒以内修改了N次,If-modified-Since能检查到s级的,这种修改就无法判断。

这时,利用Etag能够更加准确的控制缓存,因为Etag是服务器自动生成或者由开发中生成对应资源在服务器的唯一标识符。

Etag的优先级高于Last-Modified, Etag的缓存会被写入硬盘中

强缓存如何重新加载缓存过的资源?

强缓存不会发送请求到服务端,根据设置的缓存时间,浏览器一直从缓存中获取资源,在这期间,若资源发生变化,浏览器在缓存期间就一直得不到最新的资源。

那怎么解决?

我们在构建的时候,需要为我们为静态资源添加md5 hash后缀,避免资源更新而引起的前后端文件无法同步的问题

这个图更加直观

3. 图片资源优化

在我们实际开发中,真正占用了大量网络传输资源的,并不是这些文件,而是图片。所以对图片进行优化工作的话,你就能看见明显的效果。

3.1 不要在HTML中缩放图像

比如在一个200*200的容器里面放了一张400*400的图片,一张200kb和2M的图片的传输时间会是200m和12s的差距,所以当你需要多大的图片的时候,就在服务器准备多大的图片,尽量固定图片尺寸。

3.2 使用雪碧图 Css Sprite , Svg Sprite

这里给大家推荐一个在线生成雪碧图的工具:https://www.toptal.com/developers/css/sprite-generator

还有插件生成雪碧图的方法:webpack-spritesmith

首先介绍写插件生成雪碧图的思路:

首先,把所有的小图标放置在一个文件夹内便于管理

然后,我们需要插件去读取这个文件下内的所有图片资源文件,以文件夹名称生成一张雪碧图到指定的位置,并且输出能够正确使用的css文件

3.3 使用字体图标 iconfont

无论是压缩的图片还是雪碧图,终归还是图片,只要是图片就会占用大量传输网络资源。但是字体图标的出现,让前端看到了另外一个神奇的世界。

我最喜欢用的是阿里矢量图标库(网址:http://www.iconfont.cn/ ),里面有大量的矢量图资源,而且你只需要像在淘宝采购一样把他们添加至购物车就能把它们带回家,整理完资源后还能自动生成 CDN 链接,可以说是完美的一条龙服务了。(图片来自官网首页)

图片能做的很多事情,矢量图都能作,而且它只是往 HTML 里插入字符和 CSS 样式而已,和图片请求比起来资源占用完全不在一个数量级,如果你的项目里有小图标,就是用矢量图吧。

但如果我们做的是公司或者团队的项目,需要使用到许多自定义的字体图标,可爱的设计小姐姐们只是丢给你了几份.svg图片,你又该如何去做呢?

其实也很简单,阿里矢量图标库就提供了上传本地 SVG 资源的功能,这里另外推荐一个网站——icomoon。icomoon 这个网站也为我们提供了将 SVG 图片自动转化成 CSS 样式的功能。(图片来自 icomoon 首页)

我们可以点击 Import Icons 按钮导入我们本地的 SVG 资源,然后选中他们,接下来生成 CSS 的事情,就交给 icomoon 吧,具体的操作,就和阿里矢量图标库类同了。

3.4 使用Webp

WebP 格式,是谷歌公司开发的一种旨在加快图片加载速度的图片格式。图片压缩体积大约只有 JPEG 的 2/3,并能节省大量的服务器带宽资源和数据空间。Facebook、Ebay 等知名网站已经开始测试并使用 WebP 格式。

我们可以使用官网提供的 Linux 命令行工具对项目中的图片进行 WebP 编码,也可以使用我们的线上服务,这里我推荐叉拍云(网址:https://www.upyun.com/webp )。但是在实际的上线工作中,我们还是得编写 Shell 脚本用命令行工具进行自动化编译,测试阶段用线上服务方便快捷。

4 使用CDN

Last but not least,再好的性能优化实例,也必须在 CDN 的支撑下才能到达极致。

如果我们在 Linux 下使用命令$ traceroute targetIp或者在 Windows 下使用批处理> tracert targetIp,都可以定位用户与目标计算机之间经过的所有路由器,不言而喻,用户和服务器之间距离越远,经过的路由器越多,延迟也就越高。使用 CDN 的目的之一便是解决这一问题,当然不仅仅如此,CDN 还可以分担 IDC 压力。

当然,凭着我们单个人的资金实力(除非你是王思聪)是必定搭建不起来 CDN 的,不过我们可以使用各大企业提供的服务,诸如腾讯云等,配置也十分简单,这里就请大家自行去推敲啦。

web性能优化-网络传输性能优化的更多相关文章

  1. 常见的磁盘I/O和网络I/O优化技巧

    磁盘I/O 优化 性能检测 应用程序通过访问磁盘来读取数据,而磁盘I/O 通常都是很耗时间的,所以一般我们来判断I/O是否有瓶颈的时候,就需要一些参数指标来参考. WAIT 指标 :压测应用程序,查看 ...

  2. HTML5 网络拓扑图性能优化

    HTML5 中的 Canvas 对文本的渲染(fillText,strokeText)性能都不太好,比如设置字体(font).文本旋转(rotation),如果绘制较多的文本时,一些交互操作会手动很大 ...

  3. web移动端性能调优及16ms优化

    本文只是一个索引,收集了网络上大部分关于调试及优化方面的文章,从中挑选了一些比较好的文章分享给大家. 移动端性能不及桌面浏览器性能的10分之1,特别是在android设备良莠不齐的情况下,性能显得尤为 ...

  4. [转载][转]修改/proc目录下的参数优化网络性能

    原文地址:[转]修改/proc目录下的参数优化网络性能作者:雪人 网络优化 注意: 1. 参数值带有速度(rate)的参数不能在loopback接口上工作. 2.因为内核是以HZ为单位的内部时钟来定义 ...

  5. web页面内容优化管理与性能技巧

    来源:GBin1.com 回 想一下,以前我们不得不花费大量时间去优化页面内容(图片.CSS等等),如今用户有更快速的互联网链接,我们似乎能够使用更大的图像或更大的闪 存文件,里面包含的有视频或者图片 ...

  6. 一个Web报表项目的性能分析和优化实践(五):重构有助于性能优化么?

    项目从初次开发到现在,已经快3年了.期间,有N个工程师参与过. 需求方面:增加减少,反反复复,无数次:人力方面:增加减少,不稳定:时间方面:功能开发着急上线,Bug开发紧急修复. 因此,代码臃肿,问题 ...

  7. Java生鲜电商平台-SpringCloud微服务架构中网络请求性能优化与源码解析

    Java生鲜电商平台-SpringCloud微服务架构中网络请求性能优化与源码解析 说明:Java生鲜电商平台中,由于服务进行了拆分,很多的业务服务导致了请求的网络延迟与性能消耗,对应的这些问题,我们 ...

  8. spark性能调优:资源优化

    在开发完Spark作业之后,就该为作业配置合适的资源了.Spark的资源参数,基本都可以在spark-submit命令中作为参数设置.很多Spark初学者,通常不知道该设置哪些必要的参数,以及如何设置 ...

  9. 一:MySQL数据库的性能的影响分析及其优化

    MySQL数据库的性能的影响分析及其优化 MySQL数据库的性能的影响 一. 服务器的硬件的限制 二. 服务器所使用的操作系统 三. 服务器的所配置的参数设置不同 四. 数据库存储引擎的选择 五. 数 ...

随机推荐

  1. Django-ORM之ManyToManyField的使用-多对多关系

    表结构设计 多对多关系表创建外键,典型例子:书--作者--出版社,书与作者的关系就可以看作是多对多关系. # 表结构设计 class Book(models.Model): title = model ...

  2. VirtualBox下Centos6.8网络配置

    win10环境下,VirtualBox和Centos6.8已经按照完毕,下面配置Centos6.8网络. 1.设置VirtualBox为桥接模式,具体的有三种联网方法,我们参考http://www.c ...

  3. C++中map和unordered_map的用法

    1. 简介 map和unordered_map都是c++中可以充当字典(key-value)来用的数据类型,但是其基本实现是不一样的. 2. map 对于map的底层原理,是通过红黑树(一种非严格意义 ...

  4. python+selenium调用JavaScript

    有些浏览器的页面操作,不能依靠WebDriver提供的API来操作,需要借助JavaScript脚本. webdriver提供了execute_script()方法来执行JavaScript代码. f ...

  5. js同步任务和异步任务的执行顺序

    先来道今日头条面试题开开胃 async function async1() { console.log('async1 start'); await async2(); console.log('as ...

  6. LeetCode-求最长回文子序列

    题目:给定一个字符串,求它的最长回文子串 /*求最长回文子串,以当前字符为中心,向两边同时拓展*/ string longestPalindrome(string s) { int len = s.l ...

  7. luoguP1379-八数码难题(双向bfs)

    题目链接:https://www.luogu.org/problemnew/show/P1379 题意:用字符串表示八数码,求根据给定八数码得到末状态“123804765”最少的步数. 思路:这题很方 ...

  8. Roadmap-学习目标

    自学过一些HTML标签,学的不多也没经常用,但还是比较喜欢前端,希望可以深入学习有用的东西,最后弄一个自己看的过去的博客练练.手.

  9. jdbc简单使用

    1.代码 import java.sql.*; public class DBUtil { public static void main(String[] args) throws ClassNot ...

  10. SYN攻击源码

    一.linux下源代码实现/* syn flood by wqfhenanxc. * random soruce ip and random sourec port. * use #include & ...