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

web优化 #43

Open
lewenweijia opened this issue Oct 22, 2019 · 20 comments
Open

web优化 #43

lewenweijia opened this issue Oct 22, 2019 · 20 comments

Comments

@lewenweijia
Copy link
Owner

lewenweijia commented Oct 22, 2019

https://github.com/berwin/Blog/issues
w3c webperf会员大佬博客
嗨,送你一张Web性能优化地图

问题

如何进行系统性地页面优化

  1. 浏览器多进程架构 | 渲染主线程 | GUI线程和JS线程执行互斥 | 单处理管道的多任务调度策略
    「前端进阶」从多线程到Event Loop全面梳理
    从浏览器多进程到JS单线程,JS运行机制最全面的一次梳理
`一个宏任务(JS线程) > 系列微任务(JS线程) > 渲染(GUI线程)`
单次宏任务以及系列伴随微任务执行完毕, 渲染主线程检查GUI线程, 执行渲染, 出位图操作

俚语

  • 浏览器内核? -> 渲染进程

页面优化

浅谈script标签中的async和defer

脚本并不关心页面的DOM元素(文档是否加载完毕), 并不会产生其他脚本需要的数据?:
async走起, 百度统计

脚本页面依赖页面的DOM元素, 或者被其他脚本依赖, defer走起:
1. 评论框 | 2. 代码语法高粱 | 3. polyfill.js

不确定是defer还是async? -> 那么defer稳妥些!

肯定是要隐身模式的啊, 去除所有浏览器插件的干扰的效果的呢
@lewenweijia
Copy link
Owner Author

lewenweijia commented Oct 22, 2019

优化场景
「前端进阶」高性能渲染十万条数据(时间分片)
对于大量数据渲染的时候,JS运算并不是性能的瓶颈,性能的瓶颈主要在于渲染阶段

raf? -> 系统来决定cb的执行时间
setTimeout的分批渲染, raf的分批渲染

最终?: raf + documentFragment(保存在内存中的啊, 是DOM节点, 但并不是DOM树的一部分) 减少页面
回流

@lewenweijia
Copy link
Owner Author

lewenweijia commented Oct 25, 2019

Event: mousemove/keydown | Timer Fired | Animation Frame Fired

开发网页? 用户体验 | 可访问性 | 安全性 => 跟呼吸一样自然和简单

以用户为中心的性能指标 User-centric Performance Metrics

拆分计算任务, 减少用户输入延迟(键盘/鼠标)

http2多路复用和server push的结合使用(一条流一个资源, 不需要显式请求资源, 服务器主动server push 推送)

一对多的流推送服务, 一个请求多个六推送
schedule to the next IdlePoint (协调调度到下一个空闲点)

http2: 多路复用, 请求优先级, 头部压缩, 服务端推送
h2? 啥都不变, 只是针对数据的传输格式做了重新定义
一方面完美地向下兼容, 对用户完全透明, 只会感觉到性能的提升

关键渲染路径(critical rendering path)
**前置: ** 什么是关键渲染路径:阻塞页面的初始化渲染也就是FP/FCP的咯
控制三个变量的尽可能小化

  • **[ 关键资源 ]数量: ** 个数 =>
  • **[ 关键路径 ]长度: ** 资源之间的顺序依赖长度 , 影响RTT, 前面的跑完才能拉下一个
  • **[ 关键字节 ]大小: **

个数: 减少个数
大小: 压缩大小
长度: 尽可能趁早加载关键资源, 减短路径长度

消除/使其变得不重要 => 压缩/优化, 最小化传输字节

@lewenweijia
Copy link
Owner Author

lewenweijia commented Oct 25, 2019

缓存

避免不必要的缓存开销
versioned url for long-lived caching: 长时间缓存的版本化url的啊

对第三方的tree shaking, 还不如直接cdn化的呢

工程化/性能优化/安全

largish: 稍大的 <-- somewhat large

document.body.childNodes[0].appendChild(component());

浏览器区分资源还是通过url的

window/global/self <==> browser/node.js/serviceWorker
简单地将sw想象成一个中间件就好了的, 中间人, 中间代理

尝试去拉取并安装sw

@lewenweijia
Copy link
Owner Author

事实: 网络能力和设备能力总是不对称的

  1. 好网络差设备
  2. 差网络好设备

对低端网络,传输大小至关重要
对CPU能力差的设备,解析、编译的时间十分重要
==》 应该尽可能减低这两个指标的呢

两个指标:

  1. 网络传输时间
  2. JS的解析、编译、执行占用主线程过多的时间的啊

@lewenweijia
Copy link
Owner Author

lewenweijia commented Oct 28, 2019

保持其价值尽可能降低第三方脚本带来对我们网站的影响,

IntersectionObserver + + dataset
IntersectionObserver + div + background-image

video标签视频加载的延迟?

  1. preload="none"
  2. poster="....png"

video => gif
muted autoplay loop

首屏中的关键img资源直接用标准的img更快的啊

。。。抵制js实现懒加载带来的性能诱惑陷阱

首屏线
首屏线 + 向下适当缓冲区 => IntersectionObserver(cb, { rootMargin:" "})

图片、视频延迟加载? 减少不必要的下载:

  1. 流量
  2. CPU消耗

最大限度压缩所需下载量

压缩
。注释 + 空格移除
文本的数量进行计数压缩

基于文本资源的minified(html、css、js):

  1. gzip =》 针对文本资源压缩友好, 70%. 图片?其他算法处理过了的,gzip微乎其微

  2. minified =》2. gzip ====》 .min.js.zip

minified?: 需要用特定的工具针对特定的资源进行压缩:
1. js,移除注解、空格换行、变量名简化
2. css、移除注解、空格换行、重叠选择器合并
3. html、移除注解、空格换行

@lewenweijia
Copy link
Owner Author

lewenweijia commented Oct 28, 2019

服务器开启gzip,是回报率很高的一项劳作的啊

gzip后,体积反而变得更大?原本就高度压缩的了,内容比gzip所依赖存储压缩信息的成本还高
=》 设置进行gzip的文件最小阈值

tree shaking的好处?:

  1. 减少网络传输大小

  2. 减少js的解析、编译时间。js文件拉下来之后,肯定执行一次的啊(伪main)

  3. 避免不必要的下载

  4. 通过压缩技术优化每个资源的传输编码

  5. 利用缓存完全否定RTT

自有资源和第三方资源:
该资源是否遵循性能的最佳做法?压缩、缓存

第三方资源成为我们的单点故障? =》 也就是该资源不可用的时候,影响我们网页的性能和用户体验

基于文本的资源
[html、css、js]、png

css像素和设备像素的对应关系:
1个css像素刚好对应1个设备像素
1个css像素对应多个设备像素

设备像素越丰富,展示的效果越细腻

  1. 矢量图片
  2. 光栅图片

如果使用光栅图片,那么设置srcset、picture =》 提供图片的多个变体

svg?也是基于文本的资源的啊,也应该剔除注释、元信息、minified、gzipped

浏览器为光栅图片(不管什么格式)的每个像素始终占据4个字节的内存(rgba四通道信息)
500 × 500的像素的光栅图片 =》 1m左右

图片的格式选择:

  1. 通用格式:png(细节控)、jpeg(能显示就行)
  2. 现代客户端?:webp

三个能力:动画、透明度、浏览器支持度
webp支持动画、也支持透明度,和gif相差只有浏览器的支持程度了

多数cdn都会提供自动化图片优化服务

图片仍然是网络暴涨的原因

嘿嘿嘿, 图片优化是个精细活啊。。。
webp也是google家发明的啊

link下进行preconnect一个cdn站点,tcp消耗,tls消耗

webpack的js代码优化?
1. 减少重复代码 -》optimizaiton.splitChunks.cacheGroups => 不断的抽取公共代码
2. 动态导入


webpack的optimization里面配置
1. 压缩器:minimizer[ new TerserPlugin({}) ]
2. 公共模块抽取设置:splitChunks.cacheGroups

嘿嘿,都是通过白名单的形式的啊


@lewenweijia
Copy link
Owner Author

预提取和预加载
prefetch: 低优先级,浏览器空闲时,类RIC
preload: 高优先级,不阻塞load时间情况下进行记载, 类raf

预提取总是地风险的, 不会浪费用户流量

预提取/预加载技术:
dns-prefetch: renderer项目中大量使用
prefetch: 低优先级, 浏览器空闲
preload: 高优先级, 不堵塞load事件, 真正获取的时候网络进程直接走cache通道

@lewenweijia
Copy link
Owner Author

webpack的optimization.splitChunks下的智能代码分割

@lewenweijia
Copy link
Owner Author

lewenweijia commented Oct 29, 2019

最后来个资源提示的效果的
dns-prefetch
preconnect
prefetch
preload
性能优化?:
1. 资源加载优化
2. 渲染优化

@lewenweijia
Copy link
Owner Author

页面具有高可交互性,并且运行顺滑:
用户输入(键盘、鼠标、touch滚动)
动画

滚动应该像手指的滑动一样快

高性能网站和应用?

  1. 理解浏览器是如何处理HTML、CSS、JS,并确保代码(包括第三方代码)尽可能高效地进行运行
下面因素需要保持一致以获取最大的页面流畅度:
浏览器渲染动画和页面的速率 《===》 设备屏幕的刷新率 

@lewenweijia
Copy link
Owner Author

来来来,研究下为啥会出现卡顿感。。。(我只是分享我的发现和总结)
页面卡顿感?:
浏览器的渲染(出图)速率跟不上设备屏幕刷新率

卡顿、===》 用户体验

我们在意的是用户体验的效果的啊

如果处于交互状态,完全是js领导化的啊

布局、绘制、合成

渲染优化?这项工作是要浏览器配合的呢

sticky scrolling, 粘黏滚动 => 页面滚动跟手指滑动一样的快的效果的啊
闪烁更新,flickering update

布局和绘制是可选的啊,在渲染流水线(rendering pipeline)里面
layout property: 不改变元素的几何属性, 就不走layout步骤的啊
=> 几何属性? width/height/position(top, left)信息, 宽/高/位置

最后的最后再走合成路线, 将他们合并回来

paint-only属性举例: background-image, text color, shadow, background-color

这个页面有几个图层的呢, 需要通过compositor进行合并页面的啊
页面由图层进行组成的

渲染流水线的第一个阶段: 可以引起视觉变化的统一(js、css改变、webanimation api)

渲染流水线,除了第一阶段和最后一阶段,其他的都是可选的啊

文本资源?
1. minified
2. comrpess
3. acahe

关键渲染路径?:浏览器获取资源到将它们渲染成页面的整个流程

@lewenweijia
Copy link
Owner Author

BIG DEAL

关键渲染路径
渲染流水线

资源优化

1. 移除不必要的代码
2. minify
3. compress
4. cache
``
1. 页面获取
2. 子资源获取

浏览器会干的事情,也是开发者预定好的那些事情的效果的啊

增量形式的HTML分发, incrementally HTML delivery

let's go to timeline and record

练习?探索时间线轨迹

grep location *, 命令行文件扩展符

@lewenweijia
Copy link
Owner Author

一帧结束的标识:像素被绘制到屏幕就好了的啊

js当然需要在一帧的开头进行尽可能早的执行:

  1. 因为js会触发style, layout, paint, composite一系列过程的啊

raf?make js code run at the right point of every frame`

raf?很棒的工具来进行动画的制作

浏览器是如何渲染一帧的:渲染流水线

在16ms的时间预算下, 任务可能会超时,浏览器自身也有一些内部任务
browser has housekeeping to do

@lewenweijia
Copy link
Owner Author

16ms? 浏览器每一帧也有内部工作要做,所以6ms给浏览器作为时间预算,那么我们就只有10ms了的啊

js代码在占据渲染流水线的时间,至多3/4的啊

样式计算
布局计算
绘制
合成(图层管理)

@lewenweijia
Copy link
Owner Author

js问啥要在渲染流水线的最前面?因为js会导致后面的任何一个渲染流水线子阶段重新执行的啊
可能导致很多工作redone
同时,也尽可能让js有更多的时间进行执行
。。。jQuery still use setTimeout for animation today

setTimeout的问题,v8引擎对对啥时候出图是没有感知的,傻傻的等timeout
raf,浏览器每次出帧的时候, 会自动去拿里面的东西

为什么React是RIC?
让更高优先级的用户输入和动画,可以流畅执行。而React的reconcilation任务属于CPU密集性,不属于高优先级任务,可以延缓

@lewenweijia
Copy link
Owner Author

function animate() {
  // Do something super rad here

  requestAnimationFrame(animate);
}

requestAnimationFrame(animate)

@lewenweijia
Copy link
Owner Author

lewenweijia commented Oct 29, 2019

raf, 最低版本IE9, setTimeout来作为polyfill的效果的啊。并不是一个理想的fallback,但是可以工作的啊

可怕的可怕的啊,JS的代码都跑在帧里面的正确时间的啊

need to fill all the work inside 16ms

need to fill all the work inside 16ms =》 js => style => layout => paint => composite
10-12ms的时间来跑js代码的情况的啊。。style => ... => composite这一段可以认为对开发者完全是
不透明的,是浏览器的housekeeping。浏览器提供两个逃生舱让我们可以参与渲染流水线的协调中来
分别是raf和ric的啊
raf:js代码可以

js代码很容易在一帧里面超出一开始的时间预算

framework/library? => they has their work to do ,而不是单单你写的那些代码了的啊。哈哈

timeline?
告诉js执行时间,哪个函数,在哪里

@lewenweijia
Copy link
Owner Author

lewenweijia commented Oct 29, 2019

and interact with the site

long-running JavaScript

通过Performance来查找长时间运行的JS代码的啊
这里我们会多出许多额外的信息,来帮助我们进行调研查找
find bottleneck more easily

sort fn? actually the built-in one is great!

Performance下的各种形式的火焰图的效果和形式的啊。flame view

主线程和worker线程互不干扰, 但是可以相互通信

main: consumeData(result) postMessage(params)
worker: dowork(data) postMessage(result)

web worker对跑长时间js的任务来说, 无限价值的形式的啊。

spawn出一个新的ww线程

@lewenweijia
Copy link
Owner Author

lewenweijia commented Nov 1, 2019

284aec5bb7f16b3ef4e7482110c5ddbb_articlex


2151798436-59da4801c6772_articlex

@lewenweijia
Copy link
Owner Author

async,乱序。不依赖其他脚本 + 不操作DOM

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