简单聊聊Web优化

使用缓存的优劣

因为Web的访问时下载特性,使用缓存可以有效避免每次访问都下载资源给服务器造成带宽压力、同时减少Web加载时间。

但缓存使用不当,会造成用户无法看到最新的内容或者显示问题。

 

浏览器缓存机制

根据http协议,在 http 1.0 时代,给客户端设定缓存方式一般通过两个字段 Pragma 和 Expires:

<meta http-equiv="pragma" content="no-cache" >

<meta http-equiv="Expires" content="Tue, 01 Jan 1980 1:00:00 GMT">

其中pragma字段代表是否使用缓存,Expires代表缓存时间

 

http 1.1 新增加了 Cache-Control 来定义缓存过期时间,目的是针对上述 Expires 时间是相对于服务器而言,无法保证和客户端时间统一的问题

<meta http-equiv="Cache-Control" content="public,max-age=900">

max-age:指示客户机可以接收生存期不大于指定时间(以秒为单位)的响应。

今天主要说明的三种缓存方式:

public: 所有内容都将被缓存(客户端和代理服务器都可缓存)。

no-store:所有内容都不会被缓存到缓存或 Internet 临时文件中。

no-cache: 告诉浏览器、缓存服务器,不管本地副本是否过期,使用资源副本前,一定要到源服务器进行副本有效性校验。

 

 

  • Public缓存

以apache为例:

打开httpd.conf,找到并取消注释:

LoadModule headers_module modules/mod_headers.so

 

然后在extra/ httpd-vhosts.conf中加入:

header set cache-control " public,max-age=5"

设置完毕后,重启apache,刷新浏览器页面,观察缓存时间,过5秒后,观察缓存时间。

 

在有效期内,浏览器返回的状态码均为200,from cache。

 

  • No-cache缓存

在进行一个测试:

header set cache-control "no-cache"

设置完毕,重启apache,刷新浏览器页面观察,此时应该状态码为304

这种缓存模式通过header头的两个字段:Last-Modified(最后修改时间)和ETag(唯一标识符)来判断是否需要重新更新资源。

Last-Modified代表的是文件最后修改时间

ETag代表的是文件唯一标识符(具体规则由服务器软件自动判定或手动设置)

 

判断这两个参数是否一致,如果一致返回状态码304,代表这个资源没有被更改过(可以使用本地)

 

  • No-store缓存

就是不使用缓存,每次打开页面一定向服务器索取最新资源。

 

Public与no-cache对比:

虽然no-cache可以随时使用最新的资源且节约服务器带宽,但依然要向服务器发起http请求进行询问,没有能够非常有效的减少http请求的次数。

Public这种强缓存可以将请求和带宽优化做到极致,但如果利用不好就会造成用户显示内容的滞后。

no-store(禁用浏览器缓存)考虑服务器压力问题一般不会应用在网站上,小部分内网、局域网用户会用到。

 

具体可以看流程图:

https://img-blog.csdn.net/20160918161516084?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center

 

 

浏览器信息储存发展

超文本标记语言(第一版)——在1993年6月作为互联网工程工作小组(IETF)工作草案发布(并非标准),1997年12月提出了HTML4。

之后随着计算机普及,互联网人数增多,Web的复杂性提高,很快HTML4的功能与标准不能满足建站者的需要,2014年HTML5标准规范,正式宣告HTML5时代到来。

因为http是无状态协议,所以当一个用户访问多个页面时无法确定其身份,所以发明了Cookie用来保存身份或其他信息,这是石器时代唯一的本地储存功能。

每个HTTP请求,浏览器会自动将Cookie附加到请求头中,同时每个Cookie有4KB的大小限制。一个是减少本地磁盘占用,另一个是由于请求头中会附带Cookie,会增加请求头的大小。

 

浏览器本地储存技术

为了满足更复杂的网页需求,HTML5标准制定了多种本地储存规范,其中localStorage、sessionStorage兼容性良好,基本所有浏览器都支持,Web SQL则只有Chrome、Safari、Opera在进行了实现。

localStorage、sessionStorage是一种key、value的简单储存方式,一般浏览器支持分配5-20MB的储存空间。其中localStorage是储存在硬盘上的,sessionStorage储存在内存中,在关闭浏览器后消失。

 

使用很简单:只有三个API:

localStorage.setItem()  localStorage.getItem()  localStorage.removeItem()

但要注意的是清理浏览器缓存时会被清理掉。

 

Js、css文件混淆压缩

再上线之前对js、css代码进行压缩,不仅保护代码原创性,还能减少体积。

这里使用uglifyjs进行演示:

通过Node.js进行安装:

npm install uglify-js –g

安装好后,进入目录,运行命令(将inet.js压缩为inet-min.js):

uglifyjs inet.js -o inet-min.js

还有一些其他参数这里一并列出来:

  --source-map                  指定输出的文件产生一份sourcemap 
  --source-map-root             此路径中的源码编译后会产生sourcemap
  --source-map-url              放在//#sourceMappingURL的sourcemap路径.  默认是 
                                --source-map传入的值.
  --source-map-include-sources  如果你要在sourcemap中加上源文件的内容作为sourcesContent属性,
                                就传这个参数吧。
  --source-map-inline           把sourcemap以base64格式附在输出文件结尾
  --in-source-map               输入sourcemap。假如的你要编译的JS是另外的源码编译出来的。
                                假如该sourcemap包含在js内,请指定"inline"。
  --screw-ie8                   是否要支持IE6/7/8。UglifyJS默认不兼容IE。
  --support-ie8                 是否要支持IE6/7/8,等同于在`compress`, `mangle` 和
                                 `output`选项中都设置`screw_ie8: false`
  --expr                        编译一个表达式,而不是编译一段代码(编译JSON时用)
  -p, --prefix                  忽略sourcemap中源码的前缀。例如`-p 3`会干掉文件名前面3层目录
                                以及保证路径是相对路径。你也可以指定`-p relative`,让UglifyJS
                                自己计算输出文件、sourcemap与源码之间的相对路径。
  -o, --output                  输出文件,默认标准输出(STDOUT)
  -b, --beautify                美化输出/指定输出 选项
  -m, --mangle                  Mangle的名字,或传入一个mangler选项.
  -r, --reserved                mangle的例外,不包含在mangling的名字
  -c, --compress                是否启用压缩功能(true/fasle),或者传一个压缩选项对象, 例如 
                                `-c 'if_return=false,pure_funcs=["Math.pow","console.log"]'`,
                                `-c`不带参数的话就是用默认的压缩设置。
  -d, --define                  全局定义
  -e, --enclose                 所有代码嵌入到一个大方法中,传入参数为配置项
  --comments                    保留版权注释。默认保留Google Closure那样的,保留JSDoc-style、
                                包含"@license" 或"@preserve"字样的注释。你也可以传下面的参数:
                                - "all" 保留所有注释
                                - 正则(如`/foo/`、`/^!/`)保留匹配到的。要注意,如果启用了压
                                缩,因为会移除不可达代码以及压缩连续声明,因此不是*所有*注释都能
                                保留下来。
  --preamble                    在输出文件开头插入的前言。你可以插入一段注释,例如版权信息。
                                这些不会被编译,但sourcemap会改成当前的样子。
  --stats                       在STDERR中显示操作运行时间。
  --acorn                       用 Acorn解析。
  --spidermonkey                假如输入文件是 SpiderMonkey AST 格式(像JSON).
  --self                        把UglifyJS2本身也构建成一个依赖包
                                (等同于`--wrap=UglifyJS --export-all`)
  --wrap                        所有代码嵌入到一个大函数中,让"exports"和"global"变量有效,
                                你需要传入一个参数指定模块被浏览器引入时的名字。
  --export-all                  只当`--wrap`时有效,告诉UglifyJS自动把代码暴露到全局。
  --lint                        显示一些可视警告
  -v, --verbose                 Verbose
  -V, --version                 打印版本号.
  --noerr                       不要为-c,-b 或 -m选项中出现未知选项而抛出错误。
  --bare-returns                允许返回函数的外部。当最小化CommonJs模块和Userscripts时,
                                可能匿名函数会被.user.js引擎调用立即执行(IIFE)
  --keep-fnames                 不要混淆、干掉的函数的名字。当代码依赖Function.prototype.name时有用。
  --reserved-file               要保留的文件的名字
  --reserve-domprops            保留(绝大部分?)DOM的属性,当--mangle-props
  --mangle-props                混淆属性,默认是`0`.设置为`true`或`1`则会混淆所有属性名。
                                设为`unquoted`或 `2`则只混淆不在引号内的属性。`2`时也会让
                                `keep_quoted_props` 美化选项生效,保留括号内的属性;让压缩选项
                                的`properties`失效,阻止覆写带点号(.)的属性。你可以通过在命令
                                中明确设置来覆写它们。
  --mangle-regex                混淆正则,只混淆匹配到的属性名。
  --name-cache                  用来保存混淆map的文件
  --pure-funcs                  假如返回值没被调用则可以安全移除的函数。 
                                例如`--pure-funcs Math.floor console.info`(需要设置 `--compress`)

一般使用-m参数进行最小化压缩

 

零散图片合并

多张图片合并在一起能够有效减少请求次数,但维护起来会相应变困难一些,图片合并工具也有很多,但我一般只用PS。

Css3规范中也可以将图片转化为base64编码格式放到css文件中,从而减少图片的加载,非常适合多组的零散小图,但维护性略差。

 

服务器使用gzip压缩

Gzip压缩可以先在服务端进行压缩,然后传递给浏览器后浏览器在进行解压,从而减少大小,以apache为例,打开httpd.conf:

LoadModule deflate_module modules/mod_deflate.so

就能打开gzip压缩,

接着在下方添加代码:

<IfModule mod_deflate.c>

# 告诉 apache 对传输到浏览器的内容进行压缩

SetOutputFilter DEFLATE

# 压缩等级1-9

DeflateCompressionLevel 9

#设置不对后缀gifjpgjpegpng的图片文件进行压缩

SetEnvIfNoCase Request_URI .(?:gif|jpe?g|png)$ no-gzip dont-vary

</IfModule>

一般文本压缩率能达到50%甚至更好,图片压缩效果不明显,同时在header里面就能看到:Content-Encoding:gzip字段。

我本地测试一个6kb的html和css在启用level1时就能压缩到2kb,但1-9效果并不明显。虽然gzip好用,但是需要消耗cpu处理,还是要看服务器本身的场景,带宽重要还是CPU更重要。

 

图片懒加载

即当网页很长时,只加载第一屏的图片,当用户继续往后滚屏的时候才加载后续的图片。因为不是所有用户都想浏览整个网页。

这个实现方法一般是在开发时配合处理。

 

将资源分离或放入CDN

一般来说,浏览器会对统一域名下的http请求数进行限制。

比如a.dajiaochongmanhua.com下有30张图片资源,那么实际上浏览器不会同时加载这30张图片,只会同时下载10张(具体几张看浏览器机制)。

但a.dajiaochongmanhua.com、b.dajiaochongmanhua.com、c.dajiaochongmanhua.com各有10张却会同时下载30张。

且还有一个好处不会携带cookie,减少请求头大小。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值