1. 页面性能优化
- 减少 http 请求: 资源 压缩 Gzip、合并,图片精灵。
- Apache: Use mod_deflate
- Nginx: Use HttpGzipModule
- IIS: Configure HTTP Compression.aspx>)
- 非核心代码异步加载 --> 异步加载方式 --> 异步加载的区别,使用 defer async 比放到页面底部更 modern、更好
- 利用浏览器缓存 --> 缓存分类 --> 缓存原理
- 使用 CDN
DNS 预解析:
<meta http-equiv="x-dns-prefetch-control" content="on"> <link rel="dns-prefetch" href="//url.com">
https 协议下 a 标签默认浏览器是关闭 dns 预解析。上面 meta 告诉浏览器强制打开对 a 标签的 dns 预解析。
图片优化,大小、格式。图片预加载,将样式表放在顶部,将脚本放在底部
- 页面静态化
- 减小 cookie 大小
- 用 innerHTML 代替 DOM 操作,减少 DOM 操作次数
- 当需要设置的样式很多时设置 className 而不是直接操作 style
- 少用全局变量、缓存 DOM 节点查找的结果。减少 IO 读取操作。
- 避免在页面的主体布局中使用 table,table 要等其中的内容完全下载之后才会显示出来,显示比 div+css 布局慢。
- 避免多次重定向
对普通的网站有一个统一的思路,就是尽量向前端优化、减少数据库操作、减少磁盘 IO。向前端优化指的是,在不影响功能和体验的情况下,能在浏览器执行的不要在服务端执行,能在缓存服务器上直接返回的不要到应用服务器,程序能直接取得的结果不要到外部取得,本机内能取得的数据不要到远程取,内存能取到的不要到磁盘取,缓存中有的不要去数据库查询。减少数据库操作指减少更新次数、缓存结果减少查询次数、将数据库执行的操作尽可能的让你的程序完成(例如 join 查询),减少磁盘 IO 指尽量不使用文件系统作为缓存、减少读写文件次数等。
1.1. 异步加载方式
- 动态脚本加载。
document.createElement('script')
加载到 body, head 中 - defer
- async
1.1.1. 异步加载的区别
- defer 不阻止 文档解析,浏览器遇到 defer 边下载 defer script 边往下解析。全解析完之后才执行 defer script。如果多个依次执行。
- async 不阻止 文档解析,浏览器遇到 async 边下载 async script 边往下解析。当下载好了 js 后立即执行,此时文档解析可能还没完成,执行 js 期间停止文档解析。如果多个 async script,执行顺序与加载顺序无关
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>性能优化</title>
<!-- <script src="./defer1.js" charset="utf-8" defer></script>
<script src="./defer2.js" charset="utf-8" defer></script> -->
<script src="./async1.js" charset="utf-8" async></script>
<script src="./async2.js" charset="utf-8" async></script>
</head>
<body>
<div class="">
test
<script type="text/javascript">
console.log('write');
document.write('<span>write</span>');
</script>
<script type="text/javascript">
for (var i = 0; i < 200000; i++) {
if (i % 20000 === 0) {
console.log(i);
}
}
</script>
</div>
</body>
</html>
结果都是 write,for 循环数字,最后是 defer 或者 async 执行。区别 defer 按照加载顺序执行, async 不一定,看文件大小、加载时间。
1.2. 浏览器缓存
强缓存:不跟服务器对话,本地有拿来就用
Expires Expires: Thu 绝对时间 Cache-Control max-age:3600s 相对时间(以他为准,避免服务器和本地电脑时间不一致)
协商缓存: 问服务器磁盘上的缓存能不能用
Last-Modified If-Modified-Since 他俩值一样。服务器下发 Last-Modified, 传给服务器If-Modified-Since 因为服务器要对比。 Etag If-None-Match Etag 判断文件内容是否变化
跟缓存的 http 头有哪些?Expires, Cache-Control, Last-Modified, If-Modified-Since, Etag
1.2.1. 字体优化
首先我们使用字体图标代替图片,这是常规的优化。但自定义图标、字体还需要被下载才能完全显示,没下载完成之前页面不会显示。
FontFaceObserver 原理:当字体图标下载完成后在 body
加上一个 class -- jsFontLoaded
@font-face
定义到 style.css- style.css 里面的
body { font-family: 使用常规的字体 }
。在body.jsFontLoaded { font-family: @font-face }
- in App.js 增加
<fontName>Observer
1.2.2. 响应式图片
- JS 或者服务端硬编码,resize 事件,判断屏幕大小加载不同的图片
- img srcset 方法
- picture 标签 -> source
- svg
- 第三方库 polyfill
1.2.3. 图片优化
图片优化:以前切图,现在某些效果可以用使用 css3。字体图标替换
图片分类:jpg 小,png 大透明,gif,svg 地图,apng,webp
webpack image-loader: 自动对图片进行压缩优化等处理
css sprite:制作网站 GoPng http://alloyteam.github.io/gopng
概念:将多个小图片拼接到一个图片中。通过 background-position 和 元素尺寸 调节需要显示的背景图案。
优点:
- 减少 HTTP 请求数,极大地提高页面加载速度
- 增加图片信息重复度,提高压缩比,减少图片大小
- 更换风格方便,绿色、红色的样字一样的图标可以通过 background-position 改变
缺点:
- 图片合并麻烦
- 维护麻烦,修改一个图片可能需要重新布局整个图片
注意手机端一般像素是 pc 端一半,gopng 生成的像素是 pc 端的
- fis3
- grunt-sprite
响应式动态图片加载 sdk
- 需要默认图片
- 分辨率信息告诉服务器
- 服务器返回优质图片
picture 标签:
<picture>
<source srcset="smaller.png" media="(max-width:768px)"></source>
<source srcset="bigger.png" media="(min-width:1000px)"></source>
<img srcset="default.png" alt="default img">
</picture>
1.2.4. 视频
- video 标签,不同浏览器默认样式不同
- flash 播放器,过时
需求
- 按照设计师要求制作播放器
- 用户进来就能看
第三方
- videojs
- flowplayer
视频优化点
提前加载视频资源、依赖。flowplayer 支持 html5 和 swf。如果使用 flash,即使 swf 文件写在图片前面,默认浏览器还是会最后加载 swf 这样的多媒体资源。这导致图片阻塞了视频加载。优化点就是如何才能让视频依赖前置。方法是使用样式 link
<link rel="stylesheet" href="flowplayer-3.2.18.swf">
<link rel="stylesheet" href="flowpalyer.controls.swf">
<link rel="stylesheet" href="video.mp4">
<script src=".../flowplayer.min.js"></script>
<script src="init.js"></script>
此时这些资源立马加载,之后这些资源从浏览器缓存中取出来很快。
1.3. 性能优化工具
- YSlow
- Google PageSpeed
- pingdom
- jsPerf
- dromaeo
- 微软压力测试工具,模拟每秒轰炸
- chrome 自带 performance 监控
1.3.1. 前端需要注意哪些 SEO (重要)
- 合理的 title、description、keywords:搜索对着三项的权重逐个减小,title 值强调重点即可,重要关键词出现不要超过 2 次,而且要靠前,不同页面 title 要有所不同;description 把页面内容高度概括,长度合适,不可过分堆砌关键词,不同页面 description 有所不同;keywords 列举出重要关键词即可
- 语义化的 HTML 代码,符合 W3C 规范:语义化代码让搜索引擎容易理解网页
- 重要内容 HTML 代码放在最前:搜索引擎抓取 HTML 顺序是从上到下,有的搜索引擎对抓取长度有限制,保证重要内容一定会被抓取
- 重要内容不要用 js 输出:爬虫不会执行 js 获取内容
- 少用 iframe:搜索引擎不会抓取 iframe 中的内容
- 非装饰性图片必须加 alt
- 提高网站速度:网站速度是搜索引擎排序的一个重要指标
1.4. SPA 如何处理 SEO
因为搜索引擎无法通过 js 抓取信息,所以 SPA 的 SEO 需要格外处理。
You can setup a headless browser like PhantomJS
to run on your server. It will execute all the javascript on your page. Then you can send that result to Google. This will fix your problem, but someone has to manage the server for PhantomJS. Opening and processing all these webpages is slow. It might take several servers. Phantom isn't as stable as you'd hoped.
- react server render 首次生成 html 返回给浏览器。
ReactDOMServer.renderToString
- 没人没时间,则用 PhantomJS 搞预渲染。
- 连这个都没时间弄的话,去接入 prerender 等预渲染服务。