前言
这篇文章是《高性能网站建设指南——前端工程师技能精髓》的读书笔记,即,雅虎14条军规扩展版。个人认为书名副标题取名并不精确,前端工程师优化技能精髓似乎更适合,本文粗线条地记录了我觉得应该记录下来的知识点。个人备忘录,不具备连贯性,看不懂就对了。
通识
性能黄金法则
最终用户只有10%~20%的响应时间花在了下载HTML文档上,其余的80%~90%时间花在了下载页面中的所有组件上。
注:该统计出于大概十年前,现在比例应该有所变化,但还是有很大的优化空间
HTTP备忘点
压缩
Request:Accept-Encoding: gzip,deflate
Response:Content-Encoding: gzip
条件Get请求
Request:If-Modified-Since: Wed, 22 Feb 2016 09:23:44 GMT
Response:Last-Modified: Wed, 22 Feb 2016 09:23:44 GMT
Expires
Response:Expires: Wed, 22 Feb 2016 09:23:44 GMT
Keep-Alive
Request:Connection: keep-alive
Response:Connection: keep-alive
14军规
减少HTTP请求 Make Fewer HTTP Request
- 图片地图
- CSS Sprites
很多人认为合并后的图片会比分离的图片综合要大,因为合并后包含附加的空白区域。实际上恰恰相反,因为它降低了图片自身的开销(颜色表,格式信息,等等) - 内联图片
data:[<mediatype>][;base64],<data>
- 合并脚本和样式表
使用内容发布网络(CDN)
- 缺点:修改HTTP响应头必须通过第三方完成。
添加Expires头
- 可以同时制定两个响应头:Expires和Cache-Control的max-age。如果两者同时出现,HTTP规范规定max-age指令将重写Expires头,例如:
Expires: Mon,15 Apr 2024 20:00:00 GMT
Cache-Control: max-age=312
开启Gzip压缩
- 注意点:代理缓存
- 在Web服务器相应中添加
Vary
头,这样就可以告诉代理根据一个或多个请求头来改变缓存的响应。Vary: Accept-Encoding
代理缓存响应的多个版本,当有gzip头的请求时,响应压缩过的,反之是未经压缩的。 - 禁用缓存:
Vary: *
或Cache-Control: private
将样式表放在顶部
- 样式表放在底部对加载页面所需的实际时间并没有太大影响,但会导致浏览器阻止内容逐步呈现,这让用户感性上觉得页面加载更慢。
- 无样式内容的闪烁FOUC(Flash of Unstyled Content)是浏览器行为,在样式表正确地下载并解析后,已经呈现的文字和图片要用新的样式重绘了。浏览器可以延迟呈现,知道所有样式表下载完毕,这导致了白屏,反之可以逐步呈现,但要承担闪烁的风险,这里没有完美的选择。
将脚本放在底部
- 放在顶部的影响:
- 会阻塞对其后面内容的呈现
- 会阻塞对其后面资源的下载
defer
属性表明脚本不包含document.write
,浏览器有这个线索可以继续呈现。
避免CSS表达式
- 谁会想到用户点击了一个文本框会导致IE锁死呢。
- 避免方式:创建一次性表达式和使用事件处理器取代CSS表达式 12345678910<style>p{background: expression( altBg(this));}</style><script>function altBg(ele){ele.style.backgroundColor=(new Date()).getHours()%2 ? "#f08":"B98"}</script>
使用外部javascript和css
- 页面浏览量越少,内联论据越强势,反之外置论据越强势。
减少DNS查找
- 将静态资源放在独立域名下较好,但不要超过四个,在减少DNS查找和允许并行下载之间做出权衡。
精简javascript和CSS
- gzip压缩产生的影响更大,但精简能够进一步减小文件大小。
避免重定向
- 当服务器向浏览器返回一个重定向时,是指一个范围在3XX的状态码,表示用户代理必须执行进一步操作才能完成请求。
- 300 Multiple Choices
- 302 Moved Permancently
- 302 Moved Temporarily
- 303 See other
- 304 Not Modified (并非重定向,用来响应条件GET请求)
- 305 Use Proxy
- 306 不再使用
- 307 Temporary Redirect
301
和302
是使用最多的,303
和307
是HTTP 1.1添加的,用来澄清对302的使用,但现实情况是几乎没人采用。- 还有其他方式:
- HTML META :
<meta http-equiv="refresh" content="0; url=http://google.com">
- HTML META :
删除重复脚本
- 确保脚本只被包含一次,否则会带来性能损伤。
配置ETag
- ETag是唯一标识一个静态资源特定版本的字符串。
- If-None-Match比If-Modified-Since具有更高的优先级
- ETag可能会引发性能问题,这时候完全可以移除ETag
使AJAX可缓存
- 当数据被认为是私有的时候,大多会使用
Cache-Control: no-store
。这样的响应根本不会被写入磁盘。 - 确保AJAX请求遵守性能优化原则,尤其应具有长久的Expires头
读后感
虽然知识点比较基础,但并不过时,读后我立即在自己博客上实践了下:
- 图片使用七牛CDN,感谢hexo-qiniu-sync,访问速度明显加快。
- 删掉和替换掉了一些鸡肋功能,比如NexT主题自带的浏览图片插件,换成了自己的简洁实现。
- 本来想搞一下HTTP配置,由于本站HOST在Github上,无从下手,好在Github在HTTP优化原则上已经做得很好了,省心省力。
除了HTML/CSS/JavaScript(这三样已经够折腾的了),一个优秀的前端工程师还应该具备什么样的技能呢?从这本书可以得到点启发:
- 理解HTTP协议[《HTTP权威指南》足矣]
- 了解浏览器工作原理及不同浏览器间的差异
- 掌握服务器端编程[可以从Node入手]
- 了解网络环境配置[可以学学Nginx]