网页(html)的运行载体是浏览器,浏览器解释渲染代码html应用,所以提到「性能」这个关键字大概率是在说浏览器解释渲染并响应html应用的速度

基本概念

浏览器在载入html文档后开始渲染到窗口,而代码中的所有内容就是在指明告诉浏览器怎样去渲染,比如一个button就代表它要展示出一个按钮。
相应的javascript代码也是在指明怎么去调整页面展示效果,比如一个click就代表浏览器要在那个按钮按下的时候额外做一些什么动作。它的基本过程是:

//顺序1
1. 按下
2. 浏览器渲染按下的效果
3. 监听到额外的按下事件
4. 执行额外事件并响应

默认行为

上面看到简单分4步走,其中第2步指的就是obj的默认行為。比如button按下要显示按钮阴影、checkbox按下要显示对勾、Scroll滚动要更新展示文档的下一部分。。。
这个浏览器行为是在我们自定义的代码之前会被响应的,他是浏览器基本的渲染功能中定义的。

JS的preventDefault

上面说过html与js都会被浏览器读取响应以更新渲染行为,但是在js中有声明了一个preventDefault方法,js的声明是它可以阻断obj的默认行为。

而当大量用户需要使用这个标记的时候,浏览器厂商也只能去实现它。

是的,其实js中有部分不被常用的标记声明并没有被浏览器实现,所以大家看文档手册会在每一个声明中找到市面上各大浏览器是否支持此标记,就是常说的兼容性

浏览器的实现

preventDefault()代表了在代码中任意一个位置都可能会阻断默认行为,那浏览器总不能让页面连续闪动,比如按下checkbox页面上显示对勾然后又消失对勾,这种体验会让浏览器丧失市场。

他们选择的方式是等待执行,就是把默认行为的执行顺序放到末尾:

//顺序2
1. 按下
2. 监听到额外的按下事件
3. 执行额外事件并响应
4. 浏览器渲染按下的效果

这种顺序保证了渲染效果的确定性,但缺点也很明显,就是浏览器要阻断渲染线程的运行来等待,当大量等待出现的时候页面效果会卡住不动,这种体验又会造成困扰。

passive的作用

终于引出主题了,为了出现这种尴尬,js也有声明一个passive属性。它的含义是指明在自定事件中是否需要obj的默认行为,其实就是告诉浏览器是不是要用preventDefault方法。

当true的时候浏览器就知道这段代码是可以走 顺序1 的,这时不需要等待代码,渲染效率更高,当false的时候浏览器就知道这段代码不需要ojb的默认行为,这时需要等待代码执行再渲染页面。

它的作用就是这样去影响性能的,但大家平时去写事件是很少用到的,因为浏览器公司像google、firefox人家也会对用户行为进行数据分析,对每一种obj的使用都有结果分析,所以在没有明确使用这个声明属性时,浏览器会有自己的默认值来响应。

常见情况,为了保证页面的展示效果,在触摸设备上有时会限制死页面大小比例且不允许用户自由缩放。

这可以简单的监听触摸移动(两指分开放大屏幕)然后使用preventDefault阻断默认行为。这时若不明确声明 passive=false ,浏览器会用默认的值 true 来走渲染 顺序1 ,用户会仍然可以放大缩小屏幕。

最后

当然,不同浏览器对每个obj的passive默认值或许都不一样,现代化的浏览器已经有一套成熟的规则且大差不差,所以兼容性也没什么太大误差。说起兼容性,要放10多年前一个 IE就够瞧的了,那时很多声明微软IE部都没实现。。。这就说远了

总之通过这个属性清楚了浏览器的渲染逻辑,以后再遇到奇形怪状的bug,可以换个浏览器或去手册中翻下是否这个公司实现了该声明。

By 雪峰

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注