一次首页优化
网站的首页需要调用其他业务同学提供的接口,上线后发现调用这个接口会有一定的延迟,用户需要等待较长时间,于是我们想着怎么样最快的把首页呈现给用户。
首页静态化
第一个冒入脑海的想法就是首页静态化,然而在前后端分离大行其道的今天,首页长这样(为了演示我format了一下):
<!DOCTYPE html>
<html lang=en>
<head>
<meta charset=utf-8>
<meta http-equiv=X-UA-Compatible content="IE=edge,chrome=1">
<meta name=viewport content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no">
<meta name=keywords content="">
<meta name=description content="">
<meta name=apple-mobile-web-app-capable content=yes>
<meta name=apple-mobile-web-app-status-bar-style content=black>
<meta name=format-detection content="telephone=no,email=no">
<meta name=robots content=index,follow>
<meta name=Description content=xxxxxx>
<title>xxxxx</title>
<link rel=icon href=/static/logos.png>
<link href=/static/js/chunk-2486f8be.605228fd.js rel=prefetch>
<link href=/static/js/chunk-358ee132.522eff97.js rel=prefetch>
<link href=/static/js/chunk-6781e124.544bef60.js rel=prefetch>
<link href=/static/js/chunk-68563222.b4c37bc3.js rel=prefetch>
<link href=/static/css/app.238f510c.css rel=preload as=style>
<link href=/static/css/chunk-vendors.bac5cfc7.css rel=preload as=style>
<link href=/static/js/app.26753028.js rel=preload as=script>
<link href=/static/js/chunk-vendors.dfdeb870.js rel=preload as=script>
<link href=/static/css/chunk-vendors.bac5cfc7.css rel=stylesheet>
<link href=/static/css/app.238f510c.css rel=stylesheet>
</head>
<body id=wrapper>
<noscript><strong>We're sorry but vue_cli_oss doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript>
<navigator id=navigator>
<!-- vue-ssr-outlet -->
</navigator>
<div id=app></div>
<script src=/static/js/chunk-vendors.dfdeb870.js></script><script src=/static/js/app.26753028.js></script>
</body>
</html>
根本没有任何数据Dom可以操作,不能为了静态化让前端再开发一个模板首页(我可能会被前端妹子打),后端再去定期渲染持久化。这好像又回到了前后端糅杂的时代,前端写模板,后端渲染。
接口缓存
也就是说不要每次请求都去请求外部接口,而是缓存起来,不管KV还是文件,这种看起来是最简单的,前端也不需要修改。 然而我却选择了下一种↓↓↓
JS缓存
后台会生成一个JS文件,周期性去更新。里面存储了需要的数据,类似长下面这样:
var ResData = [item, item, item...]
前端在首页HEAD直接引用JS:
<script src=/static/js/front_data.js></script>
然后前端处理流程大概长这样:
var data = []
//如果拉不到JS或者内容为空的话,再去后端拉取列表
if (window.ResData && window.ResData.length > 0) {
data = window.ResData;
} else {
data = fetchDataFromServer();
}
callback(data)
这样做的好处有,其实就两个字:快、稳
- Nginx省去一次和后端server的交互
- 前端不用等页面和JS加载完成后再去后端拉数据,浏览器可并行加载
- 可灵活配置Nginx规则利用浏览器天生的静态文件缓存能力,直接加载本地缓存JS,比如配置Cache-Control:no-cache,nginx配合返回304或200既能保证取到最新数据又兼顾效率 P.S. 对于不按套路出牌的浏览器,可能无效(逃
- 在每天多次的后台API变更过程中,难免出幺蛾子,缓存JS保证了即便变更出问题,首页也能正常使用,心态稳、发布稳、服务稳
当然这和首页静态化一样,额外带来一些问题:
- 更新缓存脚本的管理和维护
- 多台Nginx上缓存文件并不是强一致性的,不过这种列表数据不经常变,同步频率高一些,问题不大
- 更新缓存可能会出问题,需要引入监控机制