67

【原创】原来你竟然是这样的Chrome?!Firefox笑而不语 - 三生石上(FineUI控件)

 4 years ago
source link: https://www.cnblogs.com/sanshi/p/11247741.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

【原创】原来你竟然是这样的Chrome?!Firefox笑而不语

上一篇文章《【原创】用事实说话,Firefox 的性能是 Chrome 的 2 倍,Edge 的 4 倍,IE11 的 6 倍!》,我们对比了不同浏览器下FineUIPro一个页面的性能,发现Firefox的加载速度最快,而众望所归的Chrome却表现的差强人意,加载速度仅仅是Firefox的一半!

最近我们重新对测试和代码进行了优化和整理,有如下三个发现:

1. 测试代码将开始时间放在<head>标签的做法有失偏颇,如下所示:

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <script>
        var __STARTTIME = new Date();
    </script>
</head>

这会导致所计算的时间包含HTML页面,CSS文件和JavaScript文件的网络传输时间,实际上这部分是我们测试案例所不关心的,我们仅关心页面的渲染速度!

因此,优化后的代码将开始时间放到页面底部,如下所示:

</form>
    <script>
        // 等所有JS资源下载完毕后开始
        var __STARTTIME = new Date();

        // 表格渲染完毕后结束
        function onGridRender() {
            F.ui.Grid1.setTitle('表格(23列,500行,行高不同) - 渲染:' + ((new Date() - __STARTTIME) / 1000).toFixed(2));
        }

    </script>
</body>
</html>

2. 前面一篇文章《【原创】这一次,Chrome表现和IE11一样令人失望,围观群众有:Edge,Firefox,我们发现Chrome解析如下结构时遇到问题:

2.1 页面结构如下:

<td class="f-grid-cell">
    <div class="f-grid-cell-inner">杨婷婷</div>
</td>

2.2 页面样式包含:

.f-grid-cell {
    overflow: hidden;
}
.f-grid-cell-inner {
    position: relative;
}

这样的 CSS 设置会导致滚动时页面出现白屏,并且CPU占用率飙升。

不仅如此,在去除 td 的 overflow:hidden 样式后,我们发现 Chrome 下的页面渲染速度也有明显的提升,这一点对接下来的Chrome性能提升也很重要!

3. FineUIPro 代码中有强制 Chrome 重绘的浏览器特定代码,这也是对 Chrome 之前版本存在滚动条不显示的应急策略:

function forceChromeRepaint(targetNode) {
    //:: Chrome的BUG(Firefox,IE都没有此问题)
    //:: http://stackoverflow.com/questions/4394350/chrome-scrollbars-not-disappearing-when-content-is-smaller-than-container?rq=1
    if(F._fjs_isChrome) {
        var overflow = targetNode.css('overflow');
        if(overflow === 'auto' && targetNode._fjs_scrollLeft() == 0 && targetNode._fjs_scrollTop() == 0) {
            targetNode.css('overflow', 'hidden');
            //:: 强制浏览器重新绘制
            targetNode[0].scrollWidth;
            targetNode.css('overflow', 'auto');
        }
    }
}

在最新版的Chrome下测试,相应的浏览器滚动条不显示问题已经得到了修正,所以可以把相关的强制重绘代码去掉了(之前出问题的好像是Chrome v58前后的一些版本,现在Chrome都升级到75了)。这也进一步提升了页面的渲染速度。

经过上面三方面的改进,我们再来看下不同浏览器下的页面渲染性能的对比数据。

优化后的对比数据

和第一篇文章的测试类似,我们将表格行增加到 500 多行,列增加到 20 多列,并且行高不固定,来测试下各个浏览器的性能。

测试使用的电脑是 MacBook Pro 笔记本(英特尔 i7-8750H,32GB内存,512GB SSD),单独拆分出一个新的 256GB 分区用来安装 Windows 10 Pro(64位)系统,并更新至最新补丁。

参与测试的浏览器都是最新版,分别为:

  • Chrome 75
  • Firefox 68 
  • Edge 44

由于 IE11 有明显的卡顿,进行本测试意义不大,所以这次不再对 IE11 进行测试。

下面是测试结果(第一张是 FineUIPro v5.5.0 的截图,第二张是代码优化后的截图):

Firefox:

48817-20190727143448754-823974934.png

 

48817-20190727143518132-2140450284.png

Chrome:

48817-20190727143550906-1031984934.png
48817-20190727143614892-130131739.png

Edge:

48817-20190727144842906-911893127.png
48817-20190727144905475-275464727.png

下面对上述结果进行一个综述:

1. 每次页面刷新结果都有一定的差异,这个取的是多次运行的中间值。

2. 优化后的结果需要等FineUIPro v5.6.0 发布后自行到官网示例测试,目前没有在线测试链接。

可以看到,经过代码优化后,Chrome的性能有明显的提升,但即使如此,Firefox还是比Chrome有性能优势,只不过不再那么辣眼睛了。

发现新问题

看似一个问题的结束,却是另一个问题的开始,还记得上一篇文章中我们提到 Chrome 下选中卡顿的问题吗?

即使在上述数据优化之后,Chrome的渲染性能有明显提升的情况下(从1.85s提升到1.08s之后),Chrome下的行选中依然有明显的卡顿现象,对比下几个浏览器下的动图:

Chrome:

48817-20190727144334285-977737415.gif

Firefox:

48817-20190727144405069-1273125250.gif

Edge:

48817-20190727144424712-2102420221.gif

Chrome你这是要闹哪样?即使页面渲染慢得多的Edge都没有卡顿,选中行时非常丝滑,而Chrome就像被卡着脖子一样,每次点击都有差不多0.5秒的延迟!

真不省心,真不省心.....

这个问题的解决可以说是费尽周折,因为已经明确知道是Chrome浏览器的BUG,而Firefox和Edge都正常,所以根本不能按照常规思路去解释。

后来,一个偶尔的机会,发现去掉第一列(包含复选框的那一列),问题神奇般的消失了,所以我一度怀疑是复选框的样式问题,来看一下。
复选框的HTML结构很简单:

<i class="f-icon f-iconfont f-grid-checkbox f-checkbox"></i>

CSS代码:

.f-checkbox {
    position: relative;
    top: 0;
    left: 0;
    display: inline-block;
    width: 14px;
    height: 14px;
    min-width: 14px;
    margin: 3px 1px;
    border-width: 1px;
    border-style: solid;
    border-radius: 2px;
}
.f-checkbox:after {
    display: table;
    position: absolute;
    left: 4px;
    top: 1px;
    width: 5px;
    height: 8px;
    border-width: 2px;
    border-style: solid;
    border-color: #fff;
    border-top: 0;
    border-left: 0;
    content: " ";
    -webkit-transform: rotate(45deg) scale(0);
    transform: rotate(45deg) scale(0);
    opacity: 0;
    filter: alpha(opacity=0);
}
.f-checkbox.f-checked {
    background-color: #007465;
    border-color: #007465;
}
.f-checkbox.f-checked:after {
    width: 5px;
    height: 8px;
    left: 4px;
    top: 1px;
    -webkit-transform: rotate(45deg) scale(1);
    transform: rotate(45deg) scale(1);
    opacity: 1;
    filter: alpha(opacity=100);
}

这段CSS代码我看了很久很久,实在找不到可以优化的地方,因为这个做法也是业内所公认的,通过将 f-checkbox:after 的 L 型边框旋转 45 度来实现对勾的效果。

接下来,神奇的事情发生了,一个偶然的机会,我会外层的 .f-grid-cell-inner 的 position: relative 去掉,所有的卡顿不见了,一切都像Firefox一样丝滑:

48817-20190727180305119-1290466864.png

现在来看下去掉这个 CSS 属性之后,行选中的效果,丝滑的就像Firefox一样:

48817-20190727181005557-489940486.gif

问题解决了,是不是很高兴?

可惜一点都高兴不起来,首先不知道这个 td -> div 的 position:relative 挨着谁的事了,这么不受 Chrome 的待见。

其次这个属性虽然FineUIPro没有大用处,还是有一点用处的,比如这里:

48817-20190727181327968-716185552.png

所以遇到这种情况,就先加个例外好了。

不管怎么说,也算是暂时画上一个句号,看Chrome哪个版本能修正类似的问题?

不忘初心,砥砺前行!


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK