Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

性能 #8

Open
AngusLius opened this issue May 30, 2018 · 0 comments
Open

性能 #8

AngusLius opened this issue May 30, 2018 · 0 comments

Comments

@AngusLius
Copy link
Owner

AngusLius commented May 30, 2018

框架层面

SSR:Server Side Rendering

react-server: React服务端渲染框架
next.js: 轻量级的同构框架
beidou: 阿里自己的同构框架,基于eggjs, 定位是企业级同构框架

前后端渲染

后端:浏览器会直接接收到经过服务器计算之后的呈现给用户的最终的HTML字符串
好处:前端耗时少,利于SEO;首屏性能;

webpack

一、loader

url-loader

url-loader可以把文件的内容经过 base64 编码后注入到 JavaScript 或者 CSS 中去。
一般利用 url-loader 把网页需要用到的小图片资源注入到代码中去,以减少加载次数。因为在 HTTP/1 协议中,每加载一个资源都需要建立一次 HTTP 链接, 为了一个很小的图片而新建一次 HTTP 连接是不划算的
其他:插件压缩图片、雪碧图

raw-loader

raw-loader 可以把文本文件的内容读取出来,注入到 JavaScript 或 CSS 中去,例:svg

压缩(GZIP、UglifyJS)

GZIP:为了提升网页加速速度和减少网络传输流量,可以对这些资源进行压缩。 压缩的方法除了可以通过 GZIP 算法对文件压缩外,还可以对文本本身进行压缩。
UglifyJS:目前最成熟的 JavaScript 代码压缩工具是 UglifyJS , 它会分析 JavaScript 代码语法树,理解代码含义,从而能做到诸如去掉无效代码、去掉日志输出代码、缩短变量名等优化。
cssnano:Css压缩

三、CDN加速

  • 针对 HTML 文件:不开启缓存,把 HTML 放到自己的服务器上,而不是 CDN 服务上,同时关闭自己服务器上的缓存。自己的服务器只提供 HTML 文件和数据接口。
  • 针对静态的 JavaScript、CSS、图片等文件:开启 CDN 和缓存,上传到 CDN 服务上去,同时给每个文件名带上由文件内容算出的 Hash 值, 例如上面的 app_a6976b6d.css 文件。 带上 Hash 值的原因是文件名会随着文件内容而变化,只要文件发生变化其对应的 URL 就会变化,它就会被重新下载,无论缓存时间有多长。
    Webpack构建实现:
    1、静态资源的导入 URL 需要变成指向 CDN 服务的绝对路径的 URL 而不是相对于 HTML 文件的 URL。
    2、静态资源的文件名称需要带上有文件内容算出来的 Hash 值,以防止被缓存。
    3、不同类型的资源放到不同域名的 CDN 服务上去,以防止资源的并行加载被阻塞。
    实现:
    1、output.publicPath 中设置 JavaScript 的地址。
    2、css-loader.publicPath 中设置被 CSS 导入的资源的的地址。
    3、WebPlugin.stylePublicPath 中设置 CSS 文件的地址。

代码分割

1、分离业务代码、公共代码、第三方库(可缓存)
2、按需加载

polyfill.io

去掉构建中静态的 polyfill,换而使用 polyfill.io 这样的动态 polyfill 服务,保证只有在需要时,才会引入 polyfill。
具体的使用方法非常简单,只需要外链一个 js:

<script src="https://cdn.polyfill.io/v2/polyfill.min.js"></script>

placeholder

解决闪屏,提前设置占位元素

四、tree shaking

必须是采用 ES6 模块化语法的, 因为 ES6 模块化语法是静态的(导入导出语句中的路径必须是静态的字符串,而且不能放入其它代码块中),这让 Webpack 可以简单的分析出哪些 export 的被 import 过了。

代码层面

immutable.js

思考:为什么可提供一个不错的性能提升?
https://juejin.im/post/5ac437436fb9a028c97a437c
camsong/blog#3

函数防抖,节流

createDocumentFragment

事件委托

避免使用for...in(它能枚举到原型,所以很慢)

优化循环length

条件判断,计算量大放后面

window.requestAnimationFrame

浏览器通常每秒更新页面 60 次,每一帧的时间就是 16.6ms,为了能让浏览器保持 60帧 的帧率,为了让动画看起来流畅,需要保证帧率达到 60fps,因此每一帧的逻辑需要在 16.6ms 内完成。
我们希望在每一帧刚开始的时候对页面进行更改,目前只有使用 requestAnimationFrame 能够保证这一点。

webworker

使用 Web Worker 来处理复杂的计算

css 、JavaScript加载

大多数人已经知道通常要把 JavaScript 放在文档底部,把 CSS 放在文档顶部。为什么呢?因为 JavaScript 会阻塞页面的解析,而外部样式表会阻塞页面的呈现和 JavaScript 的执行。
CSS 被认为是阻塞渲染的资源,在CSSOM 构建完成之前,页面不会被渲染,放在顶部让样式表能够尽早开始加载。
当在 HTML 文档中遇到 script 标签后控制权将交给 JavaScript,在 JavaScript 下载并执行完成之前,都不会解析 HTML。因此如果将 JavaScript 放在文档顶部,恰好这个时候 JavaScript 脚本加载的特别慢,用户将会等待很长一段时间,这段个时候 HTML 文档还没有解析到 body 部分,页面会是空白的。

另外常常被忽略的事实是:在浏览器没有下载并解析完成使用 link 引入的 CSS 文件之前,JavaScript 是不会执行的,因为 JavaScript 中可能需要读取样式,而此时样式表还没有加载回来,因此浏览器不会执行 JavaScript。可以给 JavaScript 加上 async 标记,表示 JavaScript 的执行不会读取 DOM ,JavaScript 可以不被 CSS 阻塞,可以在空闲时间立刻执行。

综上所述,你更要保证 CSS 文件加载的足够快。

懒加载、延迟加载

可以通过Intersection Observer延迟加载图片、视频、广告脚本、或任何其他资源。
可以先加载低质量或模糊的图片,当图片加载完毕后再使用完整版图片替换它。
延迟加载所有体积较大的组件、字体、JS、视频或Iframe是一个好主意

客户端(浏览器)层面

缓存

浏览器对于请求资源, 拥有一系列成熟的缓存策略. 按照发生的时间顺序分别为存储策略, 过期策略, 协商策略, 其中存储策略在收到响应后应用, 过期策略, 协商策略在发送请求前应用. 流程图如下所示.
54a021d766b64e993d39

1.http header中与缓存有关的key:
2018-06-24 2 43 17

2.缓存协商策略用于重新验证缓存资源是否有效, 有关的key如下:
2018-06-24 2 43 50

面试:为什么缓存有同时存在这些字段,区别?
Last-Modified标注的最后修改只能精确到秒级:
用于标记请求资源的最后一次修改时间, 格式为GMT(格林尼治标准时间). 如可用 new Date().toGMTString()获取当前GMT时间. Last-Modified 是 ETag 的fallback机制, 优先级比 ETag 低, 且只能精确到秒, 因此不太适合短时间内频繁改动的资源.
If-Modified-Since:当资源过期时(使用Cache-Control标识的max-age), 发现资源具有Last-Modified声明, 则再次向web服务器请求时带上头 If-Modified-Since,表示请求时间。 web服务器收到请求后发现有头If-Modified-Since 则与被请求资源的最后修改时间进行比对。
Etag:web服务器响应请求时,告诉浏览器当前资源在服务器的唯一标识(生成规则由服务器决定)。
If-None-Match:当资源过期时(使用Cache-Control标识的max-age),发现资源具有Etage声明, 则再次向web服务器请求时带上头If-None-Match (Etag的值)。 web服务器收到请求后发现有头If-None-Match 则与被请求资源的相应校验串进行比对,

强缓存
from memory cache代表使用内存中的缓存,from disk cache则代表使用的是硬盘中的缓存,浏览器读取缓存的顺序为memory –> disk。在浏览器中,浏览器会在js和图片等文件解析执行后直接存入内存缓存中,那么当刷新页面时只需直接从内存缓存中读取(from memory cache);而css文件则会存入硬盘文件中,所以每次渲染页面都需要从硬盘读取缓存(from disk cache)。

协商缓存
协商缓存就是强制缓存失效后,浏览器携带缓存标识向服务器发起请求,由服务器根据缓存标识决定是否使用缓存的过程

参考链接:

缓存:https://juejin.im/post/58eacff90ce4630058668257
请求头、响应头:https://www.jianshu.com/p/12c8ab7840e9

https://juejin.im/entry/5b30b64c51882574d32496de

@AngusLius AngusLius changed the title 性能优化 性能 Jul 28, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant