美文网首页
前端性能优化之缓存

前端性能优化之缓存

作者: zxhnext | 来源:发表于2019-05-15 12:09 被阅读0次

一、浏览器打开一个新页面的过程

image.png
如上图所示,我们来看看每一部分分别都做了什么:
-- prompt for unload: 卸载旧页面,请求新页面
---- navigationStart: 开始记时,开始处理请求页面的起始时间
-- redirect: 定向url
-- unload: 继续卸载旧页面
-- Appcache: 检查是否有离线缓存
以上操作全是在本地完成的,下面一步才开始连接网络
-- DNS
---- domainLookupStart: 开始域查找
---- domainLookupEnd: IP地址翻译结束
-- TCP:开启TCP连接,在请求资源时,是复用一个tcp连接的,以进行js,css等的串行下载

---- responseEnd: 响应完成,开始处理数据,需要注意的是,在响应过程中是不处理数据的,响应完成后才开始处理数据
-- Processing: 浏览器开始工作
---- domLoading: 将dom载入到内存当中
---- domInteractive: 解析dom,创建dom树
---- domInteractive~domContentLoaded: 这个过程中继续拿取css、js、图片资源等,到domContentLoaded时dom内容全部处理完成
---- domContentLoaded~domComplete: 这个过程中做一些其它事情,如提取页面信息,设置缓存参数等,到domComplete时dom处理结束
-- onLoad: html标签中的onLoad,开始执行脚本,处理函数等

我们需要知道的是,从prompt for unload一直到Processing页面一直是白的。我们可以根据上图来考虑需要优化的几个点:

  1. 缓存
  2. CDN
  3. TCP连接时间,加大带宽,服务器端响应速度
  4. 请求,响应速度,数据量越小,响应越快
  5. Processing,优化dom结构

二、缓存

缓存会根据请求保存输出内容的副本,例如html页面,图片,文 件,当下一个请求来到的时候:如果是相同的URL,缓存直接使 用副本响应访问请求,而不是向源服务器再次发送请求。
我们先来看一下浏览器没有缓存,或者第一次请求时的情况,如下所示:


image.png

接下来是有缓存的情况,如下所示:


image.png

我们先来解释下上图中几个缓存的意思:


image.png
  1. last-modified / if-modified-since
    这是一组请求/相应头
    响应头: * last-modified: Wed, 16 May 2018 02:57:16 GMT 01
    请求头: if-modified-since: Wed, 16 May 2018 05:55:38 GMT
    last-modified标示这个响应资源的最后修改时间,服务器端返回资源时,如果头部带上了 last-modified,那么资源下次请求时就会把值加入到请求头 if-modified-since 中,服务器可以对比这个值,确定资源是否发生变化,如果没有发生变化,则返回 304。
    当资源过期时(使用Cache-Control标识的max-age),发现资源具有Last-Modified声明,则再次向web服务器请求时带上头If- Modified-Since,表示请求时间。web服务器收到请求后发现有头If-Modified- Since 则与被请求资源的最后修改时间进行比对。若最后修改时间较新,说明资源又被改动过,则响应整片资源内容(写在响应消息包体内),HTTP 200;若最后修改时间较旧,说明资源无新修改,则响应HTTP 304 (无需包体,节省浏览),告知浏览器继续使用所保存的cache。
  2. etag / if-none-match
    这也是一组请求/相应头
    响应头: etag: "D5FC8B85A045FF720547BC36FC872550"
    请求头: if-none-match: "D5FC8B85A045FF720547BC36FC872550"
    etag是浏览器当前资源在服务器的唯一标识(生成规则由服务器决定),服务器端返回资源时,如果头部带上了 etag,那么资源下次请求时就会把值加入到请求头 if-none-match 中,服务器可以对⽐这个值,确定资源是否发生变化,如果没有发生变化,则返回 304。
    当资源过期时(使用Cache-Control标识的max- age),发现资源具有Etage声明,则再次向web服务器请求时带上头If-None-Match (Etag的值)。web服务器收到请求后发现有头If-None-Match 则与被请求资源的相应校验串进行比对,决定返回200或304。
  3. expires
    * expires: Thu, 16 May 2019 03:05:59 GMT
    在http头中设置一个过期时间,在这个过期时间之前,浏览器的请求都不会发出,而是自动从缓存中读取文件,除非缓存被清空,或者强制刷新。缺陷在于,服务器时间和⽤户端时间可能存在不⼀致,所以 HTTP/1.1 加⼊了 cache-control 头来改进这个问题。
  4. cache-control
    设置过期的时间长度(秒),在这个时间范围内,浏览器请求都会直接读缓存。当 expires 和 cache-control 都存在时,cache-control 的优先级更高。

这几个缓存的优先级如下:
cache-control > expires > etag > last-modified

  1. keep-alive

三、node中设置缓存

// last-modified
// 缺陷:文件的时间戳改动了但内容不一定改动。时间戳只能精确到秒级别,更新频繁的内容将无法生效。
var handle = function (req, res) {
    fs.stat(filename, function (err, stat) {
        var lastModified = stat.mtime.toUTCString();
        if (lastModified === req.headers['if-modified-since']) {
            res.writeHead(304, "Not Modified");
            res.end();
        } else {
            fs.readFile(filename, function(err, file) {
                var lastModified = stat.mtime.toUTCString();
                res.setHeader("Last-Modified", lastModified);
                res.writeHead(200, "Ok");
                res.end(file);
            });
        }
    });
};
// etags
var getHash = function (str) {
    var shasum = crypto.createHash('sha1');
    return shasum.update(str).digest('base64');
};
var handle = function (req, res) {
    fs.readFile(filename, function(err, file) {
        var hash = getHash(file);
        var noneMatch = req.headers['if-none-match'];
        if (hash === noneMatch) {
            res.writeHead(304, "Not Modified");
            res.end();
        } else {
            res.setHeader("ETag", hash);
            res.writeHead(200, "Ok");
            res.end(file);
        }
    });
};
// expires
// 只要本地还存在这个文件,在过期时间之前,都不会再发起请求
// 缺陷:如果用户本地时间和服务器时间不一致,那么这个缓存机制就存在问题。
var handle = function (req, res) {
    fs.readFile(filename, function(err, file) {
        var expires = new Date();
        expires.setTime(expires.getTime() + 10 * 365 * 24 * 60 * 60 * 1000);
        res.setHeader("Expires", expires.toUTCString());
        res.writeHead(200, "Ok");
        res.end(file);
    });
};
// Cache-Control
var handle = function (req, res) {
    fs.readFile(filename, function(err, file) {
        res.setHeader("Cache-Control", "max-age=" + 10 * 365 * 24 * 60 * 60 * 1000);
        res.writeHead(200, "Ok");
        res.end(file);
    });
};

四、nginx配置缓存

首先打开nginx.conf文件

gzip on // 开启压缩
etag on // 开启etag
expires 30d // 过期时间
add_header Cache-Control no-cache // 设置过期时间时要同时在下面设置这句,no-cache不要浏览器缓存

相关文章

  • 常用的后端性能优化六种方式:缓存化+服务化+异步化等

    性能优化专题 前端性能优化 数据库性能优化 jvm和多线程优化 架构层面优化 缓存性能优化 常用的后端性能优化六大...

  • 前端性能优化(中)

    性能优化调研系列文章 《前端性能优化(上)》 《前端性能优化(中)》 《前端性能优化(下)》 《前端性能优化(上)...

  • 前端性能优化(下)

    性能优化调研系列文章 《前端性能优化(上)》 《前端性能优化(中)》 《前端性能优化(下)》 《前端性能优化(中)...

  • 前端性能优化之缓存

    一、浏览器打开一个新页面的过程 ---- responseEnd: 响应完成,开始处理数据,需要注意的是,在响应过...

  • 前端性能优化指南

    前端性能优化指南 AJAX优化 缓存AJAX: 请求使用GET:当使用XMLHttpRequest时,而URL长度...

  • 漫谈Web缓存

    作者 | WilsonLiu95 背景说明 缓存一直是前端性能优化中,浓墨重彩的一笔。了解前端缓存是打造高性能网站...

  • 前端性能优化(上)

    性能优化调研系列文章 《前端性能优化(上)》 《前端性能优化(中)》 《前端性能优化(下)》 为什么要进行前端性能...

  • 【前端性能优化指南】1 - 利用缓存减少远程请求

    更多前端性能优化系列请点击这里 >> 欢迎来到「前端性能优化之旅」的第一站 —— 缓存。 当浏览器想要获取远程的数...

  • js基础常见问题总结(三)~

    web前端性能优化总结 浏览器访问优化 1、减少http请求,合理设置 HTTP缓存2、使用浏览器缓存3、启用压缩...

  • 前端性能优化之缓存技术

    缓存一直以来都是用来提高性能的一项必不可少的技术 , 利用这项技术可以很好地提高web的性能。 缓存可以很有效地降...

网友评论

      本文标题:前端性能优化之缓存

      本文链接:https://www.haomeiwen.com/subject/jxgywqtx.html