金沙国际官网_金沙国际平台登录

因为这个金沙国际官网_金沙国际平台登录网站与很多的大型澳门赌场都有合作,金沙国际官网_金沙国际平台登录尽职尽责,高效执行,保持好奇心,不断学习,追求卓越,点击进入金沙国际官网_金沙国际平台登录马上体验吧,所以现在也正式地开始了营业。

您的位置:金沙国际官网 > web前端 > 记一次淘宝首页奇葩的渲染问题,打造最舒适的

记一次淘宝首页奇葩的渲染问题,打造最舒适的

发布时间:2019-11-06 11:56编辑:web前端浏览(95)

    打造最舒适的 webview 调试环境

    2015/11/11 · CSS · 4 评论

    本文作者: 伯乐在线 - risker 。未经作者许可,禁止转载!
    欢迎加入伯乐在线 专栏作者。

    你在做移动web开发的时候是不是只是在Chrome下开启移动模式,然后就啪啪啪闷头敲代码了?如果你平时只是做做宣传页,Chrome的移动模式可能就能满足你。但是现在越来越多的应用采用Hybrid的开发方式,这样的话就可能在web页面上调用webview注入的函数,那么,这个页面在Chrome上只会报错,因为我们不在webview里,根本没有注入的那些函数。

    以我现在做的项目为例,要在页面里判断在客户端有没有登录,可以这样写:

    JavaScript

    var isLogin = AndroidWebview.hasLogin() ;

    1
    2
    var isLogin = AndroidWebview.hasLogin() ;
     

    结果可想而知,AndroidWebview是客户端在webview里注入的方法,这里当然会报错了。

    图片 1

    记一次淘宝首页奇葩的渲染问题

    2015/11/23 · CSS · 渲染

    原文出处: 淘宝前端团队(FED)- 阎王   

    图片 2

    或许你曾经在 Chrome 浏览器上碰到过这样让人瞠目结舌的问题:

    • hover 触发一个层展示,hover 离开后,这个层还遗留残影
    • 浏览器没有清理一个元素渲染的上一个状态,导致页面多出一个错位的跟该元素一模一样的影子
    • 交互时突然出现一个方形色块,覆盖在元素上
    • 或者还有更奇葩的……

    以上列举到的三个问题,我在维护淘宝首页的时候都遇到过。这些都是浏览器渲染页面时,因为渲染引擎的 bug 导致的问题,不常见,更加难以写 demo 演示,它们只在特定的复杂场景下,程序计算存在误差或者漏洞的时候出现,尤其是涉及到边界判断的时候。

    小tips: zoom和transform:scale的区别

    2015/11/03 · CSS · transform, zoom

    原文出处: 张鑫旭   

    真机测试

    这种情况怎么开发呢?回顾一下以前的两种办法 :

    • 真机 + Chrome inspect :Chrome 版本必须高于 32,其次你的测试机 Android 系统高于 4.4
    JavaScript
    
    1. 先用数据线将 Android
    测试机连接到电脑上。需要打开测试机上面“开发者选项”中的 “USB
    调试”功能。
    
    <table>
    <colgroup>
    <col style="width: 50%" />
    <col style="width: 50%" />
    </colgroup>
    <tbody>
    <tr class="odd">
    <td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
    <div class="crayon-num" data-line="crayon-5b8f631a36a36329472806-1">
    1
    </div>
    <div class="crayon-num crayon-striped-num" data-line="crayon-5b8f631a36a36329472806-2">
    2
    </div>
    </div></td>
    <td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
    <div id="crayon-5b8f631a36a36329472806-1" class="crayon-line">
    1.  先用数据线将 Android 测试机连接到电脑上。需要打开测试机上面“开发者选项”中的 “USB 调试”功能。
    </div>
    <div id="crayon-5b8f631a36a36329472806-2" class="crayon-line crayon-striped-line">
     
    </div>
    </div></td>
    </tr>
    </tbody>
    </table>
    
    1.  在PC的Chrome上打开`Chrome://inspect`即可找到你的设备
    2.  手机进入一个webview页面,即可在Chrome上看到调试台了![](http://jbcdn2.b0.upaiyun.com/2015/11/f93b8bbbac89ea22bac0bf188ba49a612.png)可以看到,第一个记录是手机里的浏览器的;第二个是记录是手机助手里的webview。
    
    • 真机 + weinre : 在你本地创建一个监听服务器,并提供一个JS脚本,需要在需要测试的页面中加载这段 JS,就可以被 Weinre 监听到,在 Inspect 面板中调试你这个页面。
    JavaScript
    
    1. 安装 weinre `npm install -g weinre`
    
    <table>
    <colgroup>
    <col style="width: 50%" />
    <col style="width: 50%" />
    </colgroup>
    <tbody>
    <tr class="odd">
    <td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
    <div class="crayon-num" data-line="crayon-5b8f631a36a3a189287013-1">
    1
    </div>
    <div class="crayon-num crayon-striped-num" data-line="crayon-5b8f631a36a3a189287013-2">
    2
    </div>
    </div></td>
    <td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
    <div id="crayon-5b8f631a36a3a189287013-1" class="crayon-line">
    1.  安装 weinre `npm install -g weinre`
    </div>
    <div id="crayon-5b8f631a36a3a189287013-2" class="crayon-line crayon-striped-line">
     
    </div>
    </div></td>
    </tr>
    </tbody>
    </table>
    
    1.  开启 weinre `weinre --httpPort 8888 --boundHost -all-`
    2.  浏览器打开 `localhost:8888` :
        ![](http://jbcdn2.b0.upaiyun.com/2015/11/28c8edde3d61a0411511d3b1866f06365.png)
    3.  将 “2” 这段脚本加载到调试的页面最后,手机进入页面,然后进入 “1”
        ,就可以看到控制台了
        ![](http://jbcdn2.b0.upaiyun.com/2015/11/665f644e43731ff9db3d341da5c827e14.png)
    

    这两种办法都需要真机测试,你可以想像一下你在开发、调试时的流程:

    1. 写代码
    2. 拿起手机,进入页面
    3. 有BUG,重复1、2
    4. 开发新功能,重复1、2、3

    然后你的手不停地在键盘和手机之间切换,多么痛苦。后来,我遇到了Genymotion

    问题复现

    很难得有机会让我碰到一个可以复现的,我把它记录下来了。如下图所示,hover 到学习模块的边界位置时:

    图片 3

    手动 hover 和模拟 hover 都有一样的问题,没有多想,立马加上了一句话修复了这个问题:

    CSS

    .channel2 .channel-item { transform: translateZ(0); }

    1
    2
    3
    .channel2 .channel-item {
        transform: translateZ(0);
    }

    这个不是直觉,多次遇到这种奇葩问题,我第一想到的便是使用 3D 加速将这个渲染层隔离渲染,80% 以上的概率能够解决问题,而解决问题的关键在于找准加这句代码的 DOM 元素。

    一、IE和Chrome等浏览器与zoom

    还在几年前,zoom还只是IE浏览器自己私有的玩具,但是,现在,除了FireFox浏览器,其他,尤其Chrome和移动端浏览器已经很好支持zoom属性了:

    图片 4

    zoom的字面意思是“变焦”,摄影的时候常用到的一个概念。对于web上的zoom效果,你也可以按照此概念理解。可以改变页面上元素的尺寸,属于真实尺寸。

    在旧的web时代。*zoom: 1可以给IE6/IE7浏览器增加haslayout, 用来清除浮动,修复一些布局上的疑难杂症等。

    其支持的值类型有:

    • 百分比值:zoom:50%,表示缩小到原来的一半。
    • 数值:zoom:0.5,表示缩小到原来的一半。
    • normal关键字:zoom:normal等同于zoom:1.

    注意,虽然Chrome/Safari浏览器支持了zoom属性,但是,其实zoom并不是标准属性。

    Genymotion

    这是一款安卓模拟器,有了它我们可以在电脑上开启一个安卓机。具体使用我就不细说了,很简单请自行搜索。

    这是我在模拟器上安装的手机助手:

    图片 5

    而且使用 Chrome inspect 是直接可以调试模拟器中的webview的:

    图片 6

    这样,我们就可以不用手忙脚乱地写代码、看手机了,一切都在PC上调试。但是我们在模拟器上看到的是线上代码,我们加一个新功能还要发布代码才能看到效果?

    探索 bug

    这个层在我的代码中肯定是不存在的,我们只能用 bug 来形容这个问题。因为元素刚好贴在 .channel2 的边界,猜测应该跟层渲染有关,于是打开了控制台 ESC -> Rendering -> Show layer borders,看到了这个:

    图片 7

    仔细观察,可以看到,这个粉色块在瓦片边界和父元素边界之中,可以断定,这几个瓦片在渲染的时候存在问题。


    这里需要补充下关于瓦片的知识。瓦片,英文里头称之为 tile,它是 webkit/blink 渲染页面时的中间过程,将整个页面分成多个大小一样的瓦片,并发渲染每个瓦片的内容。一个元素开启 3D 硬件加速之后,会变成一个独立的层,这个层的渲染也会被分割成瓦片,可以想象成一个子页面。

    瓦片和瓦片之间的边界计算是处理的难点,因为渲染的内容不能错位。


    其实让我找到问题根本原因的是,rendering 块的颜色,平时在网页上开启 show layer borders 看到的是半透明的绿色块,而这里显示的是粉色块,搜索了下不同色块代表的含义,没找到具体的文档说明,但是找到了 代码:

    JavaScript

    // Missing resize invalidations are in salmon pink. SkColor DebugColors::MissingResizeInvalidations() { return SkColorSetARGB(255, 255, 155, 170); }

    1
    2
    3
    4
    // Missing resize invalidations are in salmon pink.
    SkColor DebugColors::MissingResizeInvalidations() {
      return SkColorSetARGB(255, 255, 155, 170);
    }

    对应的就是这个颜色,“缺失调整验证”,在 chromium 的源码仓库中搜了上面的代码,找到了 具体说明:

    JavaScript

    if (!deflated_content_rect.Contains(canvas_playback_rect)) { if (clear_canvas_with_debug_color) { // Any non-painted areas outside of the content bounds are left in // this color. If this is seen then it means that cc neglected to // rerasterize a tile that used to intersect with the content rect // after the content bounds grew. canvas->save(); canvas->translate(-canvas_bitmap_rect.x(), -canvas_bitmap_rect.y()); canvas->clipRect(gfx::RectToSkRect(content_rect), SkRegion::kDifference_Op); canvas->drawColor(DebugColors::MissingResizeInvalidations(), SkXfermode::kSrc_Mode); canvas->restore(); } }

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    if (!deflated_content_rect.Contains(canvas_playback_rect)) {
      if (clear_canvas_with_debug_color) {
        // Any non-painted areas outside of the content bounds are left in
        // this color.  If this is seen then it means that cc neglected to
        // rerasterize a tile that used to intersect with the content rect
        // after the content bounds grew.
        canvas->save();
        canvas->translate(-canvas_bitmap_rect.x(), -canvas_bitmap_rect.y());
        canvas->clipRect(gfx::RectToSkRect(content_rect),
                         SkRegion::kDifference_Op);
        canvas->drawColor(DebugColors::MissingResizeInvalidations(),
                          SkXfermode::kSrc_Mode);
        canvas->restore();
      }
    }

    这里能看的肯定就是注释啦,没有太多上下文,看的挺头痛!大致翻译了下上下几段注释:

    1. 即使完全覆盖,对于触碰到渲染层边界的栅格化处理,我们依然需要,在上次记录没有覆盖到的纹理下方和纹理化线性过滤的上方,栅格化处理背景颜色。
    2. 内容的最后的纹理可能只有部分被栅格覆盖
    3. 在内容边界外没有被渲染到的部分将使用 MissingResizeInvalidations 颜色,如果这个块能够被看见,那就意味着程序忽视处理了内边边界增长之后栅格化与内容相交的瓦片。

    从第三句大致可以了解到,因为元素的边界增长导致了这个渲染 bug,回头看了下元素的边界状态,果然…

    二、CSS3 transform下的scale

    transform下的scale就不一样了,是明明确确写入规范的。从IE9+到其他现代浏览器都支持。语法为:transform: scale(<x> [<y>]). 同时有scaleXscaleY专门的xy方向的控制。

    zoom不同,scale并不支持百分比值和normal关键字,只能是数值。而且,还能是负数,没错,负数。而zoom不能是负值!

    Charles / Fiddler

    幸好有Charles这样的工具(Windows下请使用Fiddler),Charles会在本地开启一个代理服务,默认接口8888。通过这个代理,模拟器上的请求会被转移到电脑上,我们可以任意地去替换请求文件让我们更加方便地调试页面。

    直接原因

    我们看看 hover 上去之后,层边界的变化:

    图片 8

    很明显,这里的高度溢出了,但是没有处理,看了下这个元素的 css,确实高度上没有做处理,在元素上添加

    CSS

    .channel-item { overflow: hidden; }

    1
    2
    3
    .channel-item {
      overflow: hidden;
    }

    同样可以解决问题。

    最后的解决手段:

    图片 9

    层渲染的问题我还是比较喜欢使用 3d 硬件加速来处理,而 overflow:hidden 这样的 css 布局处理上,我是不太推荐的,搞不好就把哪个重要的内容隐藏掉了。

    三、zoom和scale更深层次的差异

    先总结下上面表面所见的差异:

    1. 浏览器兼容性。IE全族/Chrome/Safari和IE9+现代浏览器的差别。
    2. 控制缩放的值不一样。zoom更全面,但是不能是负数,只能等比例控制;而scale虽然只能是数值,但是能负数,可以只控制1个维度。

    然而,更深层次的差异才是更重要的。

    您可以狠狠地点击这里:zoom和scale对比demo

    从demo我们看出如下几点差异:

    1. zoom的缩放是相对于左上角的;而scale默认是居中缩放;
    2. zoom的缩放改变了元素占据的空间大小;而scale的缩放占据的原始尺寸不变,页面布局不会发生变化;
    3. zoom和scale对元素的渲染计算方法可能有差异(如下截图示意)。图片 10
    4. 对文字的缩放规则不一致。zoom缩放依然受限于最小12像素中文大小限制;而scale就是纯粹的对图形进行比例控制,文字50%原来尺寸。

    图片 11

    然后,还有一个肉眼看不见却更重要的差异,渲染的性能差异明显

    由于zoom的缩放会改变元素的真实空间大小,换句话说,实时影响了其他小伙伴。

    根据我的一些同事的测试,在文档流中zoom加在任意一个元素上都会引起一整个页面的重新渲染,而scale只是在当前的元素上重绘。这其实很好理解,对吧。scale呢变化时候,其原本的尺寸是不变的,因此,就没有layout的重计算;但是zoom牵一发动全身,就麻烦地多!

    这就让我们要斟酌下移动端一些功能的实现了。

    我们要实现元素的缩放效果,可以使用CSS3 animation, 但是存在这样一种情况,就是元素原本就使用了一些transform属性进行,此时,再使用scale进行animation缩放,就会覆盖原来的值,事情就会变得麻烦。

    聪明的小伙伴想到了一个方法,就是使用zoom做动画。从效果上讲,zoom是可以的;但是,从性能上讲,大家就要掂量掂量了,不要弄好后,发现某些Android机子下面动画就像便秘一样,屎拉了一半悬着就是掉不下来,你就有的搞了。

    我能说的就这么多,其他靠你自己了!图片 12

    本文由金沙国际官网发布于web前端,转载请注明出处:记一次淘宝首页奇葩的渲染问题,打造最舒适的

    关键词: