CINXE.COM
Chromium Blog: the fast and the curious
<!DOCTYPE html> <html class='v2 list-page' dir='ltr' itemscope='' itemtype='http://schema.org/Blog' lang='en' xmlns='http://www.w3.org/1999/xhtml' xmlns:b='http://www.google.com/2005/gml/b' xmlns:data='http://www.google.com/2005/gml/data' xmlns:expr='http://www.google.com/2005/gml/expr'> <head> <link href='https://www.blogger.com/static/v1/widgets/3566091532-css_bundle_v2.css' rel='stylesheet' type='text/css'/> <title> Chromium Blog: the fast and the curious </title> <meta content='width=device-width, height=device-height, initial-scale=1.0' name='viewport'/> <meta content='IE=Edge' http-equiv='X-UA-Compatible'/> <meta content='Chromium Blog' property='og:title'/> <meta content='en_US' property='og:locale'/> <meta content='https://blog.chromium.org/search/label/the%20fast%20and%20the%20curious' property='og:url'/> <meta content='Chromium Blog' property='og:site_name'/> <!-- Twitter Card properties --> <meta content='Chromium Blog' property='og:title'/> <meta content='summary' name='twitter:card'/> <meta content='@ChromiumDev' name='twitter:creator'/> <link href='https://fonts.googleapis.com/css?family=Roboto:400italic,400,500,500italic,700,700italic' rel='stylesheet' type='text/css'/> <link href='https://fonts.googleapis.com/icon?family=Material+Icons' rel='stylesheet'/> <script src='https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js' type='text/javascript'></script> <!-- End --> <style id='page-skin-1' type='text/css'><!-- /* <Group description="Header Color" selector="header"> <Variable name="header.background.color" description="Header Background" type="color" default="#ffffff"/> </Group> */ .header-outer { border-bottom: 1px solid #e0e0e0; background: #ffffff; } html, .Label h2, #sidebar .rss a, .BlogArchive h2, .FollowByEmail h2.title, .widget .post h2 { font-family: Roboto, sans-serif; } .plusfollowers h2.title, .post h2.title, .widget h2.title { font-family: Roboto, sans-serif; } .widget-item-control { height: 100%; } .widget.Header, #header { position: relative; height: 100%; width: 100%; } } .widget.Header .header-logo1 { float: left; margin-right: 15px; padding-right: 15px; border-right: 1px solid #ddd; } .header-title h2 { color: rgba(0,0,0,.54); display: inline-block; font-size: 40px; font-family: Roboto, sans-serif; font-weight: normal; line-height: 76px; vertical-align: top; } .header-inner { background-repeat: no-repeat; background-position: right 0px; } .post-author, .byline-author { font-size: 14px; font-weight: normal; color: #757575; color: rgba(0,0,0,.54); } .post-content .img-border { border: 1px solid rgb(235, 235, 235); padding: 4px; } .header-title a { text-decoration: none !important; } pre { border: 1px solid #bbbbbb; margin-top: 1em 0 0 0; padding: 0.99em; overflow-x: auto; overflow-y: auto; } pre, code { font-size: 9pt; background-color: #fafafa; line-height: 125%; font-family: monospace; } pre, code { color: #060; font: 13px/1.54 "courier new",courier,monospace; } .header-left .header-logo1 { width: 128px !important; } .header-desc { line-height: 20px; margin-top: 8px; } .fb-custom img, .twitter-custom img, .gplus-share img { cursor: pointer; opacity: 0.54; } .fb-custom img:hover, .twitter-custom img:hover, .gplus-share img:hover { opacity: 0.87; } .fb-like { width: 80px; } .post .share { float: right; } #twitter-share{ border: #CCC solid 1px; border-radius: 3px; background-image: -webkit-linear-gradient(top,#ffffff,#dedede); } .twitter-follow { background: url(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimKBWDeRb1pqsbNiP9AFLyFDZHzXGYEJZRELMrZ6iI0yz4KeMPH_7tPsrMq9PpJ3H6riC_UohpWMn83_Z1N2sTuTTrVL7i6TrNzpO9oFg4e8VFK4zFJb1rfamWfc8RxG8Fhz2RgRgHN10u/s1600/twitter-bird.png) no-repeat left center; padding-left: 18px; font: normal normal normal 11px/18px 'Helvetica Neue',Arial,sans-serif; font-weight: bold; text-shadow: 0 1px 0 rgba(255,255,255,.5); cursor: pointer; margin-bottom: 10px; } .twitter-fb { padding-top: 2px; } .fb-follow-button { background: -webkit-linear-gradient(#4c69ba, #3b55a0); background: -moz-linear-gradient(#4c69ba, #3b55a0); background: linear-gradient(#4c69ba, #3b55a0); border-radius: 2px; height: 18px; padding: 4px 0 0 3px; width: 57px; border: #4c69ba solid 1px; } .fb-follow-button a { text-decoration: none !important; text-shadow: 0 -1px 0 #354c8c; text-align: center; white-space: nowrap; font-size: 11px; color: white; vertical-align: top; } .fb-follow-button a:visited { color: white; } .fb-follow { padding: 0px 5px 3px 0px; width: 14px; vertical-align: bottom; } .gplus-wrapper { margin-top: 3px; display: inline-block; vertical-align: top; } .twitter-custom, .gplus-share { margin-right: 12px; } .fb-follow-button{ margin: 10px auto; } /** CUSTOM CODE **/ --></style> <style id='template-skin-1' type='text/css'><!-- .header-outer { clear: both; } .header-inner { margin: auto; padding: 0px; } .footer-outer { background: #f5f5f5; clear: both; margin: 0; } .footer-inner { margin: auto; padding: 0px; } .footer-inner-2 { /* Account for right hand column elasticity. */ max-width: calc(100% - 248px); } .google-footer-outer { clear: both; } .cols-wrapper, .google-footer-outer, .footer-inner, .header-inner { max-width: 978px; margin-left: auto; margin-right: auto; } .cols-wrapper { margin: auto; clear: both; margin-top: 60px; margin-bottom: 60px; overflow: hidden; } .col-main-wrapper { float: left; width: 100%; } .col-main { margin-right: 278px; max-width: 660px; } .col-right { float: right; width: 248px; margin-left: -278px; } /* Tweaks for layout mode. */ body#layout .google-footer-outer { display: none; } body#layout .header-outer, body#layout .footer-outer { background: none; } body#layout .header-inner { height: initial; } body#layout .cols-wrapper { margin-top: initial; margin-bottom: initial; } --></style> <!-- start all head --> <meta content='text/html; charset=UTF-8' http-equiv='Content-Type'/> <meta content='blogger' name='generator'/> <link href='https://blog.chromium.org/favicon.ico' rel='icon' type='image/x-icon'/> <link href='https://blog.chromium.org/search/label/the%20fast%20and%20the%20curious' rel='canonical'/> <link rel="alternate" type="application/atom+xml" title="Chromium Blog - Atom" href="https://blog.chromium.org/feeds/posts/default" /> <link rel="alternate" type="application/rss+xml" title="Chromium Blog - RSS" href="https://blog.chromium.org/feeds/posts/default?alt=rss" /> <link rel="service.post" type="application/atom+xml" title="Chromium Blog - Atom" href="https://www.blogger.com/feeds/2471378914199150966/posts/default" /> <!--Can't find substitution for tag [blog.ieCssRetrofitLinks]--> <meta content='https://blog.chromium.org/search/label/the%20fast%20and%20the%20curious' property='og:url'/> <meta content='Chromium Blog' property='og:title'/> <meta content='News and developments from the open source browser project' property='og:description'/> <!-- end all head --> <base target='_self'/> <style> html { font-family: Roboto, sans-serif; -moz-osx-font-smoothing: grayscale; -webkit-font-smoothing: antialiased; } body { padding: 0; /* This ensures that the scroll bar is always present, which is needed */ /* because content render happens after page load; otherwise the header */ /* would "bounce" in-between states. */ min-height: 150%; } h2 { font-size: 16px; } h1, h2, h3, h4, h5 { line-height: 2em; } html, h4, h5, h6 { font-size: 14px; } a, a:visited { /* Ensures links meet minimum contrast ratios. */ color: #3974d6; text-decoration: none; } a:focus, a:hover, a:active { text-decoration: none; } .Header { margin-top: 15px; } .Header h1 { font-size: 32px; font-weight: 300; line-height: 32px; height: 42px; } .header-inner .Header .titlewrapper { padding: 0; margin-top: 30px; } .header-inner .Header .descriptionwrapper { padding: 0; margin: 0; } .cols-wrapper { margin-top: 56px; } .header-outer, .cols-wrapper, .footer-outer, .google-footer-outer { padding: 0 60px; } .header-inner { height: 256px; position: relative; } html, .header-inner a { color: #212121; color: rgba(0,0,0,.87); } .header-inner .google-logo { display: inline-block; background-size: contain; z-index: 1; height: 70px; overflow: hidden; margin-top: 4px; margin-right: 8px; } .header-left { position: absolute; top: 50%; -webkit-transform: translateY(-50%); transform: translateY(-50%); margin-top: 12px; width: 100%; } .google-logo { margin-left: -4px; } .google-logo img{ height:70px; } #google-footer { position: relative; font-size: 13px; list-style: none; text-align: right; } #google-footer a { color: #444; } #google-footer ul { margin: 0; padding: 0; height: 144px; line-height: 144px; } #google-footer ul li { display: inline; } #google-footer ul li:before { color: #999; content: "\00b7"; font-weight: bold; margin: 5px; } #google-footer ul li:first-child:before { content: ''; } #google-footer .google-logo-dark { left: 0; margin-top: -16px; position: absolute; top: 50%; } /** Sitemap links. **/ .footer-inner-2 { font-size: 14px; padding-top: 42px; padding-bottom: 74px; } .footer-inner-2 .HTML h2 { color: #212121; color: rgba(0,0,0,.87); font-size: 14px; font-weight: 500; padding-left: 0; margin: 10px 0; } .footer-inner-2 .HTML ul { font-weight: normal; list-style: none; padding-left: 0; } .footer-inner-2 .HTML li { line-height: 24px; padding: 0; } .footer-inner-2 li a { color: rgba(65,132,243,.87); } /** Archive widget. **/ .BlogArchive { font-size: 13px; font-weight: normal; } .BlogArchive .widget-content { display: none; } .BlogArchive h2, .Label h2 { color: #4184F3; text-decoration: none; } .BlogArchive .hierarchy li { display: inline-block; } /* Specificity needed here to override widget CSS defaults. */ .BlogArchive #ArchiveList ul li, .BlogArchive #ArchiveList ul ul li { margin: 0; padding-left: 0; text-indent: 0; } .BlogArchive .intervalToggle { cursor: pointer; } .BlogArchive .expanded .intervalToggle .new-toggle { -ms-transform: rotate(180deg); transform: rotate(180deg); } .BlogArchive .new-toggle { float: right; padding-top: 3px; opacity: 0.87; } #ArchiveList { text-transform: uppercase; } #ArchiveList .expanded > ul:last-child { margin-bottom: 16px; } #ArchiveList .archivedate { width: 100%; } /* Months */ .BlogArchive .items { max-width: 150px; margin-left: -4px; } .BlogArchive .expanded .items { margin-bottom: 10px; overflow: hidden; } .BlogArchive .items > ul { float: left; height: 32px; } .BlogArchive .items a { padding: 0 4px; } .Label { font-size: 13px; font-weight: normal; } .sidebar-icon { display: inline-block; width: 24px; height: 24px; vertical-align: middle; margin-right: 12px; margin-top: -1px } .Label a { margin-right: 4px; } .Label .widget-content { display: none; } .FollowByEmail { font-size: 13px; font-weight: normal; } .FollowByEmail h2 { background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAALCAYAAACZIGYHAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAUBJREFUeNrMkSGLAlEUhb+ZB4JFi8mx2cz+ApvhRUGTcUCrNqNJDYIi+DO0GUwmQXDK2DSIoGgZcSaIjDrzwrK4ssvChj1w0733O+fdp+m6PozH4yQSCfb7Pa7r8pOi0SjJZBLP8zgej4gAIMvlMuPxmADIYrHger1+C6lUKmo+NJ/NZojb7SZDWiwWo1qtks1msW2bw+HwZdkwDHq9HvV6nel0SqvVYrvdIh6Ph3Qch+VyqRYLhQJSSjRNw7IsfN9XgGKxSLfbJZfL0e/3aTabrFYr7vc7IujLcOh8PqunrNdr0uk0pVKJVCpFJBJRgEajweVyod1uMxgM2O12BAGUgRbU8DV2JpOhVquRz+cRQii3+XxOp9NRN3jVR5LPOp1OjEYjlSL8hclkgmmabDabt4d+m+S30vkD/R/IU4ABAPTZgnZdmG/PAAAAAElFTkSuQmCC"); background-repeat: no-repeat; background-position: 0 50%; text-indent: 30px; } .FollowByEmail .widget-content { display: none; } .searchBox input { border: 1px solid #eee; color: #212121; color: rgba(0,0,0,.87); font-size: 14px; padding: 8px 8px 8px 40px; width: 164px; font-family: Roboto, sans-serif; background: url("https://www.gstatic.com/images/icons/material/system/1x/search_grey600_24dp.png") 8px center no-repeat; } .searchBox ::-webkit-input-placeholder { /* WebKit, Blink, Edge */ color: rgba(0,0,0,.54); } .searchBox :-moz-placeholder { /* Mozilla Firefox 4 to 18 */ color: #000; opacity: 0.54; } .searchBox ::-moz-placeholder { /* Mozilla Firefox 19+ */ color: #000; opacity: 0.54; } .searchBox :-ms-input-placeholder { /* Internet Explorer 10-11 */ color: #757575; } .widget-item-control { margin-top: 0px; } .section { margin: 0; padding: 0; } #sidebar-top { border: 1px solid #eee; } #sidebar-top > div { margin: 16px 0; } .widget ul { line-height: 1.6; } /*main post*/ .post { margin-bottom:30px; } #main .post .title { margin: 0; } #main .post .title a { color: #212121; color: rgba(0,0,0,.87); font-weight: normal; font-size: 24px; } #main .post .title a:hover { text-decoration:none; color: #3974d6; } .message, #main .post .post-header { margin: 0; padding: 0; } #main .post .post-header .caption, #main .post .post-header .labels-caption, #main .post .post-footer .caption, #main .post .post-footer .labels-caption { color: #444; font-weight: 500; } #main .tr-caption-container td { text-align: left; } #main .post .tr-caption { color: #757575; color: rgba(0,0,0,.54); display: block; max-width: 560px; padding-bottom: 20px; } #main .post .tr-caption-container { line-height: 24px; margin: -1px 0 0 0 !important; padding: 4px 0; text-align: left; } #main .post .post-header .published{ font-size:11px; font-weight:bold; } .post-header .publishdate { font-size: 17px; font-weight:normal; color: #757575; color: rgba(0,0,0,.54); } #main .post .post-footer{ font-size:12px; padding-bottom: 21px; } .label-footer { margin-bottom: 12px; margin-top: 12px; } .comment-img { margin-right: 16px; opacity: 0.54; vertical-align: middle; } #main .post .post-header .published { margin-bottom: 40px; margin-top: -2px; } .post .post-content { color: #212121; color: rgba(0,0,0,.87); font-size: 17px; margin: 25px 0 36px 0; line-height: 32px; } .post-body .post-content ul, .post-body .post-content ol { margin: 16px 0; padding: 0 48px; } .post-summary { display: none; } /* Another old-style caption. */ .post-content div i, .post-content div + i { font-size: 14px; font-style: normal; color: #757575; color: rgba(0,0,0,.54); display: block; line-height: 24px; margin-bottom: 16px; text-align: left; } /* Another old-style caption (with link) */ .post-content a > i { color: #4184F3 !important; } /* Old-style captions for images. */ .post-content .separator + div:not(.separator) { margin-top: -16px; } /* Capture section headers. */ .post-content br + br + b, .post-content .space + .space + b, .post-content .separator + b { display: inline-block; margin-bottom: 8px; margin-top: 24px; } .post-content li { line-height: 32px; } /* Override all post images/videos to left align. */ .post-content .separator, .post-content > div { text-align: left; } .post-content .separator > a, .post-content .separator > span { margin-left: 0 !important; } .post-content img { max-width: 100%; height: auto; width: auto; } .post-content .tr-caption-container img { margin-bottom: 12px; } .post-content iframe, .post-content embed { max-width: 100%; } .post-content .carousel-container { margin-bottom: 48px; } #main .post-content b { font-weight: 500; } /* These are the main paragraph spacing tweaks. */ #main .post-content br { content: ' '; display: block; padding: 4px; } .post-content .space { display: block; height: 8px; } .post-content iframe + .space, .post-content iframe + br { padding: 0 !important; } #main .post .jump-link { margin-bottom:10px; } .post-content img, .post-content iframe { margin: 30px 0 20px 0; } .post-content > img:first-child, .post-content > iframe:first-child { margin-top: 0; } .col-right .section { padding: 0 16px; } #aside { background:#fff; border:1px solid #eee; border-top: 0; } #aside .widget { margin:0; } #aside .widget h2, #ArchiveList .toggle + a.post-count-link { color: #212121; color: rgba(0,0,0,.87); font-weight: 400 !important; margin: 0; } #ArchiveList .toggle { float: right; } #ArchiveList .toggle .material-icons { padding-top: 4px; } #sidebar .tab { cursor: pointer; } #sidebar .tab .arrow { display: inline-block; float: right; } #sidebar .tab .icon { display: inline-block; vertical-align: top; height: 24px; width: 24px; margin-right: 13px; margin-left: -1px; margin-top: 1px; color: #757575; color: rgba(0,0,0,.54); } #sidebar .widget-content > :first-child { padding-top: 8px; } #sidebar .active .tab .arrow { -ms-transform: rotate(180deg); transform: rotate(180deg); } #sidebar .arrow { color: #757575; color: rgba(0,0,0,.54); } #sidebar .widget h2 { font-size: 14px; line-height: 24px; display: inline-block; } #sidebar .widget .BlogArchive { padding-bottom: 8px; } #sidebar .widget { border-bottom: 1px solid #eee; box-shadow: 0px 1px 0 white; margin-bottom: 0; padding: 14px 0; min-height: 20px; } #sidebar .widget:last-child { border-bottom: none; box-shadow: none; margin-bottom: 0; } #sidebar ul { margin: 0; padding: 0; } #sidebar ul li { list-style:none; padding:0; } #sidebar ul li a { line-height: 32px; } #sidebar .archive { background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAYCAYAAADzoH0MAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAE1JREFUeNpiNDY23s9AAWBioBCwYBM8c+YMVsUmJibEGYBNMS5DaeMFfDYSZQA2v9I3FrB5AZeriI4FmnrBccCT8mhmGs1MwyAzAQQYAKEWG9zm9QFEAAAAAElFTkSuQmCC"); height: 24px; line-height: 24px; padding-left: 30px; } #sidebar .labels { background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAARCAYAAAA7bUf6AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAUxJREFUeNpiNDY23s9AAMycOfM7UF05kHkZmzwTMkdSUhKrIcXFxZy3bt3qBjIN8RrS09PDsHnzZjCNDr58+cKQlpbGDjSoHcg1w2oIyAUODg5gARCNzUVIBrUCuVYYhjx//pzhwIEDYAEQDeJjA1CDWIAGNQK59jBxRuSABbkAlwHIgIeHh2HWrFn/1NTU2oDcvSgBS4wBSC5iArqoCsj1YGIgEyAZVMoEchqlBjEB/cZAiUHg2AEGznpKDAImxOeM////B4VLKtBvEUCngZ1ILKivr3/u6+ubBzJAGZQ9gC5aQoqLgAY8BhkAZL4BuQQkxgXE34A4BuiiZEIuAhrwEGhAEZD5DpzYoIaA2UAM4kQADUrHZRDUgAIg8wO2XAwzbQXQa5OweQ1owB10AyA6gS7BgX1u3ry5397eHow3bdo0EyjGi00tQIABANPgyAH1q1eaAAAAAElFTkSuQmCC"); height: 20px; line-height: 20px; padding-left: 30px; } #sidebar .rss a { background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAX5JREFUeNqsVDGSgkAQHL2rIiIikohIc/EBRkbwAIwuwgfwAXiAD9AHSI7kEkECRCb6AIyINDLx7K0aa6kT7uq0q7YYtnZ7umdnt7darXbr9Zpegeu61DNNc0dvwCcH4/GYJpMJnc9nOhwOVJbl/4hAAokMECZJQtvt9k+kH7qufyEYDAakqqqYxFdRFBqNRmTbNg2HQ0rTlK7XayvR0xqBdDqdkuM4dE/0ULhYLOh4PHYrknG5XGi/31MYhuL/nkwonM1mlGUZ1XXdrsiyLGEDhY7juJEZ1u5tIixDGdYhmYw+B7CAzPP5nDabjdgIAgCksMX1832/3drtdqPT6SQWapomiGEFNkDEdpDMMAzK81ys/7XYy+XyoQgq2WoURSIJ2iIIgp/WZCCTvFm2wgeAU31aI3Q2GhIDMeB53qPYPIcm5VrxXIOIOxsDMStjVawAc1VViRgN22lNBiuQN3GR+SY07hpOoStmFQAKXRRFY93bnpG+fONfedi+BRgAbkS8Fxp7QQIAAAAASUVORK5CYII="); } #sidebar .subscription a { background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAALCAYAAACZIGYHAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAUBJREFUeNrMkSGLAlEUhb+ZB4JFi8mx2cz+ApvhRUGTcUCrNqNJDYIi+DO0GUwmQXDK2DSIoGgZcSaIjDrzwrK4ssvChj1w0733O+fdp+m6PozH4yQSCfb7Pa7r8pOi0SjJZBLP8zgej4gAIMvlMuPxmADIYrHger1+C6lUKmo+NJ/NZojb7SZDWiwWo1qtks1msW2bw+HwZdkwDHq9HvV6nel0SqvVYrvdIh6Ph3Qch+VyqRYLhQJSSjRNw7IsfN9XgGKxSLfbJZfL0e/3aTabrFYr7vc7IujLcOh8PqunrNdr0uk0pVKJVCpFJBJRgEajweVyod1uMxgM2O12BAGUgRbU8DV2JpOhVquRz+cRQii3+XxOp9NRN3jVR5LPOp1OjEYjlSL8hclkgmmabDabt4d+m+S30vkD/R/IU4ABAPTZgnZdmG/PAAAAAElFTkSuQmCC"); } #sidebar-bottom { background: #f5f5f5; border-top:1px solid #eee; } #sidebar-bottom .widget { border-bottom: 1px solid #e0e0e0; padding: 15px 0; text-align: center; } #sidebar-bottom > div:last-child { border-bottom: 0; } #sidebar-bottom .text { line-height: 20px; } /* Home, forward, and backward pagination. */ .blog-pager { border-top : 1px #e0e0e0 solid; padding-top: 10px; margin-top: 15px; text-align: right !important; } #blog-pager { margin-botom: 0; margin-top: -14px; padding: 16px 0 0 0; } #blog-pager a { display: inline-block; } .blog-pager i.disabled { opacity: 0.2 !important; } .blog-pager i { color: black; margin-left: 16px; opacity: 0.54; } .blog-pager i:hover, .blog-pager i:active { opacity: 0.87; } #blog-pager-older-link, #blog-pager-newer-link { float: none; } .gplus-profile { background-color: #fafafa; border: 1px solid #eee; overflow: hidden; width: 212px; } .gplus-profile-inner { margin-left: -1px; margin-top: -1px; } /* Sidebar follow buttons. */ .followgooglewrapper { padding: 12px 0 0 0; } .loading { visibility: hidden; } .detail-page .post-footer .cmt_iframe_holder { padding-top: 40px !important; } /** Desktop **/ @media (max-width: 900px) { .col-right { display: none; } .col-main { margin-right: 0; min-width: initial; } .footer-outer { display: none; } .cols-wrapper { min-width: initial; } .google-footer-outer { background-color: #f5f5f5; } } /** Tablet **/ @media (max-width: 712px) { .header-outer, .cols-wrapper, .footer-outer, .google-footer-outer { padding: 0 40px; } } /* An extra breakpoint accommodating for long blog titles. */ @media (max-width: 600px) { .header-left { height: 100%; position: initial; top: inherit; margin-top: 0; -webkit-transform: initial; transform: initial; } .header-title { margin-top: 18px; } .header-inner { height: auto; margin-bottom: 32px; margin-top: 32px; } .header-desc { margin-top: 12px; } .header-inner .google-logo { height: 70px; margin-top: 3px; } .header-inner .google-logo img { height: 70px; } .header-title h2 { font-size: 32px; line-height: 76px; } } /** Mobile/small desktop window; also landscape. **/ @media (max-width: 480px), (max-height: 480px) { .header-outer, .cols-wrapper, .footer-outer, .google-footer-outer { padding: 0 16px; } .cols-wrapper { margin-top: 0; } .post-header .publishdate, .post .post-content { font-size: 16px; } .post .post-content { line-height: 28px; margin-bottom: 30px; } .post { margin-top: 30px; } .byline-author { display: block; font-size: 12px; line-height: 24px; margin-top: 6px; } #main .post .title a { font-weight: 500; color: #4c4c4c; color: rgba(0,0,0,.70); } #main .post .post-header { padding-bottom: 12px; } #main .post .post-header .published { margin-bottom: -8px; margin-top: 3px; } .post .read-more { display: block; margin-top: 14px; } .post .tr-caption { font-size: 12px; } #main .post .title a { font-size: 20px; line-height: 30px; } .post-content iframe { /* iframe won't keep aspect ratio when scaled down. */ max-height: 240px; } .post-content .separator img, .post-content .tr-caption-container img, .post-content iframe { margin-left: -16px; max-width: inherit; width: calc(100% + 32px); } .post-content table, .post-content td { width: 100%; } #blog-pager { margin: 0; padding: 16px 0; } /** List page tweaks. **/ .list-page .post-original { display: none; } .list-page .post-summary { display: block; } .list-page .comment-container { display: none; } .list-page #blog-pager { padding-top: 0; border: 0; margin-top: -8px; } .list-page .label-footer { display: none; } .list-page #main .post .post-footer { border-bottom: 1px solid #eee; margin: -16px 0 0 0; padding: 0 0 20px 0; } .list-page .post .share { display: none; } /** Detail page tweaks. **/ .detail-page .post-footer .cmt_iframe_holder { padding-top: 32px !important; } .detail-page .label-footer { margin-bottom: 0; } .detail-page #main .post .post-footer { padding-bottom: 0; } .detail-page #comments { display: none; } } [data-about-pullquote], [data-is-preview], [data-about-syndication] { display: none; } </style> <noscript> <style> .loading { visibility: visible }</style> </noscript> <script type='text/javascript'> (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) })(window,document,'script','https://www.google-analytics.com/analytics.js','ga'); ga('create', 'UA-37592578-1', 'auto', 'blogger'); ga('blogger.send', 'pageview'); </script> <link href='https://www.blogger.com/dyn-css/authorization.css?targetBlogID=2471378914199150966&zx=3a5e6827-7ceb-4daf-b12c-bebbc55c1d22' media='none' onload='if(media!='all')media='all'' rel='stylesheet'/><noscript><link href='https://www.blogger.com/dyn-css/authorization.css?targetBlogID=2471378914199150966&zx=3a5e6827-7ceb-4daf-b12c-bebbc55c1d22' rel='stylesheet'/></noscript> <meta name='google-adsense-platform-account' content='ca-host-pub-1556223355139109'/> <meta name='google-adsense-platform-domain' content='blogspot.com'/> <link rel="stylesheet" href="https://fonts.googleapis.com/css2?display=swap&family=Roboto"></head> <body> <script type='text/javascript'> //<![CDATA[ var axel = Math.random() + ""; var a = axel * 10000000000000; document.write('<iframe src="https://2542116.fls.doubleclick.net/activityi;src=2542116;type=gblog;cat=googl0;ord=ord=' + a + '?" width="1" height="1" frameborder="0" style="display:none"></iframe>'); //]]> </script> <noscript> <img alt='' height='1' src='https://ad.doubleclick.net/ddm/activity/src=2542116;type=gblog;cat=googl0;ord=1?' width='1'/> </noscript> <!-- Header --> <div class='header-outer'> <div class='header-inner'> <div class='section' id='header'><div class='widget Header' data-version='1' id='Header1'> <div class='header-left'> <div class='header-title'> <a class='google-logo' href='https://blog.chromium.org/'> <img alt="Chromium Blog" height="50" src="//1.bp.blogspot.com/-vkF7AFJOwBk/VkQxeAGi1mI/AAAAAAAARYo/57denvsQ8zA/s1600-r/logo_chromium.png"> </a> <a href='/.'> <h2> Chromium Blog </h2> </a> </div> <div class='header-desc'> News and developments from the open source browser project </div> </div> </div></div> </div> </div> <!-- all content wrapper start --> <div class='cols-wrapper loading'> <div class='col-main-wrapper'> <div class='col-main'> <div class='section' id='main'><div class='widget Blog' data-version='1' id='Blog1'> <div class='post' data-id='7799096493389946023' itemscope='' itemtype='http://schema.org/BlogPosting'> <h2 class='title' itemprop='name'> <a href='https://blog.chromium.org/2024/06/how-chrome-achieved-highest-score-ever.html' itemprop='url' title='How Chrome achieved the highest score ever on Speedometer 3'> How Chrome achieved the highest score ever on Speedometer 3 </a> </h2> <div class='post-header'> <div class='published'> <span class='publishdate' itemprop='datePublished'> Thursday, June 6, 2024 </span> </div> </div> <div class='post-body'> <div class='post-content' itemprop='articleBody'> <script type='text/template'> <p><em><br /></em></p><p style="text-align: center;"></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjTQhp2W8dIjin6cG9FZFPANCCxZkFh9n1Nkn60O8XvgU4XVY_rq3ChNITmiJ1VG16BHnsxVijTYMc06SNA0VHjqfee6dqZLgfjazWxh7p1b3i-pj4thXDt3QyK3vWSpRgrTHaxiSFfPvc1YRDtdcBOorm85i53-FebJDWUXrJA4a_oMAYNbxjTFE0PPbJc/s400/Fast%20Curious_image.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="166" data-original-width="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjTQhp2W8dIjin6cG9FZFPANCCxZkFh9n1Nkn60O8XvgU4XVY_rq3ChNITmiJ1VG16BHnsxVijTYMc06SNA0VHjqfee6dqZLgfjazWxh7p1b3i-pj4thXDt3QyK3vWSpRgrTHaxiSFfPvc1YRDtdcBOorm85i53-FebJDWUXrJA4a_oMAYNbxjTFE0PPbJc/s16000/Fast%20Curious_image.png" /></a></div><br /><em><br /></em><p></p><p> <em>Today’s The Fast and the Curious post explores how Chrome achieved the highest score on the new Speedometer 3.0, an upgraded browser benchmarking tool to optimize the performance of Web applications. Try out <a href="https://www.google.com/chrome/">Chrome</a> today! </em></p> <p> <a href="https://browserbench.org/Speedometer3.0/">Speedometer 3.0</a> is a recently published benchmark for <a href="https://webkit.org/blog/15131/speedometer-3-0-the-best-way-yet-to-measure-browser-performance/">measuring browser performance</a> that was created as an industry collaboration between companies like Google, Apple, Mozilla, Intel, and Microsoft. This benchmark helped us identify areas in which we could optimize Chrome to deliver a faster browser experience to all our users. </p> <p> Here’s a closer look at how we further optimized Chrome to achieve the highest score ever Speedometer 3, by carefully tracking its recent performance over time as the updated benchmark was being developed. Since the inception of Speedometer 3 in May 2022, we've driven a 72% increase in Chrome’s Speedometer score - translating into performance gains for our users: </p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjhWV2DrIDMUUKPwXhOGaWNB1Md15huKND9UdpxiFs8taTD8PvDbGcbQnqgzibx8A9Q0SShTLxW0AyjGoJnNwIW-OEPfo5NN8vy0KvcS6vj7PnscI2-FE7_TZ19aTsjIRK5iYohctES6JgahB5W72NJVDkGJ_LhhyT_f9dcGKhVD9FsupDKI_bGwm4WtHw-/s8333/Fast%20&%20Curious%20In-Line%20Graph%20_%20Speedometer%20improvements_HighRes-04.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="5151" data-original-width="8333" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjhWV2DrIDMUUKPwXhOGaWNB1Md15huKND9UdpxiFs8taTD8PvDbGcbQnqgzibx8A9Q0SShTLxW0AyjGoJnNwIW-OEPfo5NN8vy0KvcS6vj7PnscI2-FE7_TZ19aTsjIRK5iYohctES6JgahB5W72NJVDkGJ_LhhyT_f9dcGKhVD9FsupDKI_bGwm4WtHw-/s16000/Fast%20&%20Curious%20In-Line%20Graph%20_%20Speedometer%20improvements_HighRes-04.png" /></a></div><br /><p style="text-align: center;"><br /></p> <h3 style="text-align: left;"> Optimizing workloads </h3> <p> By looking at the workloads in Speedometer and in which functions Chrome was spending the most time, we were able to make targeted optimizations to those functions that each drove an increase in Chrome’s score. For example, the SpaceSplitString function is used heavily to turn space-separated strings such as those in “class=’foo bar’ ” into a list representation. In this function we removed some unnecessary bound checks. When we detect that there are duplicated stylesheets, we dedupe them and reference a single stylesheet instance. We made an optimization to reduce the cost of drawing paths and arcs by tuning memory allocations. When creating form editors we detected some unnecessary processing that occurs when form elements are created. Within querySelector, we were able to detect what selector was commonly used and create a hot-path for that. </p> <p> We <a href="https://blog.chromium.org/2023/04/more-ways-were-making-chrome-faster.html">previously shared</a> how we optimized innerHTML using specialized fast paths for parsing, an implementation that also <a href="https://github.com/WebKit/WebKit/pull/9926">made its way into WebKit</a>. Some workloads in Speedometer 3 use <a href="https://developer.mozilla.org/en-US/docs/Web/API/DOMParser">DOMParser</a> so we extended the same optimization for another 1% gain. </p> <p> We worked with the Harfbuzz maintainer to also optimize how Chrome renders <a href="https://en.wikipedia.org/wiki/Apple_Advanced_Typography#AAT_Layout">AAT</a> fonts such as those used by Apple Mac OS system fonts. Text starts as a processed stream of unicode characters that is then transformed into a glyph stream that is then run through a state machine defined in the AAT font. The optimization allows us to determine more quickly whether glyphs actually participate in the rules for the state machine, leading to speed-ups when processing text using AAT. </p> <p> </p> <h3 style="text-align: left;"> Picking the right code to focus on </h3> <p> An important strategy for achieving high performance is tiering up code, which is picking the right code to further optimize within the engine. Intel contributed profile guided tiering to V8 that remembers tiering decisions from the past such that if a function was stably tiered up in the past, we eagerly tier it up on future runs. </p> <h3 style="text-align: left;"> Improving garbage collection </h3> <p> Another area of changes that drove around 3% progression on Speedometer 3 was improvements around garbage collection. V8’s garbage collector has a <a href="https://queue.acm.org/detail.cfm?id=2977741">long history of making use of renderer idle time</a> to avoid interfering with actual application code. The recent changes follow this spirit by extending existing mechanisms to prefer garbage collection in idle time on otherwise very active renderers where possible. Specifically, DOM finalization code that is run on reclaiming objects is now also run in idle time. Previously, such operations would compete with regular application code over CPU resources. In addition, V8 now supports a much more compact layout for objects that wrap DOM elements, i.e., all objects that are exposed to JavaScript frameworks. The compact layout reduces memory pressure and results in less time spent on garbage collection. </p> <p> <em>Posted by Thomas Nattestad, Chrome Product Manager</em> </p> <span itemprop='author' itemscope='itemscope' itemtype='http://schema.org/Person'> <meta content='https://plus.google.com/116899029375914044550' itemprop='url'/> </span> </script> <noscript> <p><em><br /></em></p><p style="text-align: center;"></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjTQhp2W8dIjin6cG9FZFPANCCxZkFh9n1Nkn60O8XvgU4XVY_rq3ChNITmiJ1VG16BHnsxVijTYMc06SNA0VHjqfee6dqZLgfjazWxh7p1b3i-pj4thXDt3QyK3vWSpRgrTHaxiSFfPvc1YRDtdcBOorm85i53-FebJDWUXrJA4a_oMAYNbxjTFE0PPbJc/s400/Fast%20Curious_image.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="166" data-original-width="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjTQhp2W8dIjin6cG9FZFPANCCxZkFh9n1Nkn60O8XvgU4XVY_rq3ChNITmiJ1VG16BHnsxVijTYMc06SNA0VHjqfee6dqZLgfjazWxh7p1b3i-pj4thXDt3QyK3vWSpRgrTHaxiSFfPvc1YRDtdcBOorm85i53-FebJDWUXrJA4a_oMAYNbxjTFE0PPbJc/s16000/Fast%20Curious_image.png" /></a></div><br /><em><br /></em><p></p><p> <em>Today’s The Fast and the Curious post explores how Chrome achieved the highest score on the new Speedometer 3.0, an upgraded browser benchmarking tool to optimize the performance of Web applications. Try out <a href="https://www.google.com/chrome/">Chrome</a> today! </em></p> <p> <a href="https://browserbench.org/Speedometer3.0/">Speedometer 3.0</a> is a recently published benchmark for <a href="https://webkit.org/blog/15131/speedometer-3-0-the-best-way-yet-to-measure-browser-performance/">measuring browser performance</a> that was created as an industry collaboration between companies like Google, Apple, Mozilla, Intel, and Microsoft. This benchmark helped us identify areas in which we could optimize Chrome to deliver a faster browser experience to all our users. </p> <p> Here’s a closer look at how we further optimized Chrome to achieve the highest score ever Speedometer 3, by carefully tracking its recent performance over time as the updated benchmark was being developed. Since the inception of Speedometer 3 in May 2022, we've driven a 72% increase in Chrome’s Speedometer score - translating into performance gains for our users: </p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjhWV2DrIDMUUKPwXhOGaWNB1Md15huKND9UdpxiFs8taTD8PvDbGcbQnqgzibx8A9Q0SShTLxW0AyjGoJnNwIW-OEPfo5NN8vy0KvcS6vj7PnscI2-FE7_TZ19aTsjIRK5iYohctES6JgahB5W72NJVDkGJ_LhhyT_f9dcGKhVD9FsupDKI_bGwm4WtHw-/s8333/Fast%20&%20Curious%20In-Line%20Graph%20_%20Speedometer%20improvements_HighRes-04.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="5151" data-original-width="8333" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjhWV2DrIDMUUKPwXhOGaWNB1Md15huKND9UdpxiFs8taTD8PvDbGcbQnqgzibx8A9Q0SShTLxW0AyjGoJnNwIW-OEPfo5NN8vy0KvcS6vj7PnscI2-FE7_TZ19aTsjIRK5iYohctES6JgahB5W72NJVDkGJ_LhhyT_f9dcGKhVD9FsupDKI_bGwm4WtHw-/s16000/Fast%20&%20Curious%20In-Line%20Graph%20_%20Speedometer%20improvements_HighRes-04.png" /></a></div><br /><p style="text-align: center;"><br /></p> <h3 style="text-align: left;"> Optimizing workloads </h3> <p> By looking at the workloads in Speedometer and in which functions Chrome was spending the most time, we were able to make targeted optimizations to those functions that each drove an increase in Chrome’s score. For example, the SpaceSplitString function is used heavily to turn space-separated strings such as those in “class=’foo bar’ ” into a list representation. In this function we removed some unnecessary bound checks. When we detect that there are duplicated stylesheets, we dedupe them and reference a single stylesheet instance. We made an optimization to reduce the cost of drawing paths and arcs by tuning memory allocations. When creating form editors we detected some unnecessary processing that occurs when form elements are created. Within querySelector, we were able to detect what selector was commonly used and create a hot-path for that. </p> <p> We <a href="https://blog.chromium.org/2023/04/more-ways-were-making-chrome-faster.html">previously shared</a> how we optimized innerHTML using specialized fast paths for parsing, an implementation that also <a href="https://github.com/WebKit/WebKit/pull/9926">made its way into WebKit</a>. Some workloads in Speedometer 3 use <a href="https://developer.mozilla.org/en-US/docs/Web/API/DOMParser">DOMParser</a> so we extended the same optimization for another 1% gain. </p> <p> We worked with the Harfbuzz maintainer to also optimize how Chrome renders <a href="https://en.wikipedia.org/wiki/Apple_Advanced_Typography#AAT_Layout">AAT</a> fonts such as those used by Apple Mac OS system fonts. Text starts as a processed stream of unicode characters that is then transformed into a glyph stream that is then run through a state machine defined in the AAT font. The optimization allows us to determine more quickly whether glyphs actually participate in the rules for the state machine, leading to speed-ups when processing text using AAT. </p> <p> </p> <h3 style="text-align: left;"> Picking the right code to focus on </h3> <p> An important strategy for achieving high performance is tiering up code, which is picking the right code to further optimize within the engine. Intel contributed profile guided tiering to V8 that remembers tiering decisions from the past such that if a function was stably tiered up in the past, we eagerly tier it up on future runs. </p> <h3 style="text-align: left;"> Improving garbage collection </h3> <p> Another area of changes that drove around 3% progression on Speedometer 3 was improvements around garbage collection. V8’s garbage collector has a <a href="https://queue.acm.org/detail.cfm?id=2977741">long history of making use of renderer idle time</a> to avoid interfering with actual application code. The recent changes follow this spirit by extending existing mechanisms to prefer garbage collection in idle time on otherwise very active renderers where possible. Specifically, DOM finalization code that is run on reclaiming objects is now also run in idle time. Previously, such operations would compete with regular application code over CPU resources. In addition, V8 now supports a much more compact layout for objects that wrap DOM elements, i.e., all objects that are exposed to JavaScript frameworks. The compact layout reduces memory pressure and results in less time spent on garbage collection. </p> <p> <em>Posted by Thomas Nattestad, Chrome Product Manager</em> </p> <span itemprop='author' itemscope='itemscope' itemtype='http://schema.org/Person'> <meta content='https://plus.google.com/116899029375914044550' itemprop='url'/> </span> </noscript> </div> </div> <div class='share'> <span class='twitter-custom social-wrapper' data-href='http://twitter.com/share?text=Chromium Blog:How Chrome achieved the highest score ever on Speedometer 3&url=https://blog.chromium.org/2024/06/how-chrome-achieved-highest-score-ever.html&via=ChromiumDev'> <img alt='Share on Twitter' height='24' src='https://www.gstatic.com/images/icons/material/system/2x/post_twitter_black_24dp.png' width='24'/> </span> <span class='fb-custom social-wrapper' data-href='https://www.facebook.com/sharer.php?u=https://blog.chromium.org/2024/06/how-chrome-achieved-highest-score-ever.html'> <img alt='Share on Facebook' height='24' src='https://www.gstatic.com/images/icons/material/system/2x/post_facebook_black_24dp.png' width='24'/> </span> </div> <div class='post-footer'> <div class='cmt_iframe_holder' data-href='https://blog.chromium.org/2024/06/how-chrome-achieved-highest-score-ever.html' data-viewtype='FILTERED_POSTMOD'></div> <a href='https://plus.google.com/112374322230920073195' rel='author' style='display:none;'> Google </a> <div class='label-footer'> <span class='labels-caption'> Labels: </span> <span class='labels'> <a class='label' href='https://blog.chromium.org/search/label/the%20fast%20and%20the%20curious' rel='tag'> the fast and the curious </a> </span> </div> </div> </div> <div class='post' data-id='2966402891480312376' itemscope='' itemtype='http://schema.org/BlogPosting'> <h2 class='title' itemprop='name'> <a href='https://blog.chromium.org/2024/06/introducing-shared-memory-versioning-to.html' itemprop='url' title='Introducing Shared Memory Versioning to improve slow interactions'> Introducing Shared Memory Versioning to improve slow interactions </a> </h2> <div class='post-header'> <div class='published'> <span class='publishdate' itemprop='datePublished'> Monday, June 3, 2024 </span> </div> </div> <div class='post-body'> <div class='post-content' itemprop='articleBody'> <script type='text/template'> <p style="text-align: center;"></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgULbG_V-g8EZnGGU7HOmjeHhtXqsFS5cXno21FsN1uucnkTMdlq9tL9rOoZW7fx5vqp6_nW3R5Ib4JJZxMr9zD-MVIqLuCyy8N6ZheCW4iYkI7unu2GX7mMG2PVHNkNrykjbgi5PUwurzRSbd89DP6k1hGe7hze6EKVAzo4XKO8b3NfiO4PRsnHNwMKBDa/s400/Fast%20Curious_image.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="166" data-original-width="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgULbG_V-g8EZnGGU7HOmjeHhtXqsFS5cXno21FsN1uucnkTMdlq9tL9rOoZW7fx5vqp6_nW3R5Ib4JJZxMr9zD-MVIqLuCyy8N6ZheCW4iYkI7unu2GX7mMG2PVHNkNrykjbgi5PUwurzRSbd89DP6k1hGe7hze6EKVAzo4XKO8b3NfiO4PRsnHNwMKBDa/s16000/Fast%20Curious_image.png" /></a></div><br /><em><br /></em><p></p><p> <em>On the Chrome team, we believe it’s not sufficient to be fast most of the time, we have to be fast all of the time. Today’s The Fast and the Curious post explores how we contributed to Core Web Vitals by surveying the field data of Chrome responding to user interactions across all websites, ultimately improving performance of the web. </em> </p> <p> As billions of people turn to the web to get things done every day, the browser becomes more responsible for hosting a multitude of apps at once, resource contention becomes a challenge. The multi-process Chrome browser contends for multiple resources: CPU and memory of course, but also its own queues of work between its internal services (in this article, the network service). </p> <p> This is why we’ve been focused on identifying and fixing <a href="https://web.dev/articles/inp">slow interactions</a> from Chrome users’ field data, which is the authoritative source when it comes to real user experiences. We gather this field data by recording anonymized Perfetto traces on Chrome Canary, and report them using a privacy-preserving filter. </p> <p> When looking at field data of slow interactions, one particular cause caught our attention: recurring synchronous calls to fetch the current site’s cookies from the network service. </p> <p> Let’s dive into some history. </p> <h3 style="text-align: left;"><b> Cookies under an evolving web </b></h3> <p> Cookies have been part of the web platform since the very beginning. They are commonly created like this: </p> <pre class="prettyprint"> document.cookie = "user=Alice;color=blue" </pre> <p> And later retrieved like this:<br /> </p> <pre class="prettyprint"> // Assuming a `getCookie` helper method: getCookie("user", document.cookie) </pre> <p> Its implementation was simple in single-process browsers, which kept the cookie jar in memory. </p> <p> Over time, browsers became multi-process, and the process hosting the cookie jar became responsible for answering more and more queries. Because the Web Spec requires Javascript to fetch cookies synchronously, however, answering each <code>document.cookie</code> query is a blocking operation. </p> <p> The operation itself is very fast, so this approach was generally fine, but under heavy load scenarios where multiple websites are requesting cookies (and other resources) from the network service, the queue of requests could get backed up. </p> <p> We discovered through field traces of slow interactions that some websites were triggering inefficient scenarios with cookies being fetched multiple times in a row. We landed additional metrics to measure how often a <code>GetCookieString()</code> IPC was redundant (same value returned as last time) across all navigations. We were astonished to discover that <strong>87% of cookie accesses were redundant</strong> and that, in some cases, this could happen hundreds of times per second. </p> <p> The simple design of <code>document.cookie </code>was backfiring as JavaScript on the web was using it like a local value when it was really a remote lookup. Was this a classic computer science case of caching?! Not so fast! </p> <p> The web spec allows collaborating domains to modify each other’s cookies. Hence, a simple cache per renderer process didn’t work, as it would have prevented writes from propagating between such sites (causing stale cookies and, for example, unsynchronized carts in ecommerce applications). </p> <h3 style="text-align: left;"> A new paradigm: Shared Memory Versioning </h3> <p> We solved this with a new paradigm which we called <a href="https://source.chromium.org/chromium/chromium/src/+/main:mojo/public/cpp/base/shared_memory_version.h">Shared Memory Versioning</a>. The idea is that each value of <code>document.cookie</code> is now paired with a monotonically increasing version. Each renderer caches its last read of <code>document.cookie</code> alongside that version. The network service hosts the version of each <code>document.cookie</code> in shared memory. Renderers can thus tell whether they have the latest version without having to send an inter-process query to the network service.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhl8OJ82Etmnlpmr2nRzeWSmYBk-2yRPAaDSrftFMxYp-hRkb8ZIxYzIMLG09c9iqHB-dD8UrLj3GaXio7rHjOOpLGY6YBmVYQaex21mqaTGFLSHJVMrUywbU13bvgNeVC0PxiT9sV3Wj33H0Rtr0rzOdHCJBzjQe1IGBjC-8uftmM_D5XBL0CoVMUPZMuU/s7748/Fast%20&%20Curious%20In-Line_Reduce%20cookies%20IPC_V2_HighRes.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="5251" data-original-width="7748" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhl8OJ82Etmnlpmr2nRzeWSmYBk-2yRPAaDSrftFMxYp-hRkb8ZIxYzIMLG09c9iqHB-dD8UrLj3GaXio7rHjOOpLGY6YBmVYQaex21mqaTGFLSHJVMrUywbU13bvgNeVC0PxiT9sV3Wj33H0Rtr0rzOdHCJBzjQe1IGBjC-8uftmM_D5XBL0CoVMUPZMuU/s16000/Fast%20&%20Curious%20In-Line_Reduce%20cookies%20IPC_V2_HighRes.png" /></a></div><br /><p style="text-align: center;"><br /></p><p>This reduced cookie-related inter-process messages by 80% and made <code>document.cookie</code> accesses 60% faster 🥳.</p> <h3 style="text-align: left;"> Hypothesis testing </h3> <p> Improving an algorithm is nice, but what we ultimately care about is whether that improvement results in improving slow interactions for users. In other words, we need to test the hypothesis that stalled cookie queries were a significant cause of slow interactions. </p> <p> To achieve this, we used Chrome’s A/B testing framework to study the effect and determined that it, combined with other improvements to reduce resource contention, improved the slowest interactions by approximately 5% on all platforms. This further resulted in more websites <a href="https://httparchive.org/reports/chrome-ux-report?start=2023_11_01&end=latest&view=list#cruxFastInp">passing Core Web Vitals</a> 🥳. All of this adds up to a more seamless web for users.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGnZvKinh7TK5YiwNx1HC6vzv5CCyKPJoRGhfRzZA0MlBLl-8ho5ciLI8WyFka6QcqmcRSWgMIjz-vsfsiLBWu-dYaZ7Df1j5Ow2YRB3PkQ-k7fjxsCcZ2oJpbjYKxK92pELqHWpcXw9PwaVn4wGSzgkIRj7DLMLZAAeEYkd8mYC8F4OOcJFiePTmsQp_G/s1176/Screenshot%202024-05-30%20at%2010.19.00%E2%80%AFAM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="552" data-original-width="1176" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGnZvKinh7TK5YiwNx1HC6vzv5CCyKPJoRGhfRzZA0MlBLl-8ho5ciLI8WyFka6QcqmcRSWgMIjz-vsfsiLBWu-dYaZ7Df1j5Ow2YRB3PkQ-k7fjxsCcZ2oJpbjYKxK92pELqHWpcXw9PwaVn4wGSzgkIRj7DLMLZAAeEYkd8mYC8F4OOcJFiePTmsQp_G/s16000/Screenshot%202024-05-30%20at%2010.19.00%E2%80%AFAM.png" /></a></div><br /><p style="text-align: center;"><br /></p><p><i><span style="font-size: x-small;">Timeline of the weighted average of the slowest interactions across the web on Chrome as this was released to 1% (Nov), 50% (Dec), and then all users (Feb).</span></i></p><div>Onward to a seamless web!</div> <p> <em>By Gabriel Charette, Olivier Li Shing Tat-Dupuis, Carlos Caballero Grolimund, and François Doray, from the Chrome engineering team</em> </p> <span itemprop='author' itemscope='itemscope' itemtype='http://schema.org/Person'> <meta content='https://plus.google.com/116899029375914044550' itemprop='url'/> </span> </script> <noscript> <p style="text-align: center;"></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgULbG_V-g8EZnGGU7HOmjeHhtXqsFS5cXno21FsN1uucnkTMdlq9tL9rOoZW7fx5vqp6_nW3R5Ib4JJZxMr9zD-MVIqLuCyy8N6ZheCW4iYkI7unu2GX7mMG2PVHNkNrykjbgi5PUwurzRSbd89DP6k1hGe7hze6EKVAzo4XKO8b3NfiO4PRsnHNwMKBDa/s400/Fast%20Curious_image.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="166" data-original-width="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgULbG_V-g8EZnGGU7HOmjeHhtXqsFS5cXno21FsN1uucnkTMdlq9tL9rOoZW7fx5vqp6_nW3R5Ib4JJZxMr9zD-MVIqLuCyy8N6ZheCW4iYkI7unu2GX7mMG2PVHNkNrykjbgi5PUwurzRSbd89DP6k1hGe7hze6EKVAzo4XKO8b3NfiO4PRsnHNwMKBDa/s16000/Fast%20Curious_image.png" /></a></div><br /><em><br /></em><p></p><p> <em>On the Chrome team, we believe it’s not sufficient to be fast most of the time, we have to be fast all of the time. Today’s The Fast and the Curious post explores how we contributed to Core Web Vitals by surveying the field data of Chrome responding to user interactions across all websites, ultimately improving performance of the web. </em> </p> <p> As billions of people turn to the web to get things done every day, the browser becomes more responsible for hosting a multitude of apps at once, resource contention becomes a challenge. The multi-process Chrome browser contends for multiple resources: CPU and memory of course, but also its own queues of work between its internal services (in this article, the network service). </p> <p> This is why we’ve been focused on identifying and fixing <a href="https://web.dev/articles/inp">slow interactions</a> from Chrome users’ field data, which is the authoritative source when it comes to real user experiences. We gather this field data by recording anonymized Perfetto traces on Chrome Canary, and report them using a privacy-preserving filter. </p> <p> When looking at field data of slow interactions, one particular cause caught our attention: recurring synchronous calls to fetch the current site’s cookies from the network service. </p> <p> Let’s dive into some history. </p> <h3 style="text-align: left;"><b> Cookies under an evolving web </b></h3> <p> Cookies have been part of the web platform since the very beginning. They are commonly created like this: </p> <pre class="prettyprint"> document.cookie = "user=Alice;color=blue" </pre> <p> And later retrieved like this:<br /> </p> <pre class="prettyprint"> // Assuming a `getCookie` helper method: getCookie("user", document.cookie) </pre> <p> Its implementation was simple in single-process browsers, which kept the cookie jar in memory. </p> <p> Over time, browsers became multi-process, and the process hosting the cookie jar became responsible for answering more and more queries. Because the Web Spec requires Javascript to fetch cookies synchronously, however, answering each <code>document.cookie</code> query is a blocking operation. </p> <p> The operation itself is very fast, so this approach was generally fine, but under heavy load scenarios where multiple websites are requesting cookies (and other resources) from the network service, the queue of requests could get backed up. </p> <p> We discovered through field traces of slow interactions that some websites were triggering inefficient scenarios with cookies being fetched multiple times in a row. We landed additional metrics to measure how often a <code>GetCookieString()</code> IPC was redundant (same value returned as last time) across all navigations. We were astonished to discover that <strong>87% of cookie accesses were redundant</strong> and that, in some cases, this could happen hundreds of times per second. </p> <p> The simple design of <code>document.cookie </code>was backfiring as JavaScript on the web was using it like a local value when it was really a remote lookup. Was this a classic computer science case of caching?! Not so fast! </p> <p> The web spec allows collaborating domains to modify each other’s cookies. Hence, a simple cache per renderer process didn’t work, as it would have prevented writes from propagating between such sites (causing stale cookies and, for example, unsynchronized carts in ecommerce applications). </p> <h3 style="text-align: left;"> A new paradigm: Shared Memory Versioning </h3> <p> We solved this with a new paradigm which we called <a href="https://source.chromium.org/chromium/chromium/src/+/main:mojo/public/cpp/base/shared_memory_version.h">Shared Memory Versioning</a>. The idea is that each value of <code>document.cookie</code> is now paired with a monotonically increasing version. Each renderer caches its last read of <code>document.cookie</code> alongside that version. The network service hosts the version of each <code>document.cookie</code> in shared memory. Renderers can thus tell whether they have the latest version without having to send an inter-process query to the network service.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhl8OJ82Etmnlpmr2nRzeWSmYBk-2yRPAaDSrftFMxYp-hRkb8ZIxYzIMLG09c9iqHB-dD8UrLj3GaXio7rHjOOpLGY6YBmVYQaex21mqaTGFLSHJVMrUywbU13bvgNeVC0PxiT9sV3Wj33H0Rtr0rzOdHCJBzjQe1IGBjC-8uftmM_D5XBL0CoVMUPZMuU/s7748/Fast%20&%20Curious%20In-Line_Reduce%20cookies%20IPC_V2_HighRes.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="5251" data-original-width="7748" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhl8OJ82Etmnlpmr2nRzeWSmYBk-2yRPAaDSrftFMxYp-hRkb8ZIxYzIMLG09c9iqHB-dD8UrLj3GaXio7rHjOOpLGY6YBmVYQaex21mqaTGFLSHJVMrUywbU13bvgNeVC0PxiT9sV3Wj33H0Rtr0rzOdHCJBzjQe1IGBjC-8uftmM_D5XBL0CoVMUPZMuU/s16000/Fast%20&%20Curious%20In-Line_Reduce%20cookies%20IPC_V2_HighRes.png" /></a></div><br /><p style="text-align: center;"><br /></p><p>This reduced cookie-related inter-process messages by 80% and made <code>document.cookie</code> accesses 60% faster 🥳.</p> <h3 style="text-align: left;"> Hypothesis testing </h3> <p> Improving an algorithm is nice, but what we ultimately care about is whether that improvement results in improving slow interactions for users. In other words, we need to test the hypothesis that stalled cookie queries were a significant cause of slow interactions. </p> <p> To achieve this, we used Chrome’s A/B testing framework to study the effect and determined that it, combined with other improvements to reduce resource contention, improved the slowest interactions by approximately 5% on all platforms. This further resulted in more websites <a href="https://httparchive.org/reports/chrome-ux-report?start=2023_11_01&end=latest&view=list#cruxFastInp">passing Core Web Vitals</a> 🥳. All of this adds up to a more seamless web for users.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGnZvKinh7TK5YiwNx1HC6vzv5CCyKPJoRGhfRzZA0MlBLl-8ho5ciLI8WyFka6QcqmcRSWgMIjz-vsfsiLBWu-dYaZ7Df1j5Ow2YRB3PkQ-k7fjxsCcZ2oJpbjYKxK92pELqHWpcXw9PwaVn4wGSzgkIRj7DLMLZAAeEYkd8mYC8F4OOcJFiePTmsQp_G/s1176/Screenshot%202024-05-30%20at%2010.19.00%E2%80%AFAM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="552" data-original-width="1176" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGnZvKinh7TK5YiwNx1HC6vzv5CCyKPJoRGhfRzZA0MlBLl-8ho5ciLI8WyFka6QcqmcRSWgMIjz-vsfsiLBWu-dYaZ7Df1j5Ow2YRB3PkQ-k7fjxsCcZ2oJpbjYKxK92pELqHWpcXw9PwaVn4wGSzgkIRj7DLMLZAAeEYkd8mYC8F4OOcJFiePTmsQp_G/s16000/Screenshot%202024-05-30%20at%2010.19.00%E2%80%AFAM.png" /></a></div><br /><p style="text-align: center;"><br /></p><p><i><span style="font-size: x-small;">Timeline of the weighted average of the slowest interactions across the web on Chrome as this was released to 1% (Nov), 50% (Dec), and then all users (Feb).</span></i></p><div>Onward to a seamless web!</div> <p> <em>By Gabriel Charette, Olivier Li Shing Tat-Dupuis, Carlos Caballero Grolimund, and François Doray, from the Chrome engineering team</em> </p> <span itemprop='author' itemscope='itemscope' itemtype='http://schema.org/Person'> <meta content='https://plus.google.com/116899029375914044550' itemprop='url'/> </span> </noscript> </div> </div> <div class='share'> <span class='twitter-custom social-wrapper' data-href='http://twitter.com/share?text=Chromium Blog:Introducing Shared Memory Versioning to improve slow interactions&url=https://blog.chromium.org/2024/06/introducing-shared-memory-versioning-to.html&via=ChromiumDev'> <img alt='Share on Twitter' height='24' src='https://www.gstatic.com/images/icons/material/system/2x/post_twitter_black_24dp.png' width='24'/> </span> <span class='fb-custom social-wrapper' data-href='https://www.facebook.com/sharer.php?u=https://blog.chromium.org/2024/06/introducing-shared-memory-versioning-to.html'> <img alt='Share on Facebook' height='24' src='https://www.gstatic.com/images/icons/material/system/2x/post_facebook_black_24dp.png' width='24'/> </span> </div> <div class='post-footer'> <div class='cmt_iframe_holder' data-href='https://blog.chromium.org/2024/06/introducing-shared-memory-versioning-to.html' data-viewtype='FILTERED_POSTMOD'></div> <a href='https://plus.google.com/112374322230920073195' rel='author' style='display:none;'> Google </a> <div class='label-footer'> <span class='labels-caption'> Labels: </span> <span class='labels'> <a class='label' href='https://blog.chromium.org/search/label/the%20fast%20and%20the%20curious' rel='tag'> the fast and the curious </a> </span> </div> </div> </div> <div class='post' data-id='5329985167455533255' itemscope='' itemtype='http://schema.org/BlogPosting'> <h2 class='title' itemprop='name'> <a href='https://blog.chromium.org/2024/03/speedometer-3-building-benchmark-that.html' itemprop='url' title='Speedometer 3: Building a benchmark that represents the web'> Speedometer 3: Building a benchmark that represents the web </a> </h2> <div class='post-header'> <div class='published'> <span class='publishdate' itemprop='datePublished'> Monday, March 11, 2024 </span> </div> </div> <div class='post-body'> <div class='post-content' itemprop='articleBody'> <script type='text/template'> <p style="text-align: center;"></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiwhyphenhypheng0_39U6yzt-pOO8aVmKnuz6fn2Nk2Vx5Rs-ypGPUDRiOG4v8ItqlD_WLSRfku6utJy6luWI5iDOtwEor5v69en_XiWU-akxtTmCgR8Mm-6NfjW6weeEoXT6msXLmbxGzJ8ZvzKKOEjOv0SZH-RhXHKdHG7I_6TmE5hJq5VFSrXyUV5d8K7zE0KLYJg/s564/The%20Fast%20+%20The%20Curious%20Logo_Revised_Header.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="234" data-original-width="564" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiwhyphenhypheng0_39U6yzt-pOO8aVmKnuz6fn2Nk2Vx5Rs-ypGPUDRiOG4v8ItqlD_WLSRfku6utJy6luWI5iDOtwEor5v69en_XiWU-akxtTmCgR8Mm-6NfjW6weeEoXT6msXLmbxGzJ8ZvzKKOEjOv0SZH-RhXHKdHG7I_6TmE5hJq5VFSrXyUV5d8K7zE0KLYJg/s16000/The%20Fast%20+%20The%20Curious%20Logo_Revised_Header.jpg" /></a></div><br /><div class="separator" style="clear: both; text-align: center;"><br /></div><p></p><p> <em>Today’s The Fast and the Curious post covers the <a href="https://browserbench.org/announcements/speedometer3/">release</a> of Speedometer 3.0 an upgraded browser benchmarking tool to optimize the performance of Web applications. </em> </p> <p> In collaboration with major web browser engines, Blink/V8, Gecko/SpiderMonkey, and WebKit/JavaScriptCore, we’re excited to release <a href="https://browserbench.org/Speedometer3.0/">Speedometer 3.0</a>. Benchmarks, like Speedometer, are tools that can help browser vendors find opportunities to improve performance. Ideally, they simulate functionality that users encounter on typical websites, to ensure browsers can optimize areas that are beneficial to users. </p> <p> Let’s dig into the new changes in Speedometer 3.0. </p> <h3 style="text-align: left;"><strong>Applying a multi-stakeholder governance model</strong></h3> <p> Since its initial release in <a href="https://webkit.org/blog/3395/speedometer-benchmark-for-web-app-responsiveness/">2014</a> by the WebKit team, browser vendors have successfully used Speedometer to optimize their engines and improve user experiences on the web. Speedometer 2.0, a result of a collaboration between Apple and Chrome, followed in <a href="https://webkit.org/blog/8063/speedometer-2-0-a-benchmark-for-modern-web-app-responsiveness/">2018</a>, and it included an updated set of workloads that were more representative of the modern web at that time. </p> <p> The web has changed a lot since 2018, and so has Speedometer in its latest release, Speedometer 3. This work has been based on a joint <a href="https://github.com/WebKit/Speedometer/blob/main/Governance.md">multi-stakeholder governance model</a> to share work, and build a collaborative understanding of performance on the web to help drive browser performance in ways that help users. The goal of this collaborative project is to create a shared understanding of web performance so that improvements can be made to enhance the user experience. Together, we were able to to improve how Speedometer captures and calculates scores, show more detailed results and introduce an even wider variety of workloads. This cross-browser collaboration introduced more diverse perspectives that enabled clearer insights into a broader set of web users and workflows, ensuring the newest version of Speedometer will help make the web better for everyone, regardless of which browser they use. </p> <h3 style="text-align: left;"><strong>Why is building workloads challenging?</strong></h3> <p> Building a reliable benchmark with representative tests and workloads is challenging enough. That task becomes even more challenging if it will be used as a tool to guide optimization of browser engines over multiple years. To develop the Speedometer 3 benchmark, the <a href="https://developer.chrome.com/aurora">Chrome Aurora</a> team, together with colleagues from other participating browser vendors, were tasked with finding new workloads that accurately reflect what users experience across the vast, diverse and eclectic web of 2024 and beyond. </p> <p> A few tests and workloads can’t simulate the entire web, but while building Speedometer 3 we have established some criteria for selecting ones that are critical to user’s experience. We are now closer to a representative benchmark than ever before. Let’s take a look at how Speedometer workloads evolved </p> <h3 style="text-align: left;"><strong>How did the workloads change?</strong></h3> <p> Since the goal is to use workloads that are representative of the web today, we needed to take a look at the previous workloads used in Speedometer and determine what changes were necessary. We needed to decide which frameworks are still relevant, which apps needed updating and what types of work we didn’t capture in previous versions. In Speedometer 2, all workloads were variations of a todo app implemented in different JS frameworks. We found that, as the web evolved over the past six years, we missed out on various JavaScript and Browser APIs that became popular, and apps tend to be much larger and more complicated than before. As a result, we made changes to the list of frameworks we included and we added a wider variety of workloads that cover a broader range of APIs and features. </p> <h3 style="text-align: left;"><strong>Frameworks</strong></h3> <p> To determine which frameworks to include, we used data from <a href="https://httparchive.org/">HTTP Archive</a> and discussed inclusion with all browser vendors to ensure we cover a good range of implementations. For the initial evaluation, we took a snapshot of the HTTP Archive from March 2023 to determine the top JavaScript UI frameworks currently used to build complex web apps. </p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNL-3EGN3NyWERFEqb-GnA5UnYi_lDkyp1siFYN5X0qj6qAQWpMcwrC7_3Q0PQPeQCsbQf06FDp6e_RaNB-U6nvnf1JxljO1nUeZxSSAoqmyu2-9VNGP1QjNx6krI8W7EhdmDHyg8_kvzPm7Vf0Xjo1uPKl84R-mrDwXqbY1xf0EkMSHvtu2mcMwGCgxZ7/s1932/1Chrome_Fast%20&%20Curious_Blog%20Assets_Speedometer%203.0_v2_Pages%20vs.%20Framework.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1351" data-original-width="1932" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNL-3EGN3NyWERFEqb-GnA5UnYi_lDkyp1siFYN5X0qj6qAQWpMcwrC7_3Q0PQPeQCsbQf06FDp6e_RaNB-U6nvnf1JxljO1nUeZxSSAoqmyu2-9VNGP1QjNx6krI8W7EhdmDHyg8_kvzPm7Vf0Xjo1uPKl84R-mrDwXqbY1xf0EkMSHvtu2mcMwGCgxZ7/s16000/1Chrome_Fast%20&%20Curious_Blog%20Assets_Speedometer%203.0_v2_Pages%20vs.%20Framework.png" /></a></div><br /><p style="text-align: center;"><br /></p> <p> Another approach is to determine inclusion based on popularity with developers: Do we need to include frameworks that have “momentum”, where a framework's current usage in production might be low, but we anticipate growth in adoption? This is somewhat hard to determine and might not be the ideal sole indicator for inclusion. One data point to evaluate momentum might be monthly NPM downloads of frameworks. </p> <p> Here are the same 15 frameworks NPM downloads for March 2023: </p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhh9SdoPfDPz-wjCUTknvTaTq4D3pRTUDocU7BoUF-y8iePqktwFxZXUgkAkeWF4gG8kJIIXSTJL_-ugHzrW8LnsyFdlCCEz_MleUtADMnyhU6Nlztk_RPw2J9t7dWTtzIad2eB3U9IGOMXMyb-QB4j_26bmL77oUIThz3Otp5FBSPXmn_rG8bumjBpuTj1/s1932/2Chrome_Fast%20&%20Curious_Blog%20Assets_Speedometer%203.0_Downloads%20vs.%20Framework.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1360" data-original-width="1932" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhh9SdoPfDPz-wjCUTknvTaTq4D3pRTUDocU7BoUF-y8iePqktwFxZXUgkAkeWF4gG8kJIIXSTJL_-ugHzrW8LnsyFdlCCEz_MleUtADMnyhU6Nlztk_RPw2J9t7dWTtzIad2eB3U9IGOMXMyb-QB4j_26bmL77oUIThz3Otp5FBSPXmn_rG8bumjBpuTj1/s16000/2Chrome_Fast%20&%20Curious_Blog%20Assets_Speedometer%203.0_Downloads%20vs.%20Framework.png" /></a></div><br /><p style="text-align: center;"><br /></p> <p> With both data points on hand, we decided on a list that we felt gives us a good representation of frameworks. We kept the list small to allow space for brand new types of workloads, instead of just todo apps. We also selected commonly used versions for each framework, based on the current usage. </p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWIjTao8HfxmLG3VNzDgwfcu4tHvdY1-Yu1CZxqnmHliA8LjkN4DbQy0uZDeSsdh11c7T53rQruwMoDyfqqcIgXgraNmmZ2rCjDJVCgbm0K4EP087sbjIb2utmxI8xN1OiJ7XG4L7NTYFdcg_DL2S_-kqU5Om46C6vX5dzvXiM8Kw-LJX247jB05iNZprj/s1932/3Chrome_Fast%20&%20Curious_Blog%20Assets_Speedometer%203.0_Commonly%20Used%20Versions.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1037" data-original-width="1932" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWIjTao8HfxmLG3VNzDgwfcu4tHvdY1-Yu1CZxqnmHliA8LjkN4DbQy0uZDeSsdh11c7T53rQruwMoDyfqqcIgXgraNmmZ2rCjDJVCgbm0K4EP087sbjIb2utmxI8xN1OiJ7XG4L7NTYFdcg_DL2S_-kqU5Om46C6vX5dzvXiM8Kw-LJX247jB05iNZprj/s16000/3Chrome_Fast%20&%20Curious_Blog%20Assets_Speedometer%203.0_Commonly%20Used%20Versions.png" /></a></div><br /><p style="text-align: center;"><br /></p> <p> In addition, we updated the previous JavaScript implementations and included a new web-component based version, implemented with vanilla JavaScript. </p> <h3 style="text-align: left;"><strong>More Workloads</strong></h3> <p> A simple Todo-list only tests a subset of functionality. For example: how well do browsers handle complicated flexbox and grid layouts? How can we capture SVG and canvas rendering and how can we include more realistic scenarios that happen on a website? </p> <p> We collected and categorized areas of interest into DOM, layout, API and patterns, to be able to match them to potential workloads that would allow us to test these areas. In addition we collected user journeys that included the different categories of interest: editing text, rendering charts, navigating a site, and so on. </p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvvQUbw7sWXJeFdASbV66Nn0mJxLkJtevbcCoy1UhZ9IRQj8tkHg657V31yKBiPd8T71ArAQmSedl9NeoqczYvv49MciBUuyfSg5-zyIOIrae807_5N3hzemRyQuTTHYsTiGZ7qV4ARPrQEO7vWIm9-R3kCaKpQcwRsxYr3NkqProgY-8mSe5PjHUNbSf-/s1932/4Chrome_Fast%20&%20Curious_Blog%20Assets_Speedometer%203.0_More%20Workloads.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1321" data-original-width="1932" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvvQUbw7sWXJeFdASbV66Nn0mJxLkJtevbcCoy1UhZ9IRQj8tkHg657V31yKBiPd8T71ArAQmSedl9NeoqczYvv49MciBUuyfSg5-zyIOIrae807_5N3hzemRyQuTTHYsTiGZ7qV4ARPrQEO7vWIm9-R3kCaKpQcwRsxYr3NkqProgY-8mSe5PjHUNbSf-/s16000/4Chrome_Fast%20&%20Curious_Blog%20Assets_Speedometer%203.0_More%20Workloads.png" /></a></div><br /><p style="text-align: center;"><br /></p> <p> There are many more areas that we weren’t able to include, but the final list of workloads presents a larger variety and we hope that future versions of Speedometer will build upon the current list. </p> <h3 style="text-align: left;"><strong>Validation</strong></h3> <p> The Chrome Aurora team worked with the <a href="https://v8.dev/">Chrome V8 team</a> to validate our assumptions above. In Chrome, we can use <a href="https://v8.dev/docs/rcs">runtime-call-stats</a> to measure time spent in each web API (and additionally many internal components). This allows us to get an insight into how dominant certain APIs are. </p> <p> If we look at Speedometer 2.1 we see that a disproportionate amount of benchmark time is spent in innerHTML. </p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiyW_hT0-7IEsnU0vMSGYepKt3W9atMq1rHRw0hKyQ_8zLozWyM0yILERSynI5j5F4rWM5ZKRaWPgaSanJxzwBZD0aqt_wye9p1yQmOzZaOF7cEXRPeMLTF-MhWJorfg-Q9QEAkP6Y1DKVM5AFUieQoP94Y18TyAWb8g-a3sdz_Tgxk-DMMqs_O7CwI03HA/s1932/5Chrome_Fast%20&%20Curious_Blog%20Assets_Speedometer%203.0_v2_Speedometer%202.1%20Chrome%20API%20Usage.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1328" data-original-width="1932" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiyW_hT0-7IEsnU0vMSGYepKt3W9atMq1rHRw0hKyQ_8zLozWyM0yILERSynI5j5F4rWM5ZKRaWPgaSanJxzwBZD0aqt_wye9p1yQmOzZaOF7cEXRPeMLTF-MhWJorfg-Q9QEAkP6Y1DKVM5AFUieQoP94Y18TyAWb8g-a3sdz_Tgxk-DMMqs_O7CwI03HA/s16000/5Chrome_Fast%20&%20Curious_Blog%20Assets_Speedometer%203.0_v2_Speedometer%202.1%20Chrome%20API%20Usage.png" /></a></div><br /><p style="text-align: center;"><br /></p> <p> While <a href="http://go/mdn/API/Element/innerHTML">innerHTML</a> is an important web API, it's overrepresented in Speedometer 2.1. Doing the same analysis on the new version 3.0 yields a slightly different picture: </p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgEdKNUJzhrWhWY8AHHiZYGfTLsF-crQZKcvAGhD_RtAfD0fsRDGuufFew8kCUccNrhcyF17K_cEvyR38nFx2_CgS9ZIE2Z2afe4DXCg6Rou8n_J3iY8Jq0A8lUo0TlzAG5AOmstNzaraw_47S8r_TzS9ZYX4t1Mqf5Wpe3QRissuDEhabmzk_q_7lEmVE3/s1932/6Chrome_Fast%20&%20Curious_Blog%20Assets_Speedometer%203.0_Speedometer%203.0%20Chrome%20API%20Usage.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1404" data-original-width="1932" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgEdKNUJzhrWhWY8AHHiZYGfTLsF-crQZKcvAGhD_RtAfD0fsRDGuufFew8kCUccNrhcyF17K_cEvyR38nFx2_CgS9ZIE2Z2afe4DXCg6Rou8n_J3iY8Jq0A8lUo0TlzAG5AOmstNzaraw_47S8r_TzS9ZYX4t1Mqf5Wpe3QRissuDEhabmzk_q_7lEmVE3/s16000/6Chrome_Fast%20&%20Curious_Blog%20Assets_Speedometer%203.0_Speedometer%203.0%20Chrome%20API%20Usage.png" /></a></div><br /><p style="text-align: center;"><br /></p> <p> We can see that innerHTML is still present, but its overall contribution shrunk from roughly 14% down to 4.5%. As a result, we get a better distribution that favors more DOM APIs to be optimized. We can also see that a few Canvas APIs have moved into this list, thanks to the new workloads in v3.0. </p> <p> While we will never be able to perfectly represent the whole web in a fast-running and stable benchmark, it is clear that Speedometer 3.0 is a giant step in the right direction. </p> <p> Ultimately, we ended up with the following list of workloads presented in the next few sections. </p> <h3 style="text-align: left;"><strong>What workloads are included?</strong></h3> <p> <strong><em>TodoMVC</em></strong> </p> <p> Many developers might recognize the <a href="https://todomvc.com/">TodoMVC app</a>. It’s a popular resource for learning and offers a wide range of TodoMVC implementations with different frameworks. </p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi3uqFby4YGbOdvIEo3mgb6EjFO4q9OtRNagMiDOEcTzVFyzrMeJCKoab-U4fyKVQr7rfbfTzTgCmbNxgy84pl3-bfvsfVmC6mqBYcxNB739yNTlYORwySDsKmNRIjdjwivLcpI6iG6CzGOz7x2Gy0gq1LIgRCgIJi2neq1nQWfo0G07plVTRF3E6nGs_2q/s842/1TodoMVC.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="706" data-original-width="842" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi3uqFby4YGbOdvIEo3mgb6EjFO4q9OtRNagMiDOEcTzVFyzrMeJCKoab-U4fyKVQr7rfbfTzTgCmbNxgy84pl3-bfvsfVmC6mqBYcxNB739yNTlYORwySDsKmNRIjdjwivLcpI6iG6CzGOz7x2Gy0gq1LIgRCgIJi2neq1nQWfo0G07plVTRF3E6nGs_2q/s16000/1TodoMVC.png" /></a></div><br /><p style="text-align: center;"><br /></p> <p> TodoMVC is a to-do application that allows a user to keep track of tasks. The user can enter a new task, update an existing one, mark a task as completed, or delete it. In addition to the basic CRUD operations, the TodoMVC app has some added functionality: filters are available to change the view to “all”, “active” or “completed” tasks and a status text displays the number of active tasks to complete. </p> <p> In Speedometer, we introduced a local data source for todo items, which we use in our tests to populate the todo apps. This gave us the opportunity to test a larger character set with different languages. </p> <p> The tests for these apps are all similar and are relatable to typical user journeys with a todo app: </p> <ol> <li>Add a task </li><li>Mark task as complete </li><li>Delete task </li><li>Repeat steps 1-3 a set amount of times </li> </ol> <p> These tests seem simple, but it lets us benchmark DOM manipulations. Having a variety of framework implementations also cover several different ways how this can be done. </p> <p> <strong><em>Complex DOM / TodoMVC</em></strong> </p> <p> The complex DOM workloads embed various TodoMVC implementations in a static UI shell that mimics a complex web page. The idea is to capture the performance impact on executing seemingly isolated actions (e.g. adding/deleting todo items) in the context of a complex website. Small performance hits that aren’t obvious in an isolated TodoMVC workload are amplified in a larger application and therefore capture more real-world impact. </p> <p> The tests are similar to the TodoMVC tests, executed in the complex DOM & CSSOM environment. </p> <p> This introduces an additional layer of complexity that browsers have to be able to handle effortlessly. </p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEigyFShRHZAVX8SzN0eRf1XyOPAwT1563BKuuzaOYSlG8-rVaeSqGj88DFM3bsiJmveZ5z-XB-2jaZp8Exz6NTvf1wQbN1vmouCnSbMV8QtXbWpsbbAhEFQOk0zuhTxOkUfbcDadVy6nbQ7HhjgsmQEghoO_v3v8FMnsCB7ZWWzk8YsZXeXZbD8zWbItd33/s822/2Complex%20DOM%20%20TodoMVC.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="694" data-original-width="822" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEigyFShRHZAVX8SzN0eRf1XyOPAwT1563BKuuzaOYSlG8-rVaeSqGj88DFM3bsiJmveZ5z-XB-2jaZp8Exz6NTvf1wQbN1vmouCnSbMV8QtXbWpsbbAhEFQOk0zuhTxOkUfbcDadVy6nbQ7HhjgsmQEghoO_v3v8FMnsCB7ZWWzk8YsZXeXZbD8zWbItd33/s16000/2Complex%20DOM%20%20TodoMVC.png" /></a></div><br /><p style="text-align: center;"><br /></p> <p> <strong><em>Single-page-applications (News Site)</em></strong> </p> <p> Single-page-applications (SPAs) are widely used on the web for streaming, gaming, social media and pretty much anything you can imagine. A SPA lets us capture navigating between pages and interacting with an app. We chose a news site to represent a SPA, since it allows us to capture the main areas of interest in a deterministic way. An important factor was that we want to ensure we are using static local data and that the app doesn’t rely on network requests to present this data to the user. </p> <p> Two implementations are included: one built with Next.js and the other with Nuxt. This gave us the opportunity to represent applications built with meta frameworks, with the caveat that we needed to ensure to use static outputs. </p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgeu13O9BevycHTsDVrYPsWvaM3lJEKPPUz9Ket2PmQLQE3pOpYTE_YNv85egpLFAqW3_5f0c-fHclB283uH7Xh8bTJsxMeFu9ArDW892iBSFNVTrVhqKLw4JN23XrW-zH8BnIdvND1SbC9am0kF16t4DjPuSOoOoF5qqprsyFHiMNOINqpNWZTXsQWtQAE/s826/3Single-page-applications%20(News%20Site).png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="690" data-original-width="826" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgeu13O9BevycHTsDVrYPsWvaM3lJEKPPUz9Ket2PmQLQE3pOpYTE_YNv85egpLFAqW3_5f0c-fHclB283uH7Xh8bTJsxMeFu9ArDW892iBSFNVTrVhqKLw4JN23XrW-zH8BnIdvND1SbC9am0kF16t4DjPuSOoOoF5qqprsyFHiMNOINqpNWZTXsQWtQAE/s16000/3Single-page-applications%20(News%20Site).png" /></a></div><br /><p style="text-align: center;"><br /></p> <p> Tests for the news site mimic a typical user journey, by selecting a menu item and navigating to another section of the site. </p> <ol> <li>Click on ‘More’ toggle of the navigation </li><li>Click on a navigation button </li><li>Repeat steps 1 and 2 a set amount of times </li> </ol> <p> These tests let us evaluate how well a browser can handle large DOM and CSSOM changes, by changing a large amount of data that needs to be displayed when navigating to a different page. </p> <p> <strong><em>Charting Apps & Dashboards</em></strong> </p> <p> Charting apps allow us to test SVG and canvas rendering by displaying charts in various workloads. </p> <p> These apps represent popular sites that display financial information, stock charts or dashboards. </p> <p> Both SVG rendering and the use of the canvas api weren’t represented in previous releases of Speedometer. </p> <p> <strong>Observable Plot</strong> displays a stacked bar chart, as well as a dotted chart. It is based on D3, which is a JavaScript library for visualizing tabular data and outputs SVG elements. It loops through a big dataset to build the source data that D3 needs, using map, filter and flatMap methods. As a result this exercises creation and copying of objects and arrays. </p> <p> <strong>Chart.js</strong> is a JavaScript charting library. The included workload displays a scatter graph with the canvas api, both with some transparency and with full opacity. This uses the same data as the previous workload, but with a different preparation phase. In this case it makes a heavy use of trigonometry to compute distances between airports. </p> <p> <strong>React Stockcharts</strong> displays a dashboard for stocks. It is based on D3 for all computation, but outputs SVG directly using React. </p> <p> <strong>Webkit Perf-Dashboard</strong> is an application used to track various performance metrics of WebKit. The dashboard uses canvas drawing and web components for its ui. </p> <p> These workloads test DOM manipulation with SVG or canvas by interacting with charts. For example here are the interactions of the Observable Plot workload:<br /> </p> <ol> <li>Prepare data: compute the input datasets to output structures that D3 understands. </li><li>Add stacked chart: this draws a chart using SVG elements. </li><li>Change input slider to change the computation parameters. </li><li>Repeat steps 1 and 2 </li><li>Reset: this clears the view </li><li>Add dotted chart: this draws another type of graph (dots instead of bars) to exercise different drawing primitives. This also uses a power scale.</li> </ol><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi1QH4eW4eb6BhbRSvNOkbrq9HXwSWc53aNbMKuxv5I5Sw2LzMiN5BMVqAwo6GCag4VGThAy9jifHBmc2yVRDxwNFuJo6C-jymDoTfpZqzcmFNOrtWUsHfbUxeQ0cjixXh7WRajjHdj-V_dK-FrQxCEEV5XXDzgKp7Q3xiHrTc9LJcgDaO9Ryg4_KnsYKhN/s846/4Webkit%20Perf-Dashboard_1.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="706" data-original-width="846" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi1QH4eW4eb6BhbRSvNOkbrq9HXwSWc53aNbMKuxv5I5Sw2LzMiN5BMVqAwo6GCag4VGThAy9jifHBmc2yVRDxwNFuJo6C-jymDoTfpZqzcmFNOrtWUsHfbUxeQ0cjixXh7WRajjHdj-V_dK-FrQxCEEV5XXDzgKp7Q3xiHrTc9LJcgDaO9Ryg4_KnsYKhN/s16000/4Webkit%20Perf-Dashboard_1.png" /></a></div><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg7BWgJu6HvFqDwADBq9Q0GblZFHIJpp052nYZM0CgRfQbbsAp-VTN8Xpy1o1XbYhIqUKoGg4uELeo6Un2NHFul2qaAzL99Y7vxJqASK8uMXDD8GyX2jIFIAiBl36suwaHO5hGUmvxQMt09mX38Oh5R8hOXckFneevSpQlChMu5qQmcUiKIqoaAQiCxNjrB/s822/5Webkit%20Perf-Dashboard_2.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="696" data-original-width="822" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg7BWgJu6HvFqDwADBq9Q0GblZFHIJpp052nYZM0CgRfQbbsAp-VTN8Xpy1o1XbYhIqUKoGg4uELeo6Un2NHFul2qaAzL99Y7vxJqASK8uMXDD8GyX2jIFIAiBl36suwaHO5hGUmvxQMt09mX38Oh5R8hOXckFneevSpQlChMu5qQmcUiKIqoaAQiCxNjrB/s16000/5Webkit%20Perf-Dashboard_2.png" /></a></div><br /><div style="text-align: center;"><br /></div> <p> <strong><em>Code Editors</em></strong> </p> <p> Editors, for example WYSIWYG text and code editors, let us focus on editing live text and capturing form interactions. Typical scenarios are writing an email, logging into a website or filling out an online form. Although there is some form interaction present in the TodoMVC apps, the editor workloads use a large data set, which lets us evaluate performance more accurately. </p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiHb9rJqJXZ95LXsDjo8Zd1l2TciE1uFZ5eolDJf3euB5P7C8KwJ27vB-xlCic8R7CHNy7Qxuea9zuCsqbdJ4k6safN5Z7oA6KadxbzYEus6TRmVV0cHZLcJedupQb6R-0DB4YpMagfvjviPhxGfWAIDmxzJ7jBXGzjALxeMmxuEoTACaNMIrDqEnoAMwXA/s846/6Code%20Editors.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="708" data-original-width="846" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiHb9rJqJXZ95LXsDjo8Zd1l2TciE1uFZ5eolDJf3euB5P7C8KwJ27vB-xlCic8R7CHNy7Qxuea9zuCsqbdJ4k6safN5Z7oA6KadxbzYEus6TRmVV0cHZLcJedupQb6R-0DB4YpMagfvjviPhxGfWAIDmxzJ7jBXGzjALxeMmxuEoTACaNMIrDqEnoAMwXA/s16000/6Code%20Editors.png" /></a></div><br /><p style="text-align: center;"><br /></p> <p> <strong>Codemirror</strong> is a code editor that implements a text input field with support for many editing features. Several languages and frameworks are available and for this workload we used the JavaScript library from Codemirror. </p> <p> <strong>Tiptap</strong> Editor is a headless, framework-agnostic rich text editor that's customizable and extendable. This workload used Tiptap as its basis and added a simple ui to interact with. </p> <p> Both apps test DOM insertion and manipulation of a large amount of data in the following way: </p> <ol> <li>Create an editable element. </li><li>Insert a long text.: Codemirror uses the development bundle of React, whileTipTap loads an excerpt of Proust’s Du Côté de Chez Swann. </li><li>Highlight text: Codemirror turns on syntax highlighting, while TipTap sets all the text to bold. </li> </ol> <h3 style="text-align: left;"><strong>Parting words</strong></h3> <p> Being able to collaborate with all major browser vendors and having all of us contribute to workloads has been a unique experience and we are looking forward to continuing to collaborate in the browser benchmarking space. </p> <p> Don’t forget to check out the new release of Speedometer and test it out in your favorite browser, dig into the results, check out our repo and feel free to open issues with any improvements or ideas for workloads you would like to see included in the next version. We are aiming for a more frequent release schedule in the future and if you are a framework author and want to contribute, feel free to file an issue on our <a href="https://github.com/WebKit/Speedometer/issues">Github</a> to start the discussion. </p> <p> <em><span style="font-size: x-small;">Posted by Thorsten Kober, Chrome Aurora</span></em> </p> <span itemprop='author' itemscope='itemscope' itemtype='http://schema.org/Person'> <meta content='https://plus.google.com/116899029375914044550' itemprop='url'/> </span> </script> <noscript> <p style="text-align: center;"></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiwhyphenhypheng0_39U6yzt-pOO8aVmKnuz6fn2Nk2Vx5Rs-ypGPUDRiOG4v8ItqlD_WLSRfku6utJy6luWI5iDOtwEor5v69en_XiWU-akxtTmCgR8Mm-6NfjW6weeEoXT6msXLmbxGzJ8ZvzKKOEjOv0SZH-RhXHKdHG7I_6TmE5hJq5VFSrXyUV5d8K7zE0KLYJg/s564/The%20Fast%20+%20The%20Curious%20Logo_Revised_Header.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="234" data-original-width="564" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiwhyphenhypheng0_39U6yzt-pOO8aVmKnuz6fn2Nk2Vx5Rs-ypGPUDRiOG4v8ItqlD_WLSRfku6utJy6luWI5iDOtwEor5v69en_XiWU-akxtTmCgR8Mm-6NfjW6weeEoXT6msXLmbxGzJ8ZvzKKOEjOv0SZH-RhXHKdHG7I_6TmE5hJq5VFSrXyUV5d8K7zE0KLYJg/s16000/The%20Fast%20+%20The%20Curious%20Logo_Revised_Header.jpg" /></a></div><br /><div class="separator" style="clear: both; text-align: center;"><br /></div><p></p><p> <em>Today’s The Fast and the Curious post covers the <a href="https://browserbench.org/announcements/speedometer3/">release</a> of Speedometer 3.0 an upgraded browser benchmarking tool to optimize the performance of Web applications. </em> </p> <p> In collaboration with major web browser engines, Blink/V8, Gecko/SpiderMonkey, and WebKit/JavaScriptCore, we’re excited to release <a href="https://browserbench.org/Speedometer3.0/">Speedometer 3.0</a>. Benchmarks, like Speedometer, are tools that can help browser vendors find opportunities to improve performance. Ideally, they simulate functionality that users encounter on typical websites, to ensure browsers can optimize areas that are beneficial to users. </p> <p> Let’s dig into the new changes in Speedometer 3.0. </p> <h3 style="text-align: left;"><strong>Applying a multi-stakeholder governance model</strong></h3> <p> Since its initial release in <a href="https://webkit.org/blog/3395/speedometer-benchmark-for-web-app-responsiveness/">2014</a> by the WebKit team, browser vendors have successfully used Speedometer to optimize their engines and improve user experiences on the web. Speedometer 2.0, a result of a collaboration between Apple and Chrome, followed in <a href="https://webkit.org/blog/8063/speedometer-2-0-a-benchmark-for-modern-web-app-responsiveness/">2018</a>, and it included an updated set of workloads that were more representative of the modern web at that time. </p> <p> The web has changed a lot since 2018, and so has Speedometer in its latest release, Speedometer 3. This work has been based on a joint <a href="https://github.com/WebKit/Speedometer/blob/main/Governance.md">multi-stakeholder governance model</a> to share work, and build a collaborative understanding of performance on the web to help drive browser performance in ways that help users. The goal of this collaborative project is to create a shared understanding of web performance so that improvements can be made to enhance the user experience. Together, we were able to to improve how Speedometer captures and calculates scores, show more detailed results and introduce an even wider variety of workloads. This cross-browser collaboration introduced more diverse perspectives that enabled clearer insights into a broader set of web users and workflows, ensuring the newest version of Speedometer will help make the web better for everyone, regardless of which browser they use. </p> <h3 style="text-align: left;"><strong>Why is building workloads challenging?</strong></h3> <p> Building a reliable benchmark with representative tests and workloads is challenging enough. That task becomes even more challenging if it will be used as a tool to guide optimization of browser engines over multiple years. To develop the Speedometer 3 benchmark, the <a href="https://developer.chrome.com/aurora">Chrome Aurora</a> team, together with colleagues from other participating browser vendors, were tasked with finding new workloads that accurately reflect what users experience across the vast, diverse and eclectic web of 2024 and beyond. </p> <p> A few tests and workloads can’t simulate the entire web, but while building Speedometer 3 we have established some criteria for selecting ones that are critical to user’s experience. We are now closer to a representative benchmark than ever before. Let’s take a look at how Speedometer workloads evolved </p> <h3 style="text-align: left;"><strong>How did the workloads change?</strong></h3> <p> Since the goal is to use workloads that are representative of the web today, we needed to take a look at the previous workloads used in Speedometer and determine what changes were necessary. We needed to decide which frameworks are still relevant, which apps needed updating and what types of work we didn’t capture in previous versions. In Speedometer 2, all workloads were variations of a todo app implemented in different JS frameworks. We found that, as the web evolved over the past six years, we missed out on various JavaScript and Browser APIs that became popular, and apps tend to be much larger and more complicated than before. As a result, we made changes to the list of frameworks we included and we added a wider variety of workloads that cover a broader range of APIs and features. </p> <h3 style="text-align: left;"><strong>Frameworks</strong></h3> <p> To determine which frameworks to include, we used data from <a href="https://httparchive.org/">HTTP Archive</a> and discussed inclusion with all browser vendors to ensure we cover a good range of implementations. For the initial evaluation, we took a snapshot of the HTTP Archive from March 2023 to determine the top JavaScript UI frameworks currently used to build complex web apps. </p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNL-3EGN3NyWERFEqb-GnA5UnYi_lDkyp1siFYN5X0qj6qAQWpMcwrC7_3Q0PQPeQCsbQf06FDp6e_RaNB-U6nvnf1JxljO1nUeZxSSAoqmyu2-9VNGP1QjNx6krI8W7EhdmDHyg8_kvzPm7Vf0Xjo1uPKl84R-mrDwXqbY1xf0EkMSHvtu2mcMwGCgxZ7/s1932/1Chrome_Fast%20&%20Curious_Blog%20Assets_Speedometer%203.0_v2_Pages%20vs.%20Framework.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1351" data-original-width="1932" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNL-3EGN3NyWERFEqb-GnA5UnYi_lDkyp1siFYN5X0qj6qAQWpMcwrC7_3Q0PQPeQCsbQf06FDp6e_RaNB-U6nvnf1JxljO1nUeZxSSAoqmyu2-9VNGP1QjNx6krI8W7EhdmDHyg8_kvzPm7Vf0Xjo1uPKl84R-mrDwXqbY1xf0EkMSHvtu2mcMwGCgxZ7/s16000/1Chrome_Fast%20&%20Curious_Blog%20Assets_Speedometer%203.0_v2_Pages%20vs.%20Framework.png" /></a></div><br /><p style="text-align: center;"><br /></p> <p> Another approach is to determine inclusion based on popularity with developers: Do we need to include frameworks that have “momentum”, where a framework's current usage in production might be low, but we anticipate growth in adoption? This is somewhat hard to determine and might not be the ideal sole indicator for inclusion. One data point to evaluate momentum might be monthly NPM downloads of frameworks. </p> <p> Here are the same 15 frameworks NPM downloads for March 2023: </p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhh9SdoPfDPz-wjCUTknvTaTq4D3pRTUDocU7BoUF-y8iePqktwFxZXUgkAkeWF4gG8kJIIXSTJL_-ugHzrW8LnsyFdlCCEz_MleUtADMnyhU6Nlztk_RPw2J9t7dWTtzIad2eB3U9IGOMXMyb-QB4j_26bmL77oUIThz3Otp5FBSPXmn_rG8bumjBpuTj1/s1932/2Chrome_Fast%20&%20Curious_Blog%20Assets_Speedometer%203.0_Downloads%20vs.%20Framework.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1360" data-original-width="1932" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhh9SdoPfDPz-wjCUTknvTaTq4D3pRTUDocU7BoUF-y8iePqktwFxZXUgkAkeWF4gG8kJIIXSTJL_-ugHzrW8LnsyFdlCCEz_MleUtADMnyhU6Nlztk_RPw2J9t7dWTtzIad2eB3U9IGOMXMyb-QB4j_26bmL77oUIThz3Otp5FBSPXmn_rG8bumjBpuTj1/s16000/2Chrome_Fast%20&%20Curious_Blog%20Assets_Speedometer%203.0_Downloads%20vs.%20Framework.png" /></a></div><br /><p style="text-align: center;"><br /></p> <p> With both data points on hand, we decided on a list that we felt gives us a good representation of frameworks. We kept the list small to allow space for brand new types of workloads, instead of just todo apps. We also selected commonly used versions for each framework, based on the current usage. </p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWIjTao8HfxmLG3VNzDgwfcu4tHvdY1-Yu1CZxqnmHliA8LjkN4DbQy0uZDeSsdh11c7T53rQruwMoDyfqqcIgXgraNmmZ2rCjDJVCgbm0K4EP087sbjIb2utmxI8xN1OiJ7XG4L7NTYFdcg_DL2S_-kqU5Om46C6vX5dzvXiM8Kw-LJX247jB05iNZprj/s1932/3Chrome_Fast%20&%20Curious_Blog%20Assets_Speedometer%203.0_Commonly%20Used%20Versions.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1037" data-original-width="1932" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWIjTao8HfxmLG3VNzDgwfcu4tHvdY1-Yu1CZxqnmHliA8LjkN4DbQy0uZDeSsdh11c7T53rQruwMoDyfqqcIgXgraNmmZ2rCjDJVCgbm0K4EP087sbjIb2utmxI8xN1OiJ7XG4L7NTYFdcg_DL2S_-kqU5Om46C6vX5dzvXiM8Kw-LJX247jB05iNZprj/s16000/3Chrome_Fast%20&%20Curious_Blog%20Assets_Speedometer%203.0_Commonly%20Used%20Versions.png" /></a></div><br /><p style="text-align: center;"><br /></p> <p> In addition, we updated the previous JavaScript implementations and included a new web-component based version, implemented with vanilla JavaScript. </p> <h3 style="text-align: left;"><strong>More Workloads</strong></h3> <p> A simple Todo-list only tests a subset of functionality. For example: how well do browsers handle complicated flexbox and grid layouts? How can we capture SVG and canvas rendering and how can we include more realistic scenarios that happen on a website? </p> <p> We collected and categorized areas of interest into DOM, layout, API and patterns, to be able to match them to potential workloads that would allow us to test these areas. In addition we collected user journeys that included the different categories of interest: editing text, rendering charts, navigating a site, and so on. </p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvvQUbw7sWXJeFdASbV66Nn0mJxLkJtevbcCoy1UhZ9IRQj8tkHg657V31yKBiPd8T71ArAQmSedl9NeoqczYvv49MciBUuyfSg5-zyIOIrae807_5N3hzemRyQuTTHYsTiGZ7qV4ARPrQEO7vWIm9-R3kCaKpQcwRsxYr3NkqProgY-8mSe5PjHUNbSf-/s1932/4Chrome_Fast%20&%20Curious_Blog%20Assets_Speedometer%203.0_More%20Workloads.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1321" data-original-width="1932" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvvQUbw7sWXJeFdASbV66Nn0mJxLkJtevbcCoy1UhZ9IRQj8tkHg657V31yKBiPd8T71ArAQmSedl9NeoqczYvv49MciBUuyfSg5-zyIOIrae807_5N3hzemRyQuTTHYsTiGZ7qV4ARPrQEO7vWIm9-R3kCaKpQcwRsxYr3NkqProgY-8mSe5PjHUNbSf-/s16000/4Chrome_Fast%20&%20Curious_Blog%20Assets_Speedometer%203.0_More%20Workloads.png" /></a></div><br /><p style="text-align: center;"><br /></p> <p> There are many more areas that we weren’t able to include, but the final list of workloads presents a larger variety and we hope that future versions of Speedometer will build upon the current list. </p> <h3 style="text-align: left;"><strong>Validation</strong></h3> <p> The Chrome Aurora team worked with the <a href="https://v8.dev/">Chrome V8 team</a> to validate our assumptions above. In Chrome, we can use <a href="https://v8.dev/docs/rcs">runtime-call-stats</a> to measure time spent in each web API (and additionally many internal components). This allows us to get an insight into how dominant certain APIs are. </p> <p> If we look at Speedometer 2.1 we see that a disproportionate amount of benchmark time is spent in innerHTML. </p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiyW_hT0-7IEsnU0vMSGYepKt3W9atMq1rHRw0hKyQ_8zLozWyM0yILERSynI5j5F4rWM5ZKRaWPgaSanJxzwBZD0aqt_wye9p1yQmOzZaOF7cEXRPeMLTF-MhWJorfg-Q9QEAkP6Y1DKVM5AFUieQoP94Y18TyAWb8g-a3sdz_Tgxk-DMMqs_O7CwI03HA/s1932/5Chrome_Fast%20&%20Curious_Blog%20Assets_Speedometer%203.0_v2_Speedometer%202.1%20Chrome%20API%20Usage.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1328" data-original-width="1932" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiyW_hT0-7IEsnU0vMSGYepKt3W9atMq1rHRw0hKyQ_8zLozWyM0yILERSynI5j5F4rWM5ZKRaWPgaSanJxzwBZD0aqt_wye9p1yQmOzZaOF7cEXRPeMLTF-MhWJorfg-Q9QEAkP6Y1DKVM5AFUieQoP94Y18TyAWb8g-a3sdz_Tgxk-DMMqs_O7CwI03HA/s16000/5Chrome_Fast%20&%20Curious_Blog%20Assets_Speedometer%203.0_v2_Speedometer%202.1%20Chrome%20API%20Usage.png" /></a></div><br /><p style="text-align: center;"><br /></p> <p> While <a href="http://go/mdn/API/Element/innerHTML">innerHTML</a> is an important web API, it's overrepresented in Speedometer 2.1. Doing the same analysis on the new version 3.0 yields a slightly different picture: </p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgEdKNUJzhrWhWY8AHHiZYGfTLsF-crQZKcvAGhD_RtAfD0fsRDGuufFew8kCUccNrhcyF17K_cEvyR38nFx2_CgS9ZIE2Z2afe4DXCg6Rou8n_J3iY8Jq0A8lUo0TlzAG5AOmstNzaraw_47S8r_TzS9ZYX4t1Mqf5Wpe3QRissuDEhabmzk_q_7lEmVE3/s1932/6Chrome_Fast%20&%20Curious_Blog%20Assets_Speedometer%203.0_Speedometer%203.0%20Chrome%20API%20Usage.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1404" data-original-width="1932" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgEdKNUJzhrWhWY8AHHiZYGfTLsF-crQZKcvAGhD_RtAfD0fsRDGuufFew8kCUccNrhcyF17K_cEvyR38nFx2_CgS9ZIE2Z2afe4DXCg6Rou8n_J3iY8Jq0A8lUo0TlzAG5AOmstNzaraw_47S8r_TzS9ZYX4t1Mqf5Wpe3QRissuDEhabmzk_q_7lEmVE3/s16000/6Chrome_Fast%20&%20Curious_Blog%20Assets_Speedometer%203.0_Speedometer%203.0%20Chrome%20API%20Usage.png" /></a></div><br /><p style="text-align: center;"><br /></p> <p> We can see that innerHTML is still present, but its overall contribution shrunk from roughly 14% down to 4.5%. As a result, we get a better distribution that favors more DOM APIs to be optimized. We can also see that a few Canvas APIs have moved into this list, thanks to the new workloads in v3.0. </p> <p> While we will never be able to perfectly represent the whole web in a fast-running and stable benchmark, it is clear that Speedometer 3.0 is a giant step in the right direction. </p> <p> Ultimately, we ended up with the following list of workloads presented in the next few sections. </p> <h3 style="text-align: left;"><strong>What workloads are included?</strong></h3> <p> <strong><em>TodoMVC</em></strong> </p> <p> Many developers might recognize the <a href="https://todomvc.com/">TodoMVC app</a>. It’s a popular resource for learning and offers a wide range of TodoMVC implementations with different frameworks. </p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi3uqFby4YGbOdvIEo3mgb6EjFO4q9OtRNagMiDOEcTzVFyzrMeJCKoab-U4fyKVQr7rfbfTzTgCmbNxgy84pl3-bfvsfVmC6mqBYcxNB739yNTlYORwySDsKmNRIjdjwivLcpI6iG6CzGOz7x2Gy0gq1LIgRCgIJi2neq1nQWfo0G07plVTRF3E6nGs_2q/s842/1TodoMVC.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="706" data-original-width="842" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi3uqFby4YGbOdvIEo3mgb6EjFO4q9OtRNagMiDOEcTzVFyzrMeJCKoab-U4fyKVQr7rfbfTzTgCmbNxgy84pl3-bfvsfVmC6mqBYcxNB739yNTlYORwySDsKmNRIjdjwivLcpI6iG6CzGOz7x2Gy0gq1LIgRCgIJi2neq1nQWfo0G07plVTRF3E6nGs_2q/s16000/1TodoMVC.png" /></a></div><br /><p style="text-align: center;"><br /></p> <p> TodoMVC is a to-do application that allows a user to keep track of tasks. The user can enter a new task, update an existing one, mark a task as completed, or delete it. In addition to the basic CRUD operations, the TodoMVC app has some added functionality: filters are available to change the view to “all”, “active” or “completed” tasks and a status text displays the number of active tasks to complete. </p> <p> In Speedometer, we introduced a local data source for todo items, which we use in our tests to populate the todo apps. This gave us the opportunity to test a larger character set with different languages. </p> <p> The tests for these apps are all similar and are relatable to typical user journeys with a todo app: </p> <ol> <li>Add a task </li><li>Mark task as complete </li><li>Delete task </li><li>Repeat steps 1-3 a set amount of times </li> </ol> <p> These tests seem simple, but it lets us benchmark DOM manipulations. Having a variety of framework implementations also cover several different ways how this can be done. </p> <p> <strong><em>Complex DOM / TodoMVC</em></strong> </p> <p> The complex DOM workloads embed various TodoMVC implementations in a static UI shell that mimics a complex web page. The idea is to capture the performance impact on executing seemingly isolated actions (e.g. adding/deleting todo items) in the context of a complex website. Small performance hits that aren’t obvious in an isolated TodoMVC workload are amplified in a larger application and therefore capture more real-world impact. </p> <p> The tests are similar to the TodoMVC tests, executed in the complex DOM & CSSOM environment. </p> <p> This introduces an additional layer of complexity that browsers have to be able to handle effortlessly. </p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEigyFShRHZAVX8SzN0eRf1XyOPAwT1563BKuuzaOYSlG8-rVaeSqGj88DFM3bsiJmveZ5z-XB-2jaZp8Exz6NTvf1wQbN1vmouCnSbMV8QtXbWpsbbAhEFQOk0zuhTxOkUfbcDadVy6nbQ7HhjgsmQEghoO_v3v8FMnsCB7ZWWzk8YsZXeXZbD8zWbItd33/s822/2Complex%20DOM%20%20TodoMVC.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="694" data-original-width="822" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEigyFShRHZAVX8SzN0eRf1XyOPAwT1563BKuuzaOYSlG8-rVaeSqGj88DFM3bsiJmveZ5z-XB-2jaZp8Exz6NTvf1wQbN1vmouCnSbMV8QtXbWpsbbAhEFQOk0zuhTxOkUfbcDadVy6nbQ7HhjgsmQEghoO_v3v8FMnsCB7ZWWzk8YsZXeXZbD8zWbItd33/s16000/2Complex%20DOM%20%20TodoMVC.png" /></a></div><br /><p style="text-align: center;"><br /></p> <p> <strong><em>Single-page-applications (News Site)</em></strong> </p> <p> Single-page-applications (SPAs) are widely used on the web for streaming, gaming, social media and pretty much anything you can imagine. A SPA lets us capture navigating between pages and interacting with an app. We chose a news site to represent a SPA, since it allows us to capture the main areas of interest in a deterministic way. An important factor was that we want to ensure we are using static local data and that the app doesn’t rely on network requests to present this data to the user. </p> <p> Two implementations are included: one built with Next.js and the other with Nuxt. This gave us the opportunity to represent applications built with meta frameworks, with the caveat that we needed to ensure to use static outputs. </p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgeu13O9BevycHTsDVrYPsWvaM3lJEKPPUz9Ket2PmQLQE3pOpYTE_YNv85egpLFAqW3_5f0c-fHclB283uH7Xh8bTJsxMeFu9ArDW892iBSFNVTrVhqKLw4JN23XrW-zH8BnIdvND1SbC9am0kF16t4DjPuSOoOoF5qqprsyFHiMNOINqpNWZTXsQWtQAE/s826/3Single-page-applications%20(News%20Site).png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="690" data-original-width="826" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgeu13O9BevycHTsDVrYPsWvaM3lJEKPPUz9Ket2PmQLQE3pOpYTE_YNv85egpLFAqW3_5f0c-fHclB283uH7Xh8bTJsxMeFu9ArDW892iBSFNVTrVhqKLw4JN23XrW-zH8BnIdvND1SbC9am0kF16t4DjPuSOoOoF5qqprsyFHiMNOINqpNWZTXsQWtQAE/s16000/3Single-page-applications%20(News%20Site).png" /></a></div><br /><p style="text-align: center;"><br /></p> <p> Tests for the news site mimic a typical user journey, by selecting a menu item and navigating to another section of the site. </p> <ol> <li>Click on ‘More’ toggle of the navigation </li><li>Click on a navigation button </li><li>Repeat steps 1 and 2 a set amount of times </li> </ol> <p> These tests let us evaluate how well a browser can handle large DOM and CSSOM changes, by changing a large amount of data that needs to be displayed when navigating to a different page. </p> <p> <strong><em>Charting Apps & Dashboards</em></strong> </p> <p> Charting apps allow us to test SVG and canvas rendering by displaying charts in various workloads. </p> <p> These apps represent popular sites that display financial information, stock charts or dashboards. </p> <p> Both SVG rendering and the use of the canvas api weren’t represented in previous releases of Speedometer. </p> <p> <strong>Observable Plot</strong> displays a stacked bar chart, as well as a dotted chart. It is based on D3, which is a JavaScript library for visualizing tabular data and outputs SVG elements. It loops through a big dataset to build the source data that D3 needs, using map, filter and flatMap methods. As a result this exercises creation and copying of objects and arrays. </p> <p> <strong>Chart.js</strong> is a JavaScript charting library. The included workload displays a scatter graph with the canvas api, both with some transparency and with full opacity. This uses the same data as the previous workload, but with a different preparation phase. In this case it makes a heavy use of trigonometry to compute distances between airports. </p> <p> <strong>React Stockcharts</strong> displays a dashboard for stocks. It is based on D3 for all computation, but outputs SVG directly using React. </p> <p> <strong>Webkit Perf-Dashboard</strong> is an application used to track various performance metrics of WebKit. The dashboard uses canvas drawing and web components for its ui. </p> <p> These workloads test DOM manipulation with SVG or canvas by interacting with charts. For example here are the interactions of the Observable Plot workload:<br /> </p> <ol> <li>Prepare data: compute the input datasets to output structures that D3 understands. </li><li>Add stacked chart: this draws a chart using SVG elements. </li><li>Change input slider to change the computation parameters. </li><li>Repeat steps 1 and 2 </li><li>Reset: this clears the view </li><li>Add dotted chart: this draws another type of graph (dots instead of bars) to exercise different drawing primitives. This also uses a power scale.</li> </ol><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi1QH4eW4eb6BhbRSvNOkbrq9HXwSWc53aNbMKuxv5I5Sw2LzMiN5BMVqAwo6GCag4VGThAy9jifHBmc2yVRDxwNFuJo6C-jymDoTfpZqzcmFNOrtWUsHfbUxeQ0cjixXh7WRajjHdj-V_dK-FrQxCEEV5XXDzgKp7Q3xiHrTc9LJcgDaO9Ryg4_KnsYKhN/s846/4Webkit%20Perf-Dashboard_1.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="706" data-original-width="846" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi1QH4eW4eb6BhbRSvNOkbrq9HXwSWc53aNbMKuxv5I5Sw2LzMiN5BMVqAwo6GCag4VGThAy9jifHBmc2yVRDxwNFuJo6C-jymDoTfpZqzcmFNOrtWUsHfbUxeQ0cjixXh7WRajjHdj-V_dK-FrQxCEEV5XXDzgKp7Q3xiHrTc9LJcgDaO9Ryg4_KnsYKhN/s16000/4Webkit%20Perf-Dashboard_1.png" /></a></div><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg7BWgJu6HvFqDwADBq9Q0GblZFHIJpp052nYZM0CgRfQbbsAp-VTN8Xpy1o1XbYhIqUKoGg4uELeo6Un2NHFul2qaAzL99Y7vxJqASK8uMXDD8GyX2jIFIAiBl36suwaHO5hGUmvxQMt09mX38Oh5R8hOXckFneevSpQlChMu5qQmcUiKIqoaAQiCxNjrB/s822/5Webkit%20Perf-Dashboard_2.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="696" data-original-width="822" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg7BWgJu6HvFqDwADBq9Q0GblZFHIJpp052nYZM0CgRfQbbsAp-VTN8Xpy1o1XbYhIqUKoGg4uELeo6Un2NHFul2qaAzL99Y7vxJqASK8uMXDD8GyX2jIFIAiBl36suwaHO5hGUmvxQMt09mX38Oh5R8hOXckFneevSpQlChMu5qQmcUiKIqoaAQiCxNjrB/s16000/5Webkit%20Perf-Dashboard_2.png" /></a></div><br /><div style="text-align: center;"><br /></div> <p> <strong><em>Code Editors</em></strong> </p> <p> Editors, for example WYSIWYG text and code editors, let us focus on editing live text and capturing form interactions. Typical scenarios are writing an email, logging into a website or filling out an online form. Although there is some form interaction present in the TodoMVC apps, the editor workloads use a large data set, which lets us evaluate performance more accurately. </p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiHb9rJqJXZ95LXsDjo8Zd1l2TciE1uFZ5eolDJf3euB5P7C8KwJ27vB-xlCic8R7CHNy7Qxuea9zuCsqbdJ4k6safN5Z7oA6KadxbzYEus6TRmVV0cHZLcJedupQb6R-0DB4YpMagfvjviPhxGfWAIDmxzJ7jBXGzjALxeMmxuEoTACaNMIrDqEnoAMwXA/s846/6Code%20Editors.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="708" data-original-width="846" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiHb9rJqJXZ95LXsDjo8Zd1l2TciE1uFZ5eolDJf3euB5P7C8KwJ27vB-xlCic8R7CHNy7Qxuea9zuCsqbdJ4k6safN5Z7oA6KadxbzYEus6TRmVV0cHZLcJedupQb6R-0DB4YpMagfvjviPhxGfWAIDmxzJ7jBXGzjALxeMmxuEoTACaNMIrDqEnoAMwXA/s16000/6Code%20Editors.png" /></a></div><br /><p style="text-align: center;"><br /></p> <p> <strong>Codemirror</strong> is a code editor that implements a text input field with support for many editing features. Several languages and frameworks are available and for this workload we used the JavaScript library from Codemirror. </p> <p> <strong>Tiptap</strong> Editor is a headless, framework-agnostic rich text editor that's customizable and extendable. This workload used Tiptap as its basis and added a simple ui to interact with. </p> <p> Both apps test DOM insertion and manipulation of a large amount of data in the following way: </p> <ol> <li>Create an editable element. </li><li>Insert a long text.: Codemirror uses the development bundle of React, whileTipTap loads an excerpt of Proust’s Du Côté de Chez Swann. </li><li>Highlight text: Codemirror turns on syntax highlighting, while TipTap sets all the text to bold. </li> </ol> <h3 style="text-align: left;"><strong>Parting words</strong></h3> <p> Being able to collaborate with all major browser vendors and having all of us contribute to workloads has been a unique experience and we are looking forward to continuing to collaborate in the browser benchmarking space. </p> <p> Don’t forget to check out the new release of Speedometer and test it out in your favorite browser, dig into the results, check out our repo and feel free to open issues with any improvements or ideas for workloads you would like to see included in the next version. We are aiming for a more frequent release schedule in the future and if you are a framework author and want to contribute, feel free to file an issue on our <a href="https://github.com/WebKit/Speedometer/issues">Github</a> to start the discussion. </p> <p> <em><span style="font-size: x-small;">Posted by Thorsten Kober, Chrome Aurora</span></em> </p> <span itemprop='author' itemscope='itemscope' itemtype='http://schema.org/Person'> <meta content='https://plus.google.com/116899029375914044550' itemprop='url'/> </span> </noscript> </div> </div> <div class='share'> <span class='twitter-custom social-wrapper' data-href='http://twitter.com/share?text=Chromium Blog:Speedometer 3: Building a benchmark that represents the web&url=https://blog.chromium.org/2024/03/speedometer-3-building-benchmark-that.html&via=ChromiumDev'> <img alt='Share on Twitter' height='24' src='https://www.gstatic.com/images/icons/material/system/2x/post_twitter_black_24dp.png' width='24'/> </span> <span class='fb-custom social-wrapper' data-href='https://www.facebook.com/sharer.php?u=https://blog.chromium.org/2024/03/speedometer-3-building-benchmark-that.html'> <img alt='Share on Facebook' height='24' src='https://www.gstatic.com/images/icons/material/system/2x/post_facebook_black_24dp.png' width='24'/> </span> </div> <div class='post-footer'> <div class='cmt_iframe_holder' data-href='https://blog.chromium.org/2024/03/speedometer-3-building-benchmark-that.html' data-viewtype='FILTERED_POSTMOD'></div> <a href='https://plus.google.com/112374322230920073195' rel='author' style='display:none;'> Google </a> <div class='label-footer'> <span class='labels-caption'> Labels: </span> <span class='labels'> <a class='label' href='https://blog.chromium.org/search/label/the%20fast%20and%20the%20curious' rel='tag'> the fast and the curious </a> </span> </div> </div> </div> <div class='post' data-id='4112552297450954984' itemscope='' itemtype='http://schema.org/BlogPosting'> <h2 class='title' itemprop='name'> <a href='https://blog.chromium.org/2023/11/how-core-web-vitals-saved-users-10000.html' itemprop='url' title='How Core Web Vitals saved users 10,000 years of waiting for web pages to load'> How Core Web Vitals saved users 10,000 years of waiting for web pages to load </a> </h2> <div class='post-header'> <div class='published'> <span class='publishdate' itemprop='datePublished'> Tuesday, November 7, 2023 </span> </div> </div> <div class='post-body'> <div class='post-content' itemprop='articleBody'> <script type='text/template'> <div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmp1qvDcNBZtkhpYpK-Ly3iyOHgmGT9L3c8nQlJFRy6ncMfwdblt0BYX_j3zBBRqSA9wrnKdeth6rOtS325MPGr0CNesGPFa4ZS83FLR0lcxFfKkarvl2OZcOgEb4XloVsDLvr1a3h_5YBQSX4ZdLdx2cuQyUdsbcDp2FYZzjJWGnVdlvEzxxv2asH_yT8/s400/Fast%20Curious_image.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="166" data-original-width="400" height="166" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmp1qvDcNBZtkhpYpK-Ly3iyOHgmGT9L3c8nQlJFRy6ncMfwdblt0BYX_j3zBBRqSA9wrnKdeth6rOtS325MPGr0CNesGPFa4ZS83FLR0lcxFfKkarvl2OZcOgEb4XloVsDLvr1a3h_5YBQSX4ZdLdx2cuQyUdsbcDp2FYZzjJWGnVdlvEzxxv2asH_yT8/w400-h166/Fast%20Curious_image.png" width="400" /></a></div><br /><span face="Arial, sans-serif" style="font-size: 10pt; font-style: italic; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><br /></span><p></p><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span face="Arial, sans-serif" style="font-size: 10pt; font-style: italic; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">T</span><span face="Arial, sans-serif" style="font-size: 10pt; font-style: italic; white-space-collapse: preserve;">oday’s The Fast and the Curious post explores how Core Web Vitals saved Chrome users more than 10,000 Years of waiting for web pages to load in 2023 (across Chrome desktop and Android) by quantifying the experience of sites and identifying opportunities to make improvements.</span></p><br /><br /><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span face="Arial, sans-serif" style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">In 2020, we introduced </span><a href="https://web.dev/vitals/" style="text-decoration-line: none;"><span face="Arial, sans-serif" style="color: #1155cc; font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">Web Vitals</span></a><span face="Arial, sans-serif" style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> - essential quality signals for webpages to ensure a better user experience. Since then, there has been a massive leap in web performance made possible by our work on Core Web Vitals (CWV) and its broader impact on the web. Today, over 40% of sites pass all of the CWV metrics, leading to pages that load and respond to interactions more quickly. Here’s a closer look at the journey to help improve the performance for sites and some specific work done in the browser and the ecosystem to enable this achievement. </span></p><br /><br /><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span face="Arial, sans-serif" style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-weight: 700; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-size: large;">Chrome's Quest for Speed</span></span></p><br /><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span face="Arial, sans-serif" style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">The very essence of the web lies in its ability to provide information and services efficiently and rapidly. This principle is at the heart of Google's business and drives our work on Chrome. However, we noticed an issue with sites over a long time horizon. Even if slow sites improved their performance for a while, it would often decline over time. No matter how fast Google Search might be, the user experience would be subpar if the pages found were slow to load.</span></p><br /><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span face="Arial, sans-serif" style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">We could not help these sites improve their performance directly, but we wanted users to have a great experience when they moved from Google Search to the individual sites. To tackle the challenge of improving the user experience while simultaneously providing unified guidance to developers, teams from Search and Chrome collaborated to address the issue of slow web pages.</span></p><br /><br /><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span face="Arial, sans-serif" style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-weight: 700; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-size: large;">Defining the Fast Web </span></span></p><br /><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span face="Arial, sans-serif" style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">We examined millions of pages to define a public standard for a fast, user-friendly web page (initially published in </span><a href="https://blog.chromium.org/2020/05/the-science-behind-web-vitals.html" style="text-decoration-line: none;"><span face="Arial, sans-serif" style="color: #1155cc; font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">The Science Behind Web Vitals</span></a><span face="Arial, sans-serif" style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">). We published our specifications and data to the open ecosystem and took note of the feedback we received. The introduction of CWV metrics such as </span><a href="https://web.dev/articles/lcp" style="text-decoration-line: none;"><span face="Arial, sans-serif" style="color: #1155cc; font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">LCP</span></a><span face="Arial, sans-serif" style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> (Largest Contentful Paint) was groundbreaking because it allowed us to measure when the user actually sees the content. The ability to measure the actual user experience at scale has been foundational to the improvements that we will discuss in this blog post.</span></p><br /><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span face="Arial, sans-serif" style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">Next, we updated Google's search ranking algorithms in August 2021 to consider, among other factors, whether a page met the speed and usability standards established as part of CWV. Today, it remains </span><a href="https://developers.google.com/search/docs/appearance/page-experience#core-web-vitals" style="text-decoration-line: none;"><span face="Arial, sans-serif" style="color: #1155cc; font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">highly recommended</span></a><span face="Arial, sans-serif" style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> for site owners to achieve good Core Web Vitals for success with Search and to ensure a great user experience generally.</span></p><br /><br /><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span face="Arial, sans-serif" style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-weight: 700; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-size: large;">Exponential Impact of Small Changes</span></span></p><br /><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span face="Arial, sans-serif" style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">The results we saw after these changes were significant. The average page load in Chrome is now 166 ms faster. That might seem like a minor improvement, but small changes can accumulate to create a substantial impact on the web. </span></p><br /><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span face="Arial, sans-serif" style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">So far in 2023, this project saved users over 10,000 years of waiting for web pages to load and over 1,200 years of waiting for web pages to respond to user input. And the web continues to get faster. We also tracked improvements in how many navigations meet Core Web Vitals (CWV). The current figures stand at 64.45% for mobile (up from 64%) and 68.39% for desktop (up from 67%). The Chrome Data team projects a ~69% pass rate by the end of the year.</span></p><div><span face="Arial, sans-serif" style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><br /></span></div><div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJXlVkkM1NpqQVv72HdG9lqOx0BNVa0zA8ALsBeqZI5ZRB-WQt4MDj3SMPDkwFBQt8J8Y3d6f2TaWpz_9dHjdNUNTTaNIduP5aD-y1_c_c980qRKByLSQDcZ8RVx6v3YwE__etQlQAUwTKaJJKhYQZYpyewk-QBA5apndz0w6jjdPsWhANwHhQxOYXML1r/s954/Screenshot%202023-11-06%20at%209.45.17%E2%80%AFAM.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="536" data-original-width="954" height="360" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJXlVkkM1NpqQVv72HdG9lqOx0BNVa0zA8ALsBeqZI5ZRB-WQt4MDj3SMPDkwFBQt8J8Y3d6f2TaWpz_9dHjdNUNTTaNIduP5aD-y1_c_c980qRKByLSQDcZ8RVx6v3YwE__etQlQAUwTKaJJKhYQZYpyewk-QBA5apndz0w6jjdPsWhANwHhQxOYXML1r/w640-h360/Screenshot%202023-11-06%20at%209.45.17%E2%80%AFAM.png" title="Caption: Our savings for LCP translate into 8,000 years saved for users waiting for pages to load on Android and 2,000 years in 2023 so far. On INP, we have saved users 800 years on Android and 450 years on Windows so far in 2023." width="640" /></a></div><span face="Arial, sans-serif" style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span id="docs-internal-guid-d3bb3188-7fff-d2e6-9ed6-dd110b96dabe"><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><i><span id="docs-internal-guid-ec2eec2f-7fff-9721-9c42-de5217fb0a87"></span></i></p><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span face="Arial, sans-serif" style="color: black; font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><i>Caption: Our savings for LCP translate into 8,000 years saved for users waiting for pages to load on Android and 2,000 years in 2023 so far. On INP, we have saved users 800 years on Android and 450 years on Windows so far in 2023.</i></span></p><div><br /></div></span></span></div><div><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><p dir="ltr" style="font-family: Arial, sans-serif; font-size: 10pt; line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt; white-space-collapse: preserve;"><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">Next, let’s look at some recent updates from both the Chrome team and the wider developer ecosystem, demonstrating how our joint efforts are speeding up the web.</span></p><span face="Arial, sans-serif" style="font-size: 10pt; white-space-collapse: preserve;"><br /><br /></span><p dir="ltr" style="font-family: Arial, sans-serif; line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt; white-space-collapse: preserve;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-weight: 700; vertical-align: baseline;"><span style="font-size: large;">Chrome’s Core Web Vitals Achievements</span></span></p><br /><p dir="ltr" style="font-family: Arial, sans-serif; font-size: 10pt; line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt; white-space-collapse: preserve;"><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">We’re proud to highlight numerous ways we’ve optimized performance. </span></p><span face="Arial, sans-serif" style="font-size: 10pt; white-space-collapse: preserve;"><br /></span><ul style="font-family: Arial, sans-serif; font-size: 10pt; margin-bottom: 0px; margin-top: 0px; padding-inline-start: 48px; white-space-collapse: preserve;"><li aria-level="1" dir="ltr" style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; list-style-type: disc; text-wrap: nowrap; vertical-align: baseline;"><p dir="ltr" role="presentation" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap: wrap; vertical-align: baseline;">The </span><a href="https://web.dev/articles/bfcache" style="text-decoration-line: none;"><span style="color: #1155cc; font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; text-wrap: wrap; vertical-align: baseline;">Back/forward cache</span></a><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap: wrap; vertical-align: baseline;"> (bfcache) is designed to improve browsing experience by enabling instant back and forward navigation. BFCache’s hit rate has improved month-over-month on both Android (3.6%) and Desktop (1.8%).</span></p></li></ul><span face="Arial, sans-serif" style="font-size: 10pt; white-space-collapse: preserve;"><br /></span><ul style="font-family: Arial, sans-serif; font-size: 10pt; margin-bottom: 0px; margin-top: 0px; padding-inline-start: 48px; white-space-collapse: preserve;"><li aria-level="1" dir="ltr" style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; list-style-type: disc; text-wrap: nowrap; vertical-align: baseline;"><p dir="ltr" role="presentation" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap: wrap; vertical-align: baseline;">Another example of a particularly impactful optimization is our PreconnectOnAnchorInteraction feature which connects to origins on pointer-down rather than pointer-up. This fully launched feature led to a 6/10ms (0.4/1%) median LCP improvement on Android/Desktop, and an improvement in cross-origin LCP by ~60ms on both Android and Desktop. The launch also resulted in a 0.08% Content Ad revenue increase, underlining the significant impact of performance optimizations on user engagement and ecosystem health.</span></p></li></ul><span face="Arial, sans-serif" style="font-size: 10pt; white-space-collapse: preserve;"><br /></span><ul style="font-family: Arial, sans-serif; font-size: 10pt; margin-bottom: 0px; margin-top: 0px; padding-inline-start: 48px; white-space-collapse: preserve;"><li aria-level="1" dir="ltr" style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; list-style-type: disc; text-wrap: nowrap; vertical-align: baseline;"><p dir="ltr" role="presentation" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap: wrap; vertical-align: baseline;">We also introduced </span><a href="https://developer.chrome.com/blog/prerender-pages/" style="text-decoration-line: none;"><span style="color: #1155cc; font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; text-wrap: wrap; vertical-align: baseline;">prerendering</span></a><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap: wrap; vertical-align: baseline;">, which makes pages load instantly by rendering them before the user actually visits. Page loads via typing URLs directly in the omnibox get a 500-700ms (14-25%) median LCP improvement when prerendered, depending on the platform, moving global median LCP across all navigations by 6.4ms. We're currently rolling out prerendering of omnibox-initiated searches.</span></p></li></ul><span face="Arial, sans-serif" style="font-size: 10pt; white-space-collapse: preserve;"><br /></span><ul style="font-family: Arial, sans-serif; font-size: 10pt; margin-bottom: 0px; margin-top: 0px; padding-inline-start: 48px; white-space-collapse: preserve;"><li aria-level="1" dir="ltr" style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; list-style-type: disc; text-wrap: nowrap; vertical-align: baseline;"><p dir="ltr" role="presentation" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap: wrap; vertical-align: baseline;">Chrome has been working hard to keep background tabs out of your way. Implementing </span><a href="https://blog.chromium.org/2020/11/tab-throttling-and-more-performance.html" style="text-decoration-line: none;"><span style="color: #1155cc; font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; text-wrap: wrap; vertical-align: baseline;">tab throttling for background tabs</span></a><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap: wrap; vertical-align: baseline;"> running at EcoQOS on Windows 11 and Task Role and QoS Adjustments on macOS have led to improvements in Largest Contentful Paint (</span><a href="http://web.dev/lcp" style="text-decoration-line: none;"><span style="color: #1155cc; font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; text-wrap: wrap; vertical-align: baseline;">LCP</span></a><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap: wrap; vertical-align: baseline;">) and Interaction to Next Paint (</span><a href="https://web.dev/articles/inp" style="text-decoration-line: none;"><span style="color: #1155cc; font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; text-wrap: wrap; vertical-align: baseline;">INP</span></a><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap: wrap; vertical-align: baseline;">). </span><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap: wrap; vertical-align: baseline;"><br /><br /></span></p></li><li aria-level="1" dir="ltr" style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; list-style-type: disc; text-wrap: nowrap; vertical-align: baseline;"><p dir="ltr" role="presentation" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap: wrap; vertical-align: baseline;">The web’s modern ability to run all types of applications also comes with a mandate to manage the workload that this encurs. We have been optimizing Chrome under mutliple active tabs and are happy to report improvements to scheduling and contention which improve INP by 5% and LCP by 2% in the last 6 months.</span></p></li></ul><span face="Arial, sans-serif" style="font-size: 10pt; white-space-collapse: preserve;"><br /></span><ul style="font-family: Arial, sans-serif; font-size: 10pt; margin-bottom: 0px; margin-top: 0px; padding-inline-start: 48px; white-space-collapse: preserve;"><li aria-level="1" dir="ltr" style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; list-style-type: disc; text-wrap: nowrap; vertical-align: baseline;"><p dir="ltr" role="presentation" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap: wrap; vertical-align: baseline;">We have made targeted improvements to the page loading code in Chrome in 2022. These resulted in LCP improving by 10% on Android, and CWV pass rate improving by 1.5%.</span></p></li></ul><span face="Arial, sans-serif" style="font-size: 10pt; white-space-collapse: preserve;"><br /></span><ul style="font-family: Arial, sans-serif; font-size: 10pt; margin-bottom: 0px; margin-top: 0px; padding-inline-start: 48px; white-space-collapse: preserve;"><li aria-level="1" dir="ltr" style="color: #0e101a; font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; list-style-type: disc; text-wrap: nowrap; vertical-align: baseline;"><p dir="ltr" role="presentation" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap: wrap; vertical-align: baseline;">Chrome's renderer has also seen some improvements. The renderer's main thread includes task queues for JavaScript, rendering, and image loading. Some changes that alter the priority of these tasks for optimal CWV include.</span></p></li><ul style="margin-bottom: 0px; margin-top: 0px; padding-inline-start: 48px;"><li aria-level="2" dir="ltr" style="color: #0e101a; font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; list-style-type: disc; text-wrap: nowrap; vertical-align: baseline;"><p dir="ltr" role="presentation" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-weight: 700; text-wrap: wrap; vertical-align: baseline;">High priority image loading: </span><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap: wrap; vertical-align: baseline;">Historically, image-loading had the same or lower priority than rendering. However, an experiment showed that between an image load task and a rendering task, choosing the image load task first can prevent layout shift of an intermediate frame that doesn't have the image and also improves LCP. The improvement on Android at the 75th percentile was </span><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-weight: 700; text-wrap: wrap; vertical-align: baseline;">-6.66%</span><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap: wrap; vertical-align: baseline;"> for CLS and </span><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-weight: 700; text-wrap: wrap; vertical-align: baseline;">-0.82%</span><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap: wrap; vertical-align: baseline;"> for LCP, improving the CWV pass rate on Android by </span><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-weight: 700; text-wrap: wrap; vertical-align: baseline;">+0.24%.</span><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap: wrap; vertical-align: baseline;"> A similar experiment that boosted the loading priority to "medium" of the first five images parsed from the HTML (for non-icon-sized images) showed an improvement on Android at the 75th percentile of </span><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-weight: 700; text-wrap: wrap; vertical-align: baseline;">-6.08%</span><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap: wrap; vertical-align: baseline;"> for CLS and </span><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-weight: 700; text-wrap: wrap; vertical-align: baseline;">-0.53%</span><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap: wrap; vertical-align: baseline;"> for LCP. A combined experiment showed the effects of both changes were largely independent. </span></p></li><li aria-level="2" dir="ltr" style="color: #0e101a; font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; list-style-type: disc; text-wrap: nowrap; vertical-align: baseline;"><p dir="ltr" role="presentation" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-weight: 700; text-wrap: wrap; vertical-align: baseline;">Prioritize compositing after delay: </span><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap: wrap; vertical-align: baseline;">If it has been more than 100ms since the last </span><a href="https://developer.chrome.com/blog/inside-browser-part3/#what-is-compositing" style="text-decoration-line: none;"><span style="color: #1155cc; font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; text-wrap: wrap; vertical-align: baseline;">compositing</span></a><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap: wrap; vertical-align: baseline;"> task run, elevate the priority of any queued compositing task so that it will preempt normal-priority work. This produced an improvement of </span><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-weight: 700; text-wrap: wrap; vertical-align: baseline;">-0.27%</span><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap: wrap; vertical-align: baseline;"> for CLS on Android and Windows at the 95th percentile.</span></p></li><li aria-level="2" dir="ltr" style="color: #0e101a; font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; list-style-type: disc; text-wrap: nowrap; vertical-align: baseline;"><p dir="ltr" role="presentation" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-weight: 700; text-wrap: wrap; vertical-align: baseline;">SVG Raster Optimizations</span><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap: wrap; vertical-align: baseline;">: Another SVG drawing optimization improved INP pass rates on desktops by -2.28% for MacOS at the 75th percentile. </span></p></li></ul></ul><div style="font-family: Arial, sans-serif; font-size: 10pt; white-space-collapse: preserve;"><span style="color: #0e101a;"><br /></span></div><div><div class="separator" style="clear: both; font-family: Arial, sans-serif; font-size: 10pt; text-align: center; white-space-collapse: preserve;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiKRmZM0AQmYrx8wvUc0LqtpIwpGOgGPcPGqTeezyXUM0q1WY_TP_AN9UJno42Eutj7xBDlzFUCN0yM_MItJU_hb4fqPl2LCQVR66p6lHoGqRjiEAh1R39eFrSgwZW9uNmIsxWmtl-9SEQyQxb51x_XD1vwLi1JhI3eIa5uCMvxXbRj5WQDrIERvHwGkL-V/s816/video.gif" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="312" data-original-width="816" height="244" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiKRmZM0AQmYrx8wvUc0LqtpIwpGOgGPcPGqTeezyXUM0q1WY_TP_AN9UJno42Eutj7xBDlzFUCN0yM_MItJU_hb4fqPl2LCQVR66p6lHoGqRjiEAh1R39eFrSgwZW9uNmIsxWmtl-9SEQyQxb51x_XD1vwLi1JhI3eIa5uCMvxXbRj5WQDrIERvHwGkL-V/w640-h244/video.gif" width="640" /></a></div><br /><span style="color: #0e101a;"><i><span face="Arial, sans-serif"><span style="font-size: 13.3333px; white-space-collapse: preserve;">Caption: An example of Chrome’s new prioritized loading of the first five images parsed from the HTML. This improved LCP from 3.1s to 2.5s.</span></span></i></span></div><div><br /></div><div style="font-family: Arial, sans-serif; font-size: 10pt; white-space-collapse: preserve;"><span style="color: #0e101a;"><br /></span></div><div><span face="Arial, sans-serif" id="docs-internal-guid-834c64f4-7fff-cc90-0d9c-3e0473aa2cc9" style="white-space-collapse: preserve;"><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-weight: 700; vertical-align: baseline;"><span style="font-size: large;">Ecosystem Core Web Vitals Achievements</span></span></p><br /><p dir="ltr" style="font-size: 10pt; line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">The broader developer ecosystem has also achieved remarkable results by focusing on Core Web Vitals. </span><span style="color: #0e101a; font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">The most significant achievement was the performance improvement on WordPress - the Content Management System that powers over a third of the web: "</span><a href="https://make.wordpress.org/core/2023/08/07/wordpress-6-3-performance-improvements/" style="text-decoration-line: none;"><span style="color: #4a6ee0; font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline;">WordPress 6.3</span></a><span style="color: #0e101a; font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"> loads 27% faster for block themes and 18% faster for classic themes, compared to WordPress 6.2, based on the </span><a href="https://web.dev/articles/lcp" style="text-decoration-line: none;"><span style="color: #1155cc; font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline;">Largest Contentful Paint (LCP)</span></a><span style="color: #0e101a; font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"> metric". </span></p><p dir="ltr" style="font-size: 10pt; line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="color: #0e101a; font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><br /></span></p><p dir="ltr" style="font-size: 10pt; line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="color: #0e101a; font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><span id="docs-internal-guid-16173b3d-7fff-b359-9440-045d3b2d504d"><span style="color: black; font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">Some parts of the WordPress ecosystem are going even further. Prerendering some links via the </span><a href="https://developer.chrome.com/blog/prerender-pages/" style="text-decoration-line: none;"><span style="color: #1155cc; font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline;">speculation rules API</span></a><span style="color: black; font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">, </span><a href="https://nitropack.io/" style="text-decoration-line: none;"><span style="color: #1155cc; font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline;">NitroPack</span></a><span style="color: black; font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">'s prerendered page loads have seen an 80% LCP improvement and 55% INP improvement compared to those without any speculative loading.</span></span></span></p><p dir="ltr" style="font-size: 10pt; line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="color: #0e101a; font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><span><span style="color: black; font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><br /></span></span></span></p><p dir="ltr" style="font-size: 10pt; line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="color: #0e101a; font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><span></span></span></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxjcDZR8KcnwqG2wWjgsZP6vE1uCcUGuNCMCjORJUjoFBe2PBclSgQfNz4S21j4H7d8snA6gQUwewxoSjJEDK76Yt1NAaXjYnvmAYa9HI-P_pn6Ue7hN321LQsiPldKNt1DUz8nwqMX6AXb1GNRlHR_xOLnwfbDjSn6w0EszDNYU0F4miZnva8h-l75z4O/s984/Screenshot%202023-11-06%20at%209.48.00%E2%80%AFAM.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="620" data-original-width="984" height="404" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxjcDZR8KcnwqG2wWjgsZP6vE1uCcUGuNCMCjORJUjoFBe2PBclSgQfNz4S21j4H7d8snA6gQUwewxoSjJEDK76Yt1NAaXjYnvmAYa9HI-P_pn6Ue7hN321LQsiPldKNt1DUz8nwqMX6AXb1GNRlHR_xOLnwfbDjSn6w0EszDNYU0F4miZnva8h-l75z4O/w640-h404/Screenshot%202023-11-06%20at%209.48.00%E2%80%AFAM.png" width="640" /></a></div><br /></span><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 13.3333px; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span face="Arial, sans-serif"><i>Caption: The percentage of origins passing all three Core Web Vitals (LCP, FID, CLS) with a "good" experience (Source: <a href="https://httparchive.org/reports/chrome-ux-report#cruxPassesCWV">HTTP Archive</a>) </i></span></span></p><div style="font-family: Arial, sans-serif; white-space-collapse: preserve;"><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><br /></span></div><p dir="ltr" style="font-family: Arial, sans-serif; font-size: 10pt; line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt; white-space-collapse: preserve;"><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">The JavaScript framework community has also seen Core Web Vital gains. Over the past few years, </span><a href="https://developers.chrome.com/aurora" style="font-size: 10pt; text-decoration-line: none;"><span style="color: #1155cc; font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline;">Chrome Aurora</span></a><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"> has collaborated with Next.js, Angular, and Nuxt to release performance-focused features like the </span><a href="https://nextjs.org/docs/app/building-your-application/optimizing/scripts" style="font-size: 10pt; text-decoration-line: none;"><span style="color: #1155cc; font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline;">next/script component</span></a><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">, </span><a href="https://angular.io/guide/image-directive" style="font-size: 10pt; text-decoration-line: none;"><span style="color: #1155cc; font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline;">NgOptimizedImage</span></a><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">, and </span><a href="https://google-fonts.nuxtjs.org/" style="font-size: 10pt; text-decoration-line: none;"><span style="color: #1155cc; font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline;">nuxt/google-fonts</span></a><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">. In 2022, Next.js pass rates increased from 20.4% to 27.3%, Angular pass rates increased from 7.6% to 13.2%, and Nuxt pass rates increased from 15.8% to 20.2%. Enterprise partners who tried our features have seen wins in LCP. For example, after switching to NgOptimizedImage, Land's End saw a 40% LCP improvement on mobile in Lighthouse lab tests and a 75% improvement in LCP on desktop. In similar tests, CareerKarma's LCP reduced 24% when switching to next/script's web worker mode. </span></p></div><div style="font-family: Arial, sans-serif; white-space-collapse: preserve;"><span id="docs-internal-guid-9f3dc149-7fff-0670-014d-856f9e066f27"><span style="font-size: 10pt;"><br /></span><p dir="ltr" style="font-size: 10pt; line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">In the business world, performance optimization has led to remarkable growth. For instance, RedBus improved INP and observed a </span><a href="https://web.dev/case-studies/redbus-inp" style="text-decoration-line: none;"><span style="color: #1155cc; font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline;">7%</span></a><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"> increase in conversion rates. Economic Times improved INP and saw a </span><a href="https://web.dev/case-studies/economic-times-inp" style="text-decoration-line: none;"><span style="color: #1155cc; font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline;">42%</span></a><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"> rise in page views and a 49% reduction in bounce rate. Meesho successfully brought LCP down from 6.9s to 2.5s, resulting in a 16.6% reduction in bounce rate and a 3% increase in conversions.</span></p><span style="font-size: 10pt;"><br /></span><p dir="ltr" style="font-size: 10pt; line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">Major web platforms have also seen significant improvements. Amazon has leveraged the bfcache change introduced on Chrome and saw a 22.7 percentage point (pp) improvement in bfcache hit rate with Chrome's latest version (M112). Cricbuzz experienced an even higher increase, with a 31.40 pp improvement.</span></p><span style="font-size: 10pt;"><br /><br /></span><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-weight: 700; vertical-align: baseline;"><span style="font-size: large;">Partnering for a Better Web </span></span></p><br /><p dir="ltr" style="font-size: 10pt; line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">These performance improvements aren't just statistics – they represent real-world improvements in user experience (and hence </span><a href="https://web.dev/case-studies/terra-prefetching-case-study" style="text-decoration-line: none;"><span style="color: #1155cc; font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline;">business metrics</span></a><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">) as well as developer experience.</span></p><p dir="ltr" style="font-size: 10pt; line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"> </span></p><p dir="ltr" style="font-size: 10pt; line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">Crucially, we have managed to achieve these speed boosts without impacting developer satisfaction, which remains high at 90% overall. Through our developer satisfaction studies, we also found that about half (~51%) of developers are monitoring CWV and are either already optimizing for them or planning to do so. Furthermore, a significant majority (78%) of developers optimizing for CWV report seeing notable improvements in their scores.</span></p><span style="font-size: 10pt;"><br /></span><p dir="ltr" style="font-size: 10pt; line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">Our aim is always to create a better web experience for all users, so we're excited to see the web getting faster. But we also understand that maintaining developer satisfaction is crucial to sustaining these improvements. As developers continue to monitor and optimize for CWV, we are optimistic about the future of web performance.</span></p><span style="font-size: 10pt;"><br /></span><p dir="ltr" style="font-size: 10pt; line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">On behalf of the Chrome team, we want to thank the developer community for their incredible work. By focusing on Core Web Vitals, we've made the web a significantly faster and more enjoyable place to be. We look forward to continuing this journey together, making the web better for everyone, everywhere.</span></p><span style="font-size: 10pt;"><br /></span><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: xx-small; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">Posted by Addy Osmani, Annie Sullivan and Kouhei Ueno, Software Engineers for Chrome</span></p><span style="font-size: 10pt;"><br /></span></span></div></span></div> <span itemprop='author' itemscope='itemscope' itemtype='http://schema.org/Person'> <meta content='https://plus.google.com/116899029375914044550' itemprop='url'/> </span> </script> <noscript> <div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmp1qvDcNBZtkhpYpK-Ly3iyOHgmGT9L3c8nQlJFRy6ncMfwdblt0BYX_j3zBBRqSA9wrnKdeth6rOtS325MPGr0CNesGPFa4ZS83FLR0lcxFfKkarvl2OZcOgEb4XloVsDLvr1a3h_5YBQSX4ZdLdx2cuQyUdsbcDp2FYZzjJWGnVdlvEzxxv2asH_yT8/s400/Fast%20Curious_image.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="166" data-original-width="400" height="166" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmp1qvDcNBZtkhpYpK-Ly3iyOHgmGT9L3c8nQlJFRy6ncMfwdblt0BYX_j3zBBRqSA9wrnKdeth6rOtS325MPGr0CNesGPFa4ZS83FLR0lcxFfKkarvl2OZcOgEb4XloVsDLvr1a3h_5YBQSX4ZdLdx2cuQyUdsbcDp2FYZzjJWGnVdlvEzxxv2asH_yT8/w400-h166/Fast%20Curious_image.png" width="400" /></a></div><br /><span face="Arial, sans-serif" style="font-size: 10pt; font-style: italic; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><br /></span><p></p><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span face="Arial, sans-serif" style="font-size: 10pt; font-style: italic; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">T</span><span face="Arial, sans-serif" style="font-size: 10pt; font-style: italic; white-space-collapse: preserve;">oday’s The Fast and the Curious post explores how Core Web Vitals saved Chrome users more than 10,000 Years of waiting for web pages to load in 2023 (across Chrome desktop and Android) by quantifying the experience of sites and identifying opportunities to make improvements.</span></p><br /><br /><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span face="Arial, sans-serif" style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">In 2020, we introduced </span><a href="https://web.dev/vitals/" style="text-decoration-line: none;"><span face="Arial, sans-serif" style="color: #1155cc; font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">Web Vitals</span></a><span face="Arial, sans-serif" style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> - essential quality signals for webpages to ensure a better user experience. Since then, there has been a massive leap in web performance made possible by our work on Core Web Vitals (CWV) and its broader impact on the web. Today, over 40% of sites pass all of the CWV metrics, leading to pages that load and respond to interactions more quickly. Here’s a closer look at the journey to help improve the performance for sites and some specific work done in the browser and the ecosystem to enable this achievement. </span></p><br /><br /><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span face="Arial, sans-serif" style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-weight: 700; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-size: large;">Chrome's Quest for Speed</span></span></p><br /><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span face="Arial, sans-serif" style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">The very essence of the web lies in its ability to provide information and services efficiently and rapidly. This principle is at the heart of Google's business and drives our work on Chrome. However, we noticed an issue with sites over a long time horizon. Even if slow sites improved their performance for a while, it would often decline over time. No matter how fast Google Search might be, the user experience would be subpar if the pages found were slow to load.</span></p><br /><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span face="Arial, sans-serif" style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">We could not help these sites improve their performance directly, but we wanted users to have a great experience when they moved from Google Search to the individual sites. To tackle the challenge of improving the user experience while simultaneously providing unified guidance to developers, teams from Search and Chrome collaborated to address the issue of slow web pages.</span></p><br /><br /><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span face="Arial, sans-serif" style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-weight: 700; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-size: large;">Defining the Fast Web </span></span></p><br /><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span face="Arial, sans-serif" style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">We examined millions of pages to define a public standard for a fast, user-friendly web page (initially published in </span><a href="https://blog.chromium.org/2020/05/the-science-behind-web-vitals.html" style="text-decoration-line: none;"><span face="Arial, sans-serif" style="color: #1155cc; font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">The Science Behind Web Vitals</span></a><span face="Arial, sans-serif" style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">). We published our specifications and data to the open ecosystem and took note of the feedback we received. The introduction of CWV metrics such as </span><a href="https://web.dev/articles/lcp" style="text-decoration-line: none;"><span face="Arial, sans-serif" style="color: #1155cc; font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">LCP</span></a><span face="Arial, sans-serif" style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> (Largest Contentful Paint) was groundbreaking because it allowed us to measure when the user actually sees the content. The ability to measure the actual user experience at scale has been foundational to the improvements that we will discuss in this blog post.</span></p><br /><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span face="Arial, sans-serif" style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">Next, we updated Google's search ranking algorithms in August 2021 to consider, among other factors, whether a page met the speed and usability standards established as part of CWV. Today, it remains </span><a href="https://developers.google.com/search/docs/appearance/page-experience#core-web-vitals" style="text-decoration-line: none;"><span face="Arial, sans-serif" style="color: #1155cc; font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">highly recommended</span></a><span face="Arial, sans-serif" style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> for site owners to achieve good Core Web Vitals for success with Search and to ensure a great user experience generally.</span></p><br /><br /><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span face="Arial, sans-serif" style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-weight: 700; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-size: large;">Exponential Impact of Small Changes</span></span></p><br /><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span face="Arial, sans-serif" style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">The results we saw after these changes were significant. The average page load in Chrome is now 166 ms faster. That might seem like a minor improvement, but small changes can accumulate to create a substantial impact on the web. </span></p><br /><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span face="Arial, sans-serif" style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">So far in 2023, this project saved users over 10,000 years of waiting for web pages to load and over 1,200 years of waiting for web pages to respond to user input. And the web continues to get faster. We also tracked improvements in how many navigations meet Core Web Vitals (CWV). The current figures stand at 64.45% for mobile (up from 64%) and 68.39% for desktop (up from 67%). The Chrome Data team projects a ~69% pass rate by the end of the year.</span></p><div><span face="Arial, sans-serif" style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><br /></span></div><div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJXlVkkM1NpqQVv72HdG9lqOx0BNVa0zA8ALsBeqZI5ZRB-WQt4MDj3SMPDkwFBQt8J8Y3d6f2TaWpz_9dHjdNUNTTaNIduP5aD-y1_c_c980qRKByLSQDcZ8RVx6v3YwE__etQlQAUwTKaJJKhYQZYpyewk-QBA5apndz0w6jjdPsWhANwHhQxOYXML1r/s954/Screenshot%202023-11-06%20at%209.45.17%E2%80%AFAM.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="536" data-original-width="954" height="360" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJXlVkkM1NpqQVv72HdG9lqOx0BNVa0zA8ALsBeqZI5ZRB-WQt4MDj3SMPDkwFBQt8J8Y3d6f2TaWpz_9dHjdNUNTTaNIduP5aD-y1_c_c980qRKByLSQDcZ8RVx6v3YwE__etQlQAUwTKaJJKhYQZYpyewk-QBA5apndz0w6jjdPsWhANwHhQxOYXML1r/w640-h360/Screenshot%202023-11-06%20at%209.45.17%E2%80%AFAM.png" title="Caption: Our savings for LCP translate into 8,000 years saved for users waiting for pages to load on Android and 2,000 years in 2023 so far. On INP, we have saved users 800 years on Android and 450 years on Windows so far in 2023." width="640" /></a></div><span face="Arial, sans-serif" style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span id="docs-internal-guid-d3bb3188-7fff-d2e6-9ed6-dd110b96dabe"><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><i><span id="docs-internal-guid-ec2eec2f-7fff-9721-9c42-de5217fb0a87"></span></i></p><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span face="Arial, sans-serif" style="color: black; font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><i>Caption: Our savings for LCP translate into 8,000 years saved for users waiting for pages to load on Android and 2,000 years in 2023 so far. On INP, we have saved users 800 years on Android and 450 years on Windows so far in 2023.</i></span></p><div><br /></div></span></span></div><div><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><p dir="ltr" style="font-family: Arial, sans-serif; font-size: 10pt; line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt; white-space-collapse: preserve;"><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">Next, let’s look at some recent updates from both the Chrome team and the wider developer ecosystem, demonstrating how our joint efforts are speeding up the web.</span></p><span face="Arial, sans-serif" style="font-size: 10pt; white-space-collapse: preserve;"><br /><br /></span><p dir="ltr" style="font-family: Arial, sans-serif; line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt; white-space-collapse: preserve;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-weight: 700; vertical-align: baseline;"><span style="font-size: large;">Chrome’s Core Web Vitals Achievements</span></span></p><br /><p dir="ltr" style="font-family: Arial, sans-serif; font-size: 10pt; line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt; white-space-collapse: preserve;"><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">We’re proud to highlight numerous ways we’ve optimized performance. </span></p><span face="Arial, sans-serif" style="font-size: 10pt; white-space-collapse: preserve;"><br /></span><ul style="font-family: Arial, sans-serif; font-size: 10pt; margin-bottom: 0px; margin-top: 0px; padding-inline-start: 48px; white-space-collapse: preserve;"><li aria-level="1" dir="ltr" style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; list-style-type: disc; text-wrap: nowrap; vertical-align: baseline;"><p dir="ltr" role="presentation" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap: wrap; vertical-align: baseline;">The </span><a href="https://web.dev/articles/bfcache" style="text-decoration-line: none;"><span style="color: #1155cc; font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; text-wrap: wrap; vertical-align: baseline;">Back/forward cache</span></a><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap: wrap; vertical-align: baseline;"> (bfcache) is designed to improve browsing experience by enabling instant back and forward navigation. BFCache’s hit rate has improved month-over-month on both Android (3.6%) and Desktop (1.8%).</span></p></li></ul><span face="Arial, sans-serif" style="font-size: 10pt; white-space-collapse: preserve;"><br /></span><ul style="font-family: Arial, sans-serif; font-size: 10pt; margin-bottom: 0px; margin-top: 0px; padding-inline-start: 48px; white-space-collapse: preserve;"><li aria-level="1" dir="ltr" style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; list-style-type: disc; text-wrap: nowrap; vertical-align: baseline;"><p dir="ltr" role="presentation" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap: wrap; vertical-align: baseline;">Another example of a particularly impactful optimization is our PreconnectOnAnchorInteraction feature which connects to origins on pointer-down rather than pointer-up. This fully launched feature led to a 6/10ms (0.4/1%) median LCP improvement on Android/Desktop, and an improvement in cross-origin LCP by ~60ms on both Android and Desktop. The launch also resulted in a 0.08% Content Ad revenue increase, underlining the significant impact of performance optimizations on user engagement and ecosystem health.</span></p></li></ul><span face="Arial, sans-serif" style="font-size: 10pt; white-space-collapse: preserve;"><br /></span><ul style="font-family: Arial, sans-serif; font-size: 10pt; margin-bottom: 0px; margin-top: 0px; padding-inline-start: 48px; white-space-collapse: preserve;"><li aria-level="1" dir="ltr" style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; list-style-type: disc; text-wrap: nowrap; vertical-align: baseline;"><p dir="ltr" role="presentation" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap: wrap; vertical-align: baseline;">We also introduced </span><a href="https://developer.chrome.com/blog/prerender-pages/" style="text-decoration-line: none;"><span style="color: #1155cc; font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; text-wrap: wrap; vertical-align: baseline;">prerendering</span></a><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap: wrap; vertical-align: baseline;">, which makes pages load instantly by rendering them before the user actually visits. Page loads via typing URLs directly in the omnibox get a 500-700ms (14-25%) median LCP improvement when prerendered, depending on the platform, moving global median LCP across all navigations by 6.4ms. We're currently rolling out prerendering of omnibox-initiated searches.</span></p></li></ul><span face="Arial, sans-serif" style="font-size: 10pt; white-space-collapse: preserve;"><br /></span><ul style="font-family: Arial, sans-serif; font-size: 10pt; margin-bottom: 0px; margin-top: 0px; padding-inline-start: 48px; white-space-collapse: preserve;"><li aria-level="1" dir="ltr" style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; list-style-type: disc; text-wrap: nowrap; vertical-align: baseline;"><p dir="ltr" role="presentation" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap: wrap; vertical-align: baseline;">Chrome has been working hard to keep background tabs out of your way. Implementing </span><a href="https://blog.chromium.org/2020/11/tab-throttling-and-more-performance.html" style="text-decoration-line: none;"><span style="color: #1155cc; font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; text-wrap: wrap; vertical-align: baseline;">tab throttling for background tabs</span></a><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap: wrap; vertical-align: baseline;"> running at EcoQOS on Windows 11 and Task Role and QoS Adjustments on macOS have led to improvements in Largest Contentful Paint (</span><a href="http://web.dev/lcp" style="text-decoration-line: none;"><span style="color: #1155cc; font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; text-wrap: wrap; vertical-align: baseline;">LCP</span></a><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap: wrap; vertical-align: baseline;">) and Interaction to Next Paint (</span><a href="https://web.dev/articles/inp" style="text-decoration-line: none;"><span style="color: #1155cc; font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; text-wrap: wrap; vertical-align: baseline;">INP</span></a><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap: wrap; vertical-align: baseline;">). </span><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap: wrap; vertical-align: baseline;"><br /><br /></span></p></li><li aria-level="1" dir="ltr" style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; list-style-type: disc; text-wrap: nowrap; vertical-align: baseline;"><p dir="ltr" role="presentation" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap: wrap; vertical-align: baseline;">The web’s modern ability to run all types of applications also comes with a mandate to manage the workload that this encurs. We have been optimizing Chrome under mutliple active tabs and are happy to report improvements to scheduling and contention which improve INP by 5% and LCP by 2% in the last 6 months.</span></p></li></ul><span face="Arial, sans-serif" style="font-size: 10pt; white-space-collapse: preserve;"><br /></span><ul style="font-family: Arial, sans-serif; font-size: 10pt; margin-bottom: 0px; margin-top: 0px; padding-inline-start: 48px; white-space-collapse: preserve;"><li aria-level="1" dir="ltr" style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; list-style-type: disc; text-wrap: nowrap; vertical-align: baseline;"><p dir="ltr" role="presentation" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap: wrap; vertical-align: baseline;">We have made targeted improvements to the page loading code in Chrome in 2022. These resulted in LCP improving by 10% on Android, and CWV pass rate improving by 1.5%.</span></p></li></ul><span face="Arial, sans-serif" style="font-size: 10pt; white-space-collapse: preserve;"><br /></span><ul style="font-family: Arial, sans-serif; font-size: 10pt; margin-bottom: 0px; margin-top: 0px; padding-inline-start: 48px; white-space-collapse: preserve;"><li aria-level="1" dir="ltr" style="color: #0e101a; font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; list-style-type: disc; text-wrap: nowrap; vertical-align: baseline;"><p dir="ltr" role="presentation" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap: wrap; vertical-align: baseline;">Chrome's renderer has also seen some improvements. The renderer's main thread includes task queues for JavaScript, rendering, and image loading. Some changes that alter the priority of these tasks for optimal CWV include.</span></p></li><ul style="margin-bottom: 0px; margin-top: 0px; padding-inline-start: 48px;"><li aria-level="2" dir="ltr" style="color: #0e101a; font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; list-style-type: disc; text-wrap: nowrap; vertical-align: baseline;"><p dir="ltr" role="presentation" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-weight: 700; text-wrap: wrap; vertical-align: baseline;">High priority image loading: </span><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap: wrap; vertical-align: baseline;">Historically, image-loading had the same or lower priority than rendering. However, an experiment showed that between an image load task and a rendering task, choosing the image load task first can prevent layout shift of an intermediate frame that doesn't have the image and also improves LCP. The improvement on Android at the 75th percentile was </span><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-weight: 700; text-wrap: wrap; vertical-align: baseline;">-6.66%</span><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap: wrap; vertical-align: baseline;"> for CLS and </span><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-weight: 700; text-wrap: wrap; vertical-align: baseline;">-0.82%</span><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap: wrap; vertical-align: baseline;"> for LCP, improving the CWV pass rate on Android by </span><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-weight: 700; text-wrap: wrap; vertical-align: baseline;">+0.24%.</span><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap: wrap; vertical-align: baseline;"> A similar experiment that boosted the loading priority to "medium" of the first five images parsed from the HTML (for non-icon-sized images) showed an improvement on Android at the 75th percentile of </span><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-weight: 700; text-wrap: wrap; vertical-align: baseline;">-6.08%</span><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap: wrap; vertical-align: baseline;"> for CLS and </span><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-weight: 700; text-wrap: wrap; vertical-align: baseline;">-0.53%</span><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap: wrap; vertical-align: baseline;"> for LCP. A combined experiment showed the effects of both changes were largely independent. </span></p></li><li aria-level="2" dir="ltr" style="color: #0e101a; font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; list-style-type: disc; text-wrap: nowrap; vertical-align: baseline;"><p dir="ltr" role="presentation" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-weight: 700; text-wrap: wrap; vertical-align: baseline;">Prioritize compositing after delay: </span><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap: wrap; vertical-align: baseline;">If it has been more than 100ms since the last </span><a href="https://developer.chrome.com/blog/inside-browser-part3/#what-is-compositing" style="text-decoration-line: none;"><span style="color: #1155cc; font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; text-wrap: wrap; vertical-align: baseline;">compositing</span></a><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap: wrap; vertical-align: baseline;"> task run, elevate the priority of any queued compositing task so that it will preempt normal-priority work. This produced an improvement of </span><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-weight: 700; text-wrap: wrap; vertical-align: baseline;">-0.27%</span><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap: wrap; vertical-align: baseline;"> for CLS on Android and Windows at the 95th percentile.</span></p></li><li aria-level="2" dir="ltr" style="color: #0e101a; font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; list-style-type: disc; text-wrap: nowrap; vertical-align: baseline;"><p dir="ltr" role="presentation" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-weight: 700; text-wrap: wrap; vertical-align: baseline;">SVG Raster Optimizations</span><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap: wrap; vertical-align: baseline;">: Another SVG drawing optimization improved INP pass rates on desktops by -2.28% for MacOS at the 75th percentile. </span></p></li></ul></ul><div style="font-family: Arial, sans-serif; font-size: 10pt; white-space-collapse: preserve;"><span style="color: #0e101a;"><br /></span></div><div><div class="separator" style="clear: both; font-family: Arial, sans-serif; font-size: 10pt; text-align: center; white-space-collapse: preserve;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiKRmZM0AQmYrx8wvUc0LqtpIwpGOgGPcPGqTeezyXUM0q1WY_TP_AN9UJno42Eutj7xBDlzFUCN0yM_MItJU_hb4fqPl2LCQVR66p6lHoGqRjiEAh1R39eFrSgwZW9uNmIsxWmtl-9SEQyQxb51x_XD1vwLi1JhI3eIa5uCMvxXbRj5WQDrIERvHwGkL-V/s816/video.gif" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="312" data-original-width="816" height="244" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiKRmZM0AQmYrx8wvUc0LqtpIwpGOgGPcPGqTeezyXUM0q1WY_TP_AN9UJno42Eutj7xBDlzFUCN0yM_MItJU_hb4fqPl2LCQVR66p6lHoGqRjiEAh1R39eFrSgwZW9uNmIsxWmtl-9SEQyQxb51x_XD1vwLi1JhI3eIa5uCMvxXbRj5WQDrIERvHwGkL-V/w640-h244/video.gif" width="640" /></a></div><br /><span style="color: #0e101a;"><i><span face="Arial, sans-serif"><span style="font-size: 13.3333px; white-space-collapse: preserve;">Caption: An example of Chrome’s new prioritized loading of the first five images parsed from the HTML. This improved LCP from 3.1s to 2.5s.</span></span></i></span></div><div><br /></div><div style="font-family: Arial, sans-serif; font-size: 10pt; white-space-collapse: preserve;"><span style="color: #0e101a;"><br /></span></div><div><span face="Arial, sans-serif" id="docs-internal-guid-834c64f4-7fff-cc90-0d9c-3e0473aa2cc9" style="white-space-collapse: preserve;"><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-weight: 700; vertical-align: baseline;"><span style="font-size: large;">Ecosystem Core Web Vitals Achievements</span></span></p><br /><p dir="ltr" style="font-size: 10pt; line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">The broader developer ecosystem has also achieved remarkable results by focusing on Core Web Vitals. </span><span style="color: #0e101a; font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">The most significant achievement was the performance improvement on WordPress - the Content Management System that powers over a third of the web: "</span><a href="https://make.wordpress.org/core/2023/08/07/wordpress-6-3-performance-improvements/" style="text-decoration-line: none;"><span style="color: #4a6ee0; font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline;">WordPress 6.3</span></a><span style="color: #0e101a; font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"> loads 27% faster for block themes and 18% faster for classic themes, compared to WordPress 6.2, based on the </span><a href="https://web.dev/articles/lcp" style="text-decoration-line: none;"><span style="color: #1155cc; font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline;">Largest Contentful Paint (LCP)</span></a><span style="color: #0e101a; font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"> metric". </span></p><p dir="ltr" style="font-size: 10pt; line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="color: #0e101a; font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><br /></span></p><p dir="ltr" style="font-size: 10pt; line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="color: #0e101a; font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><span id="docs-internal-guid-16173b3d-7fff-b359-9440-045d3b2d504d"><span style="color: black; font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">Some parts of the WordPress ecosystem are going even further. Prerendering some links via the </span><a href="https://developer.chrome.com/blog/prerender-pages/" style="text-decoration-line: none;"><span style="color: #1155cc; font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline;">speculation rules API</span></a><span style="color: black; font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">, </span><a href="https://nitropack.io/" style="text-decoration-line: none;"><span style="color: #1155cc; font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline;">NitroPack</span></a><span style="color: black; font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">'s prerendered page loads have seen an 80% LCP improvement and 55% INP improvement compared to those without any speculative loading.</span></span></span></p><p dir="ltr" style="font-size: 10pt; line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="color: #0e101a; font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><span><span style="color: black; font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><br /></span></span></span></p><p dir="ltr" style="font-size: 10pt; line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="color: #0e101a; font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><span></span></span></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxjcDZR8KcnwqG2wWjgsZP6vE1uCcUGuNCMCjORJUjoFBe2PBclSgQfNz4S21j4H7d8snA6gQUwewxoSjJEDK76Yt1NAaXjYnvmAYa9HI-P_pn6Ue7hN321LQsiPldKNt1DUz8nwqMX6AXb1GNRlHR_xOLnwfbDjSn6w0EszDNYU0F4miZnva8h-l75z4O/s984/Screenshot%202023-11-06%20at%209.48.00%E2%80%AFAM.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="620" data-original-width="984" height="404" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxjcDZR8KcnwqG2wWjgsZP6vE1uCcUGuNCMCjORJUjoFBe2PBclSgQfNz4S21j4H7d8snA6gQUwewxoSjJEDK76Yt1NAaXjYnvmAYa9HI-P_pn6Ue7hN321LQsiPldKNt1DUz8nwqMX6AXb1GNRlHR_xOLnwfbDjSn6w0EszDNYU0F4miZnva8h-l75z4O/w640-h404/Screenshot%202023-11-06%20at%209.48.00%E2%80%AFAM.png" width="640" /></a></div><br /></span><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 13.3333px; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span face="Arial, sans-serif"><i>Caption: The percentage of origins passing all three Core Web Vitals (LCP, FID, CLS) with a "good" experience (Source: <a href="https://httparchive.org/reports/chrome-ux-report#cruxPassesCWV">HTTP Archive</a>) </i></span></span></p><div style="font-family: Arial, sans-serif; white-space-collapse: preserve;"><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><br /></span></div><p dir="ltr" style="font-family: Arial, sans-serif; font-size: 10pt; line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt; white-space-collapse: preserve;"><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">The JavaScript framework community has also seen Core Web Vital gains. Over the past few years, </span><a href="https://developers.chrome.com/aurora" style="font-size: 10pt; text-decoration-line: none;"><span style="color: #1155cc; font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline;">Chrome Aurora</span></a><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"> has collaborated with Next.js, Angular, and Nuxt to release performance-focused features like the </span><a href="https://nextjs.org/docs/app/building-your-application/optimizing/scripts" style="font-size: 10pt; text-decoration-line: none;"><span style="color: #1155cc; font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline;">next/script component</span></a><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">, </span><a href="https://angular.io/guide/image-directive" style="font-size: 10pt; text-decoration-line: none;"><span style="color: #1155cc; font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline;">NgOptimizedImage</span></a><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">, and </span><a href="https://google-fonts.nuxtjs.org/" style="font-size: 10pt; text-decoration-line: none;"><span style="color: #1155cc; font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline;">nuxt/google-fonts</span></a><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">. In 2022, Next.js pass rates increased from 20.4% to 27.3%, Angular pass rates increased from 7.6% to 13.2%, and Nuxt pass rates increased from 15.8% to 20.2%. Enterprise partners who tried our features have seen wins in LCP. For example, after switching to NgOptimizedImage, Land's End saw a 40% LCP improvement on mobile in Lighthouse lab tests and a 75% improvement in LCP on desktop. In similar tests, CareerKarma's LCP reduced 24% when switching to next/script's web worker mode. </span></p></div><div style="font-family: Arial, sans-serif; white-space-collapse: preserve;"><span id="docs-internal-guid-9f3dc149-7fff-0670-014d-856f9e066f27"><span style="font-size: 10pt;"><br /></span><p dir="ltr" style="font-size: 10pt; line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">In the business world, performance optimization has led to remarkable growth. For instance, RedBus improved INP and observed a </span><a href="https://web.dev/case-studies/redbus-inp" style="text-decoration-line: none;"><span style="color: #1155cc; font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline;">7%</span></a><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"> increase in conversion rates. Economic Times improved INP and saw a </span><a href="https://web.dev/case-studies/economic-times-inp" style="text-decoration-line: none;"><span style="color: #1155cc; font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline;">42%</span></a><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"> rise in page views and a 49% reduction in bounce rate. Meesho successfully brought LCP down from 6.9s to 2.5s, resulting in a 16.6% reduction in bounce rate and a 3% increase in conversions.</span></p><span style="font-size: 10pt;"><br /></span><p dir="ltr" style="font-size: 10pt; line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">Major web platforms have also seen significant improvements. Amazon has leveraged the bfcache change introduced on Chrome and saw a 22.7 percentage point (pp) improvement in bfcache hit rate with Chrome's latest version (M112). Cricbuzz experienced an even higher increase, with a 31.40 pp improvement.</span></p><span style="font-size: 10pt;"><br /><br /></span><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-weight: 700; vertical-align: baseline;"><span style="font-size: large;">Partnering for a Better Web </span></span></p><br /><p dir="ltr" style="font-size: 10pt; line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">These performance improvements aren't just statistics – they represent real-world improvements in user experience (and hence </span><a href="https://web.dev/case-studies/terra-prefetching-case-study" style="text-decoration-line: none;"><span style="color: #1155cc; font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline;">business metrics</span></a><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">) as well as developer experience.</span></p><p dir="ltr" style="font-size: 10pt; line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"> </span></p><p dir="ltr" style="font-size: 10pt; line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">Crucially, we have managed to achieve these speed boosts without impacting developer satisfaction, which remains high at 90% overall. Through our developer satisfaction studies, we also found that about half (~51%) of developers are monitoring CWV and are either already optimizing for them or planning to do so. Furthermore, a significant majority (78%) of developers optimizing for CWV report seeing notable improvements in their scores.</span></p><span style="font-size: 10pt;"><br /></span><p dir="ltr" style="font-size: 10pt; line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">Our aim is always to create a better web experience for all users, so we're excited to see the web getting faster. But we also understand that maintaining developer satisfaction is crucial to sustaining these improvements. As developers continue to monitor and optimize for CWV, we are optimistic about the future of web performance.</span></p><span style="font-size: 10pt;"><br /></span><p dir="ltr" style="font-size: 10pt; line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">On behalf of the Chrome team, we want to thank the developer community for their incredible work. By focusing on Core Web Vitals, we've made the web a significantly faster and more enjoyable place to be. We look forward to continuing this journey together, making the web better for everyone, everywhere.</span></p><span style="font-size: 10pt;"><br /></span><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: xx-small; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">Posted by Addy Osmani, Annie Sullivan and Kouhei Ueno, Software Engineers for Chrome</span></p><span style="font-size: 10pt;"><br /></span></span></div></span></div> <span itemprop='author' itemscope='itemscope' itemtype='http://schema.org/Person'> <meta content='https://plus.google.com/116899029375914044550' itemprop='url'/> </span> </noscript> </div> </div> <div class='share'> <span class='twitter-custom social-wrapper' data-href='http://twitter.com/share?text=Chromium Blog:How Core Web Vitals saved users 10,000 years of waiting for web pages to load&url=https://blog.chromium.org/2023/11/how-core-web-vitals-saved-users-10000.html&via=ChromiumDev'> <img alt='Share on Twitter' height='24' src='https://www.gstatic.com/images/icons/material/system/2x/post_twitter_black_24dp.png' width='24'/> </span> <span class='fb-custom social-wrapper' data-href='https://www.facebook.com/sharer.php?u=https://blog.chromium.org/2023/11/how-core-web-vitals-saved-users-10000.html'> <img alt='Share on Facebook' height='24' src='https://www.gstatic.com/images/icons/material/system/2x/post_facebook_black_24dp.png' width='24'/> </span> </div> <div class='post-footer'> <div class='cmt_iframe_holder' data-href='https://blog.chromium.org/2023/11/how-core-web-vitals-saved-users-10000.html' data-viewtype='FILTERED_POSTMOD'></div> <a href='https://plus.google.com/112374322230920073195' rel='author' style='display:none;'> Google </a> <div class='label-footer'> <span class='labels-caption'> Labels: </span> <span class='labels'> <a class='label' href='https://blog.chromium.org/search/label/the%20fast%20and%20the%20curious' rel='tag'> the fast and the curious </a> </span> </div> </div> </div> <div class='post' data-id='1439009818036823761' itemscope='' itemtype='http://schema.org/BlogPosting'> <h2 class='title' itemprop='name'> <a href='https://blog.chromium.org/2023/08/smoothing-out-scrolling-experience-in.html' itemprop='url' title='Smoothing out the scrolling experience in Chrome on Android'> Smoothing out the scrolling experience in Chrome on Android </a> </h2> <div class='post-header'> <div class='published'> <span class='publishdate' itemprop='datePublished'> Tuesday, August 8, 2023 </span> </div> </div> <div class='post-body'> <div class='post-content' itemprop='articleBody'> <script type='text/template'> <div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhpoMaNCAyCY0wVpANeUERPRp6miTiafH8k4S4AagpE-y8noUhB-GdcmfAlpDxwZBdzjEXQOBAdPiuBAwNbUmVDTj9B9EMQ6Ty_8UI1zv1BpEgdM2BT8JX-Im1KGOE4QgtP9wVV-muo5aPVDWNzpd3RZjoecWQ_VA0Ty3WsEDbFChvDdkhBa-_JJmGpJrco/s400/Fast%20Curious_image.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="166" data-original-width="400" height="166" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhpoMaNCAyCY0wVpANeUERPRp6miTiafH8k4S4AagpE-y8noUhB-GdcmfAlpDxwZBdzjEXQOBAdPiuBAwNbUmVDTj9B9EMQ6Ty_8UI1zv1BpEgdM2BT8JX-Im1KGOE4QgtP9wVV-muo5aPVDWNzpd3RZjoecWQ_VA0Ty3WsEDbFChvDdkhBa-_JJmGpJrco/w400-h166/Fast%20Curious_image.png" width="400" /></a></div><br /><div><br /></div><br /><div><span id="docs-internal-guid-9457062a-7fff-5168-fb93-4991e2387095"><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span face="Arial, sans-serif" style="color: #424242; font-size: 11pt; font-style: italic; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space-collapse: preserve;">Big performance wins can be found by taking a step back and tweaking what you already have. Today’s</span><a href="https://blog.chromium.org/search/label/the%20fast%20and%20the%20curious" style="text-decoration-line: none;"><span face="Arial, sans-serif" style="color: #424242; font-size: 11pt; font-style: italic; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space-collapse: preserve;"> </span><span face="Arial, sans-serif" style="color: #1155cc; font-size: 11pt; font-style: italic; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">The Fast and the Curious</span></a><span face="Arial, sans-serif" style="color: #424242; font-size: 11pt; font-style: italic; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space-collapse: preserve;"> post explores how we improved the scrolling experience of Chrome on Android, ultimately reducing slow scrolling jank by 2x. Read on to see </span><span face="Arial, sans-serif" style="font-size: 11pt; font-style: italic; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space-collapse: preserve;">how we discovered and evaluated the problem, and how that has helped us design a better browser experience going forward.</span></p><br /><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space-collapse: preserve;">When measuring the performance of a browser, one might typically think of page load speed or </span><a href="https://web.dev/vitals/" style="text-decoration-line: none;"><span face="Arial, sans-serif" style="color: #1155cc; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">Web Vitals</span></a><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space-collapse: preserve;">. On mobile where touch interactions are common we also prioritize your interaction with Chrome to ensure it is always smooth and responsive including on new form factors like foldables. A significant focus of late has been on reducing jank while you scroll.</span></p><br /><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space-collapse: preserve;">We recently improved the scrolling experience of Chrome on Android by 2x by filtering noise and reducing visual jumps in the content presented on screen. To get this result, we had to take a step back and figure out the problem of why Chrome on Android was lagging behind Chrome on iOS. </span></p><br /><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space-collapse: preserve;">As we compared Chrome across platforms, we were hit with a particular observation. iOS Chrome scrolling was smooth and consistent whereas on Android, Chrome’s scrolling didn't follow your finger as closely. However, our metrics were telling us that while janks occurred occasionally, they weren’t as common as our perception when comparing with Chrome on iOS. Thus we had ourselves a mystery which needed some investigation.</span></p><br /><h1 dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span face="Arial, sans-serif" style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-size: medium;">Investigating input to output rate</span></span></h1><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space-collapse: preserve;">Our metrics flagged that we often received input at an inconsistent rate; but since the input rate was greater than the display’s frame rate, we usually had at least one input event to trigger the production of a frame to display. However, this frame might have consumed fewer or more input events, which could result in inconsistent shifting of content on screen even while scrolling at a fixed speed.</span></p><br /><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space-collapse: preserve;">This problem of different input rate vs frame rate is a problem that Chrome has had to address before. Internally, we resample input to predict/extrapolate where the finger was at a consistent point relative to the frame we want to produce. This should result in each frame representing a consistent amount of time and should mean smooth scrolling regardless of noise in the input events. The ideal scenario is illustrated in the following diagram where blue dots are real input events, green are resampled input events, and the displayed scroll deltas would fluctuate if you were to use the real input events rather than resampling.</span></p><div><span><br /></span></div><div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEioehuGvCdB4KM2GHsyak1760cuz8pnEtpNFCF4UMVGg-BOpO0gvzJ6e7zwnBFymB1b5pfgsPTRXyMGZFYw9YDCItmyX5cW_ZyoQqc6O7a-gOT1LgbKh-nGYnPdUh7i4xaUmUv8mgVPQj63erls0RVE2qa-BygRtPx-jJuVuIBrTdfYPve8wnxGWqvdrPNY/s871/input_sampling_rate.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="376" data-original-width="871" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEioehuGvCdB4KM2GHsyak1760cuz8pnEtpNFCF4UMVGg-BOpO0gvzJ6e7zwnBFymB1b5pfgsPTRXyMGZFYw9YDCItmyX5cW_ZyoQqc6O7a-gOT1LgbKh-nGYnPdUh7i4xaUmUv8mgVPQj63erls0RVE2qa-BygRtPx-jJuVuIBrTdfYPve8wnxGWqvdrPNY/s16000/input_sampling_rate.png" /></a></div><br /><span><br /></span></div><br /><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space-collapse: preserve;">Okay so we already do resampling so what's the problem?</span></p><br /><h1 dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span face="Arial, sans-serif" style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-size: medium;">A tale of woe and reimplementation</span></span></h1><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space-collapse: preserve;">Input resampling inside of Chrome (and Android) were added back in 2019 as 90hz devices emerged and the problem above became more apparent (oscillating between 2 vs 1 input events per frame rather than consistently 2 input events per frame we usually see on 60hz devices). Android implemented multiple resampling algorithms (kalman, linear, etc.) and arrived at the conclusion that linear resampling (drawing a line between two points to figure out velocity and then extrapolate to the given timestamp) was good enough for their use cases. This fixed the problem for most Android apps, but didn't address Chrome.</span></p><br /><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space-collapse: preserve;">Due to historical reasons and web spec requirements for raw input, Chrome uses unbuffered input and thus as devices started to appear with sampling rates that didn’t fit with input, Chrome had to implement some version of resampling. Below we see that each frame (measuring the time from input to it being displayed) consumes a different amount of input events (2 for the first, 3 for the second, and 1 for the third), if we assume input is consistently arriving and each is exactly 30 pixels of displacement then ideally we should smooth it out to 60 pixels per frame as seen below:</span></p><div><span><br /></span></div><div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9UMsfJShkzjJlqDxDl0Fr7pFOI0zIWkhD49X-DT8m-Uca8PB6JhA5TiR6Wz_SuAzaANgo9X9D4gHCTbm8UdXtwcLLmnVmLsBRZwI6yezCEie6bD-kW4_nGBi277ZFoVqeF3Orzj7Ks_--vpAj4RqtTxon_EAhBIaOk-nXIkyH_4NP4AeXuF_W-lO-a2-N/s659/frame_predictor_timeline.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="383" data-original-width="659" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9UMsfJShkzjJlqDxDl0Fr7pFOI0zIWkhD49X-DT8m-Uca8PB6JhA5TiR6Wz_SuAzaANgo9X9D4gHCTbm8UdXtwcLLmnVmLsBRZwI6yezCEie6bD-kW4_nGBi277ZFoVqeF3Orzj7Ks_--vpAj4RqtTxon_EAhBIaOk-nXIkyH_4NP4AeXuF_W-lO-a2-N/s16000/frame_predictor_timeline.png" /></a></div><br /><span><br /></span></div><br /><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space-collapse: preserve;">However, while we were investigating the original mystery we discovered that reality was very different from the ideal situation pictured above. We found that the actual input movement of the screen was quite spiky and inconsistent (more than we expected) and that our predictor was improving things but not as much as desired. On the left is real finger displacement on a screen (each point is an input event) and on the right the result of our predictor of actual content offset after smoothing out (each point is a frame)</span></p><div><span><br /></span></div><div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3sPk_SBDZbule8elIeQmsz5HIGd21jo6gDBwDKu_YlVp4xR2AUnEqhIM8Mr4zU4jVPTR114kX134l6i2szyuX9fFwMeMincKw7uLiicXeuCankKQjsT8TWx7Wwb0m7O5zHz6RTKqSQ4PrfkGGFtSoxX4Y-jtSuzG3kSefQQ2VZpFddopNE-VoeTgs_1uw/s1528/Screenshot%202023-08-07%20at%2010.22.51%20PM.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="496" data-original-width="1528" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3sPk_SBDZbule8elIeQmsz5HIGd21jo6gDBwDKu_YlVp4xR2AUnEqhIM8Mr4zU4jVPTR114kX134l6i2szyuX9fFwMeMincKw7uLiicXeuCankKQjsT8TWx7Wwb0m7O5zHz6RTKqSQ4PrfkGGFtSoxX4Y-jtSuzG3kSefQQ2VZpFddopNE-VoeTgs_1uw/s16000/Screenshot%202023-08-07%20at%2010.22.51%20PM.png" /></a></div><br /><span><br /></span></div><br /><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space-collapse: preserve;">Frames are being presented consistently on the right, but the rate of displacement spikes between one to another isn’t consistent (-50 to -40 followed by another -52 being especially drastic). Human fingers don’t move this discretely (at frame level precision). Rather they should slide and flex in a gradient, speeding up or slowing down gradually. So we knew we had a problem here. We dug deeper into Chrome’s implementation and found there were some fundamental differences in Chrome’s implementation (which was supposedly a copy of Android’s).</span></p><br /></span></div><blockquote style="border: none; margin: 0px 0px 0px 40px; padding: 0px; text-align: left;"><div><span><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space-collapse: preserve;">1. Android uses the native C++ MotionEvent timestamp (with nanosecond precision), but Chrome uses Java </span><a href="https://developer.android.com/reference/android/view/MotionEvent#getEventTime()" style="text-decoration-line: none;"><span face="Arial, sans-serif" style="color: #1155cc; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">MotionEvent.getEventTime</span></a><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space-collapse: preserve;"> & </span><a href="https://developer.android.com/reference/android/view/MotionEvent#getHistoricalEventTime(int)" style="text-decoration-line: none;"><span face="Arial, sans-serif" style="color: #1155cc; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">MotionEvent.getHistoricalEventTime</span></a><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space-collapse: preserve;"> (milliseconds precision). Unfortunately, nanosecond precision was not part of the public API. However, rounding of milliseconds can introduce error into our predictor when it computes velocity between event timestamps.</span></p></span></div><div><span><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space-collapse: preserve;">2. Android’s implementation takes care when selecting the two input events so resampling is using the most relevant events. Chrome however uses a simple FIFO queue of input events, which can result in weird cases of using future events to predict velocity in the past in rare cases on high refresh rate devices.</span></p></span></div></blockquote><div><span><br /><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space-collapse: preserve;">We prototyped using Android’s resampling in Chrome, but found it was still not perfect for Chrome’s architecture resulting in some jank. To improve on it, we experimented with different algorithms, using automation to replay the same input over and over again and evaluating the screen displacement curves. After tuning, this landed at the </span><span face="Arial, sans-serif" style="color: #1155cc; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;"><a href="https://gery.casiez.net/1euro/">1€ filter</a></span><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space-collapse: preserve;"> implementation that visibly and drastically improved the scrolling experience. With this filter, the screen tracks closely to your finger and websites smoothly scroll, preventing jank caused by inconsistent input events. The improvement is visible in our manual validation, on both top-end and low-end devices (<a href="https://drive.google.com/file/d/1KqcWNybFP7kCqBz4mx0vlVzQOqU3IJyb/view?usp=sharing">Here's a redmi 9A video example</a>).</span></p><br /><h1 dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span face="Arial, sans-serif" style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-size: medium;">Going forward!</span></span></h1><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space-collapse: preserve;">In Android 14, the </span><a href="https://developer.android.com/reference/android/view/MotionEvent#getEventTimeNanos()" style="text-decoration-line: none;"><span face="Arial, sans-serif" style="color: #1155cc; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">nanosecond</span></a><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space-collapse: preserve;"> </span><a href="https://developer.android.com/reference/android/view/MotionEvent#getHistoricalEventTimeNanos(int)" style="text-decoration-line: none;"><span face="Arial, sans-serif" style="color: #1155cc; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">API</span></a><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space-collapse: preserve;"> for java MotionEvents will be publicly exposed in the SDK so Chrome (and other apps with unbuffered input) will be able to call it. We also developed new metrics that track the quality of the scroll predictors frame, by creating a test app which introduced pixel level differences between frames (and no other form of jank) and running experiments to see what people would notice. These analysis can be read about </span><span face="Arial, sans-serif" style="color: #1155cc; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;"><a href="https://docs.google.com/document/d/1Y0u0Tq5eUZff75nYUzQVw6JxmbZAW9m64pJidmnGWsY/edit">here</a></span><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space-collapse: preserve;"> and will be used going forward for more exciting performance wins and to make this a visible area for tracking against regressions. In the end, after tuning and enabling the </span><span face="Arial, sans-serif" style="color: #1155cc; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;"><a href="https://gery.casiez.net/1euro/">1€ filter</a></span><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space-collapse: preserve;">, our metrics show a 2x reduction in visible jank while scrolling slowly! This improvement is going live in </span><a href="https://chromium-review.googlesource.com/c/chromium/src/+/4518271" style="text-decoration-line: none;"><span face="Arial, sans-serif" style="color: #1155cc; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">M116</span></a><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space-collapse: preserve;"> as the default, but will be launched all the way back to M110 and brings Chrome on Android on par with Chrome on iOS!</span></p><br /><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space-collapse: preserve;">The moral of the story is: Sometimes metrics don’t cover all the cases and taking a step back and investigating from the top down and getting the lay of the land can end with a superior scrolling experience for users.</span></p><br /><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span face="Arial, sans-serif" style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-size: x-small;">Post by: Stephen Nusko, Chrome Software Engineer</span></span></p><div><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space-collapse: preserve;"><br /></span></div></span></div> <span itemprop='author' itemscope='itemscope' itemtype='http://schema.org/Person'> <meta content='https://plus.google.com/116899029375914044550' itemprop='url'/> </span> </script> <noscript> <div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhpoMaNCAyCY0wVpANeUERPRp6miTiafH8k4S4AagpE-y8noUhB-GdcmfAlpDxwZBdzjEXQOBAdPiuBAwNbUmVDTj9B9EMQ6Ty_8UI1zv1BpEgdM2BT8JX-Im1KGOE4QgtP9wVV-muo5aPVDWNzpd3RZjoecWQ_VA0Ty3WsEDbFChvDdkhBa-_JJmGpJrco/s400/Fast%20Curious_image.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="166" data-original-width="400" height="166" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhpoMaNCAyCY0wVpANeUERPRp6miTiafH8k4S4AagpE-y8noUhB-GdcmfAlpDxwZBdzjEXQOBAdPiuBAwNbUmVDTj9B9EMQ6Ty_8UI1zv1BpEgdM2BT8JX-Im1KGOE4QgtP9wVV-muo5aPVDWNzpd3RZjoecWQ_VA0Ty3WsEDbFChvDdkhBa-_JJmGpJrco/w400-h166/Fast%20Curious_image.png" width="400" /></a></div><br /><div><br /></div><br /><div><span id="docs-internal-guid-9457062a-7fff-5168-fb93-4991e2387095"><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span face="Arial, sans-serif" style="color: #424242; font-size: 11pt; font-style: italic; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space-collapse: preserve;">Big performance wins can be found by taking a step back and tweaking what you already have. Today’s</span><a href="https://blog.chromium.org/search/label/the%20fast%20and%20the%20curious" style="text-decoration-line: none;"><span face="Arial, sans-serif" style="color: #424242; font-size: 11pt; font-style: italic; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space-collapse: preserve;"> </span><span face="Arial, sans-serif" style="color: #1155cc; font-size: 11pt; font-style: italic; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">The Fast and the Curious</span></a><span face="Arial, sans-serif" style="color: #424242; font-size: 11pt; font-style: italic; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space-collapse: preserve;"> post explores how we improved the scrolling experience of Chrome on Android, ultimately reducing slow scrolling jank by 2x. Read on to see </span><span face="Arial, sans-serif" style="font-size: 11pt; font-style: italic; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space-collapse: preserve;">how we discovered and evaluated the problem, and how that has helped us design a better browser experience going forward.</span></p><br /><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space-collapse: preserve;">When measuring the performance of a browser, one might typically think of page load speed or </span><a href="https://web.dev/vitals/" style="text-decoration-line: none;"><span face="Arial, sans-serif" style="color: #1155cc; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">Web Vitals</span></a><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space-collapse: preserve;">. On mobile where touch interactions are common we also prioritize your interaction with Chrome to ensure it is always smooth and responsive including on new form factors like foldables. A significant focus of late has been on reducing jank while you scroll.</span></p><br /><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space-collapse: preserve;">We recently improved the scrolling experience of Chrome on Android by 2x by filtering noise and reducing visual jumps in the content presented on screen. To get this result, we had to take a step back and figure out the problem of why Chrome on Android was lagging behind Chrome on iOS. </span></p><br /><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space-collapse: preserve;">As we compared Chrome across platforms, we were hit with a particular observation. iOS Chrome scrolling was smooth and consistent whereas on Android, Chrome’s scrolling didn't follow your finger as closely. However, our metrics were telling us that while janks occurred occasionally, they weren’t as common as our perception when comparing with Chrome on iOS. Thus we had ourselves a mystery which needed some investigation.</span></p><br /><h1 dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span face="Arial, sans-serif" style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-size: medium;">Investigating input to output rate</span></span></h1><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space-collapse: preserve;">Our metrics flagged that we often received input at an inconsistent rate; but since the input rate was greater than the display’s frame rate, we usually had at least one input event to trigger the production of a frame to display. However, this frame might have consumed fewer or more input events, which could result in inconsistent shifting of content on screen even while scrolling at a fixed speed.</span></p><br /><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space-collapse: preserve;">This problem of different input rate vs frame rate is a problem that Chrome has had to address before. Internally, we resample input to predict/extrapolate where the finger was at a consistent point relative to the frame we want to produce. This should result in each frame representing a consistent amount of time and should mean smooth scrolling regardless of noise in the input events. The ideal scenario is illustrated in the following diagram where blue dots are real input events, green are resampled input events, and the displayed scroll deltas would fluctuate if you were to use the real input events rather than resampling.</span></p><div><span><br /></span></div><div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEioehuGvCdB4KM2GHsyak1760cuz8pnEtpNFCF4UMVGg-BOpO0gvzJ6e7zwnBFymB1b5pfgsPTRXyMGZFYw9YDCItmyX5cW_ZyoQqc6O7a-gOT1LgbKh-nGYnPdUh7i4xaUmUv8mgVPQj63erls0RVE2qa-BygRtPx-jJuVuIBrTdfYPve8wnxGWqvdrPNY/s871/input_sampling_rate.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="376" data-original-width="871" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEioehuGvCdB4KM2GHsyak1760cuz8pnEtpNFCF4UMVGg-BOpO0gvzJ6e7zwnBFymB1b5pfgsPTRXyMGZFYw9YDCItmyX5cW_ZyoQqc6O7a-gOT1LgbKh-nGYnPdUh7i4xaUmUv8mgVPQj63erls0RVE2qa-BygRtPx-jJuVuIBrTdfYPve8wnxGWqvdrPNY/s16000/input_sampling_rate.png" /></a></div><br /><span><br /></span></div><br /><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space-collapse: preserve;">Okay so we already do resampling so what's the problem?</span></p><br /><h1 dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span face="Arial, sans-serif" style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-size: medium;">A tale of woe and reimplementation</span></span></h1><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space-collapse: preserve;">Input resampling inside of Chrome (and Android) were added back in 2019 as 90hz devices emerged and the problem above became more apparent (oscillating between 2 vs 1 input events per frame rather than consistently 2 input events per frame we usually see on 60hz devices). Android implemented multiple resampling algorithms (kalman, linear, etc.) and arrived at the conclusion that linear resampling (drawing a line between two points to figure out velocity and then extrapolate to the given timestamp) was good enough for their use cases. This fixed the problem for most Android apps, but didn't address Chrome.</span></p><br /><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space-collapse: preserve;">Due to historical reasons and web spec requirements for raw input, Chrome uses unbuffered input and thus as devices started to appear with sampling rates that didn’t fit with input, Chrome had to implement some version of resampling. Below we see that each frame (measuring the time from input to it being displayed) consumes a different amount of input events (2 for the first, 3 for the second, and 1 for the third), if we assume input is consistently arriving and each is exactly 30 pixels of displacement then ideally we should smooth it out to 60 pixels per frame as seen below:</span></p><div><span><br /></span></div><div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9UMsfJShkzjJlqDxDl0Fr7pFOI0zIWkhD49X-DT8m-Uca8PB6JhA5TiR6Wz_SuAzaANgo9X9D4gHCTbm8UdXtwcLLmnVmLsBRZwI6yezCEie6bD-kW4_nGBi277ZFoVqeF3Orzj7Ks_--vpAj4RqtTxon_EAhBIaOk-nXIkyH_4NP4AeXuF_W-lO-a2-N/s659/frame_predictor_timeline.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="383" data-original-width="659" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9UMsfJShkzjJlqDxDl0Fr7pFOI0zIWkhD49X-DT8m-Uca8PB6JhA5TiR6Wz_SuAzaANgo9X9D4gHCTbm8UdXtwcLLmnVmLsBRZwI6yezCEie6bD-kW4_nGBi277ZFoVqeF3Orzj7Ks_--vpAj4RqtTxon_EAhBIaOk-nXIkyH_4NP4AeXuF_W-lO-a2-N/s16000/frame_predictor_timeline.png" /></a></div><br /><span><br /></span></div><br /><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space-collapse: preserve;">However, while we were investigating the original mystery we discovered that reality was very different from the ideal situation pictured above. We found that the actual input movement of the screen was quite spiky and inconsistent (more than we expected) and that our predictor was improving things but not as much as desired. On the left is real finger displacement on a screen (each point is an input event) and on the right the result of our predictor of actual content offset after smoothing out (each point is a frame)</span></p><div><span><br /></span></div><div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3sPk_SBDZbule8elIeQmsz5HIGd21jo6gDBwDKu_YlVp4xR2AUnEqhIM8Mr4zU4jVPTR114kX134l6i2szyuX9fFwMeMincKw7uLiicXeuCankKQjsT8TWx7Wwb0m7O5zHz6RTKqSQ4PrfkGGFtSoxX4Y-jtSuzG3kSefQQ2VZpFddopNE-VoeTgs_1uw/s1528/Screenshot%202023-08-07%20at%2010.22.51%20PM.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="496" data-original-width="1528" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3sPk_SBDZbule8elIeQmsz5HIGd21jo6gDBwDKu_YlVp4xR2AUnEqhIM8Mr4zU4jVPTR114kX134l6i2szyuX9fFwMeMincKw7uLiicXeuCankKQjsT8TWx7Wwb0m7O5zHz6RTKqSQ4PrfkGGFtSoxX4Y-jtSuzG3kSefQQ2VZpFddopNE-VoeTgs_1uw/s16000/Screenshot%202023-08-07%20at%2010.22.51%20PM.png" /></a></div><br /><span><br /></span></div><br /><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space-collapse: preserve;">Frames are being presented consistently on the right, but the rate of displacement spikes between one to another isn’t consistent (-50 to -40 followed by another -52 being especially drastic). Human fingers don’t move this discretely (at frame level precision). Rather they should slide and flex in a gradient, speeding up or slowing down gradually. So we knew we had a problem here. We dug deeper into Chrome’s implementation and found there were some fundamental differences in Chrome’s implementation (which was supposedly a copy of Android’s).</span></p><br /></span></div><blockquote style="border: none; margin: 0px 0px 0px 40px; padding: 0px; text-align: left;"><div><span><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space-collapse: preserve;">1. Android uses the native C++ MotionEvent timestamp (with nanosecond precision), but Chrome uses Java </span><a href="https://developer.android.com/reference/android/view/MotionEvent#getEventTime()" style="text-decoration-line: none;"><span face="Arial, sans-serif" style="color: #1155cc; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">MotionEvent.getEventTime</span></a><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space-collapse: preserve;"> & </span><a href="https://developer.android.com/reference/android/view/MotionEvent#getHistoricalEventTime(int)" style="text-decoration-line: none;"><span face="Arial, sans-serif" style="color: #1155cc; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">MotionEvent.getHistoricalEventTime</span></a><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space-collapse: preserve;"> (milliseconds precision). Unfortunately, nanosecond precision was not part of the public API. However, rounding of milliseconds can introduce error into our predictor when it computes velocity between event timestamps.</span></p></span></div><div><span><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space-collapse: preserve;">2. Android’s implementation takes care when selecting the two input events so resampling is using the most relevant events. Chrome however uses a simple FIFO queue of input events, which can result in weird cases of using future events to predict velocity in the past in rare cases on high refresh rate devices.</span></p></span></div></blockquote><div><span><br /><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space-collapse: preserve;">We prototyped using Android’s resampling in Chrome, but found it was still not perfect for Chrome’s architecture resulting in some jank. To improve on it, we experimented with different algorithms, using automation to replay the same input over and over again and evaluating the screen displacement curves. After tuning, this landed at the </span><span face="Arial, sans-serif" style="color: #1155cc; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;"><a href="https://gery.casiez.net/1euro/">1€ filter</a></span><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space-collapse: preserve;"> implementation that visibly and drastically improved the scrolling experience. With this filter, the screen tracks closely to your finger and websites smoothly scroll, preventing jank caused by inconsistent input events. The improvement is visible in our manual validation, on both top-end and low-end devices (<a href="https://drive.google.com/file/d/1KqcWNybFP7kCqBz4mx0vlVzQOqU3IJyb/view?usp=sharing">Here's a redmi 9A video example</a>).</span></p><br /><h1 dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span face="Arial, sans-serif" style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-size: medium;">Going forward!</span></span></h1><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space-collapse: preserve;">In Android 14, the </span><a href="https://developer.android.com/reference/android/view/MotionEvent#getEventTimeNanos()" style="text-decoration-line: none;"><span face="Arial, sans-serif" style="color: #1155cc; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">nanosecond</span></a><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space-collapse: preserve;"> </span><a href="https://developer.android.com/reference/android/view/MotionEvent#getHistoricalEventTimeNanos(int)" style="text-decoration-line: none;"><span face="Arial, sans-serif" style="color: #1155cc; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">API</span></a><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space-collapse: preserve;"> for java MotionEvents will be publicly exposed in the SDK so Chrome (and other apps with unbuffered input) will be able to call it. We also developed new metrics that track the quality of the scroll predictors frame, by creating a test app which introduced pixel level differences between frames (and no other form of jank) and running experiments to see what people would notice. These analysis can be read about </span><span face="Arial, sans-serif" style="color: #1155cc; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;"><a href="https://docs.google.com/document/d/1Y0u0Tq5eUZff75nYUzQVw6JxmbZAW9m64pJidmnGWsY/edit">here</a></span><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space-collapse: preserve;"> and will be used going forward for more exciting performance wins and to make this a visible area for tracking against regressions. In the end, after tuning and enabling the </span><span face="Arial, sans-serif" style="color: #1155cc; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;"><a href="https://gery.casiez.net/1euro/">1€ filter</a></span><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space-collapse: preserve;">, our metrics show a 2x reduction in visible jank while scrolling slowly! This improvement is going live in </span><a href="https://chromium-review.googlesource.com/c/chromium/src/+/4518271" style="text-decoration-line: none;"><span face="Arial, sans-serif" style="color: #1155cc; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">M116</span></a><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space-collapse: preserve;"> as the default, but will be launched all the way back to M110 and brings Chrome on Android on par with Chrome on iOS!</span></p><br /><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space-collapse: preserve;">The moral of the story is: Sometimes metrics don’t cover all the cases and taking a step back and investigating from the top down and getting the lay of the land can end with a superior scrolling experience for users.</span></p><br /><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span face="Arial, sans-serif" style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-size: x-small;">Post by: Stephen Nusko, Chrome Software Engineer</span></span></p><div><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space-collapse: preserve;"><br /></span></div></span></div> <span itemprop='author' itemscope='itemscope' itemtype='http://schema.org/Person'> <meta content='https://plus.google.com/116899029375914044550' itemprop='url'/> </span> </noscript> </div> </div> <div class='share'> <span class='twitter-custom social-wrapper' data-href='http://twitter.com/share?text=Chromium Blog:Smoothing out the scrolling experience in Chrome on Android&url=https://blog.chromium.org/2023/08/smoothing-out-scrolling-experience-in.html&via=ChromiumDev'> <img alt='Share on Twitter' height='24' src='https://www.gstatic.com/images/icons/material/system/2x/post_twitter_black_24dp.png' width='24'/> </span> <span class='fb-custom social-wrapper' data-href='https://www.facebook.com/sharer.php?u=https://blog.chromium.org/2023/08/smoothing-out-scrolling-experience-in.html'> <img alt='Share on Facebook' height='24' src='https://www.gstatic.com/images/icons/material/system/2x/post_facebook_black_24dp.png' width='24'/> </span> </div> <div class='post-footer'> <div class='cmt_iframe_holder' data-href='https://blog.chromium.org/2023/08/smoothing-out-scrolling-experience-in.html' data-viewtype='FILTERED_POSTMOD'></div> <a href='https://plus.google.com/112374322230920073195' rel='author' style='display:none;'> Google </a> <div class='label-footer'> <span class='labels-caption'> Labels: </span> <span class='labels'> <a class='label' href='https://blog.chromium.org/search/label/performance' rel='tag'> performance </a> , <a class='label' href='https://blog.chromium.org/search/label/the%20fast%20and%20the%20curious' rel='tag'> the fast and the curious </a> </span> </div> </div> </div> <div class='blog-pager' id='blog-pager'> <a class='home-link' href='https://blog.chromium.org/'> <i class='material-icons'>  </i> </a> <i class='material-icons disabled'>  </i> <span id='blog-pager-older-link'> <a class='blog-pager-older-link' href='https://blog.chromium.org/search/label/the%20fast%20and%20the%20curious?updated-max=2023-08-08T09:56:00-07:00&max-results=20&start=5&by-date=false' id='Blog1_blog-pager-older-link' title='Older Posts'> <i class='material-icons'>  </i> </a> </span> </div> <div class='clear'></div> </div></div> </div> </div> <div class='col-right'> <div class='section' id='sidebar-top'><div class='widget HTML' data-version='1' id='HTML8'> <div class='widget-content'> <div class='searchBox'> <input type='text' title='Search This Blog' placeholder='Search blog ...' /> </div> </div> <div class='clear'></div> </div></div> <div id='aside'> <div class='section' id='sidebar'><div class='widget Label' data-version='1' id='Label1'> <div class='tab'> <img class='sidebar-icon' src='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAYpJREFUeNrs2aFuwzAQBmAvKRkMKRjZA4QMDJaWFgyMjuzFRg37DIUlA3uFkoGQSaWzJU+tpri5O9+l/zSfdFJlpe59yTmyVedq1PjfcZMZ70NuQnaF8w8htyE/rABtpviXkLcK88c5HhLkMBfgVan43zfFBNGMjHVGT/s55KP2pAvidbGHd+nzKt1RKSLG3rKF1iPFv6UWiPke8i7kEqGdGsI1O+LYVdqJAjgirwkKYD0ytkJBUNbAMvX8V3q9PhUsYvU1sWD8SO/sQvx2ahxOiNoJCSBCoAHYCEQAC4EKICOQASQEOmAS8RcAFxFN5hiIiugpgC3wk9hQAHH/70EBHXUN7IER5EWMiBgo2+nzOKQv9SCAeEM/OQAkhE/ncccFICB87qzQMia5FsJfOui0zMnmRvipU1ormHQuxGTxUsAcCFLxJQBLBLn4UoAFglW8BkATwS5eC6CBEBWvCShBiIvXBkgQRcVbADiI4uKtABSESvGWgB9EzHt3+tNwyO0qa9SoIYtvAQYAqDJhaWWeMecAAAAASUVORK5CYII='/> <h2> Labels </h2> <i class='material-icons arrow'>  </i> </div> <div class='widget-content list-label-widget-content'> <ul> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/%24200K'> $200K </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/10th%20birthday'> 10th birthday </a> <span dir='ltr'> 4 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/abusive%20ads'> abusive ads </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/abusive%20notifications'> abusive notifications </a> <span dir='ltr'> 2 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/accessibility'> accessibility </a> <span dir='ltr'> 3 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/ad%20blockers'> ad blockers </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/ad%20blocking'> ad blocking </a> <span dir='ltr'> 2 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/advanced%20capabilities'> advanced capabilities </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/android'> android </a> <span dir='ltr'> 2 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/anti%20abuse'> anti abuse </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/anti-deception'> anti-deception </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/background%20periodic%20sync'> background periodic sync </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/badging'> badging </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/benchmarks'> benchmarks </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/beta'> beta </a> <span dir='ltr'> 83 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/better%20ads%20standards'> better ads standards </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/billing'> billing </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/birthday'> birthday </a> <span dir='ltr'> 4 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/blink'> blink </a> <span dir='ltr'> 2 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/browser'> browser </a> <span dir='ltr'> 2 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/browser%20interoperability'> browser interoperability </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/bundles'> bundles </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/capabilities'> capabilities </a> <span dir='ltr'> 6 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/capable%20web'> capable web </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/cds'> cds </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/cds18'> cds18 </a> <span dir='ltr'> 2 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/cds2018'> cds2018 </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/chrome'> chrome </a> <span dir='ltr'> 35 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/chrome%2081'> chrome 81 </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/chrome%2083'> chrome 83 </a> <span dir='ltr'> 2 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/chrome%2084'> chrome 84 </a> <span dir='ltr'> 2 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/chrome%20ads'> chrome ads </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/chrome%20apps'> chrome apps </a> <span dir='ltr'> 5 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/Chrome%20dev'> Chrome dev </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/chrome%20dev%20summit'> chrome dev summit </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/chrome%20dev%20summit%202018'> chrome dev summit 2018 </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/chrome%20dev%20summit%202019'> chrome dev summit 2019 </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/chrome%20developer'> chrome developer </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/Chrome%20Developer%20Center'> Chrome Developer Center </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/chrome%20developer%20summit'> chrome developer summit </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/chrome%20devtools'> chrome devtools </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/Chrome%20extension'> Chrome extension </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/chrome%20extensions'> chrome extensions </a> <span dir='ltr'> 3 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/Chrome%20Frame'> Chrome Frame </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/Chrome%20lite'> Chrome lite </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/Chrome%20on%20Android'> Chrome on Android </a> <span dir='ltr'> 2 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/chrome%20on%20ios'> chrome on ios </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/Chrome%20on%20Mac'> Chrome on Mac </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/Chrome%20OS'> Chrome OS </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/chrome%20privacy'> chrome privacy </a> <span dir='ltr'> 4 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/chrome%20releases'> chrome releases </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/chrome%20security'> chrome security </a> <span dir='ltr'> 10 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/chrome%20web%20store'> chrome web store </a> <span dir='ltr'> 32 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/chromedevtools'> chromedevtools </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/chromeframe'> chromeframe </a> <span dir='ltr'> 3 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/chromeos'> chromeos </a> <span dir='ltr'> 4 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/chromeos.dev'> chromeos.dev </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/chromium'> chromium </a> <span dir='ltr'> 9 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/cloud%20print'> cloud print </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/coalition'> coalition </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/coalition%20for%20better%20ads'> coalition for better ads </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/contact%20picker'> contact picker </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/content%20indexing'> content indexing </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/cookies'> cookies </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/core%20web%20vitals'> core web vitals </a> <span dir='ltr'> 2 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/csrf'> csrf </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/css'> css </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/cumulative%20layout%20shift'> cumulative layout shift </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/custom%20tabs'> custom tabs </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/dart'> dart </a> <span dir='ltr'> 8 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/dashboard'> dashboard </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/Data%20Saver'> Data Saver </a> <span dir='ltr'> 3 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/Data%20saver%20desktop%20extension'> Data saver desktop extension </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/day%202'> day 2 </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/deceptive%20installation'> deceptive installation </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/declarative%20net%20request%20api'> declarative net request api </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/design'> design </a> <span dir='ltr'> 2 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/developer%20dashboard'> developer dashboard </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/Developer%20Program%20Policy'> Developer Program Policy </a> <span dir='ltr'> 2 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/developer%20website'> developer website </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/devtools'> devtools </a> <span dir='ltr'> 13 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/digital%20event'> digital event </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/discoverability'> discoverability </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/DNS-over-HTTPS'> DNS-over-HTTPS </a> <span dir='ltr'> 4 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/DoH'> DoH </a> <span dir='ltr'> 4 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/emoji'> emoji </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/emscriptem'> emscriptem </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/enterprise'> enterprise </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/extensions'> extensions </a> <span dir='ltr'> 27 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/Fast%20badging'> Fast badging </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/faster%20web'> faster web </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/features'> features </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/feedback'> feedback </a> <span dir='ltr'> 2 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/field%20data'> field data </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/first%20input%20delay'> first input delay </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/Follow'> Follow </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/fonts'> fonts </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/form%20controls'> form controls </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/frameworks'> frameworks </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/fugu'> fugu </a> <span dir='ltr'> 2 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/fund'> fund </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/funding'> funding </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/gdd'> gdd </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/google%20earth'> google earth </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/google%20event'> google event </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/google%20io%202019'> google io 2019 </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/google%20web%20developer'> google web developer </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/googlechrome'> googlechrome </a> <span dir='ltr'> 12 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/harmful%20ads'> harmful ads </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/html5'> html5 </a> <span dir='ltr'> 11 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/HTTP%2F3'> HTTP/3 </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/HTTPS'> HTTPS </a> <span dir='ltr'> 4 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/iframes'> iframes </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/images'> images </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/incognito'> incognito </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/insecure%20forms'> insecure forms </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/intent%20to%20explain'> intent to explain </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/ios'> ios </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/ios%20Chrome'> ios Chrome </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/issue%20tracker'> issue tracker </a> <span dir='ltr'> 3 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/jank'> jank </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/javascript'> javascript </a> <span dir='ltr'> 5 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/lab%20data'> lab data </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/labelling'> labelling </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/largest%20contentful%20paint'> largest contentful paint </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/launch'> launch </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/lazy-loading'> lazy-loading </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/lighthouse'> lighthouse </a> <span dir='ltr'> 2 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/linux'> linux </a> <span dir='ltr'> 2 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/Lite%20Mode'> Lite Mode </a> <span dir='ltr'> 2 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/Lite%20pages'> Lite pages </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/loading%20interventions'> loading interventions </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/loading%20optimizations'> loading optimizations </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/lock%20icon'> lock icon </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/long-tail'> long-tail </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/mac'> mac </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/manifest%20v3'> manifest v3 </a> <span dir='ltr'> 2 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/metrics'> metrics </a> <span dir='ltr'> 2 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/microsoft%20edge'> microsoft edge </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/mixed%20forms'> mixed forms </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/mobile'> mobile </a> <span dir='ltr'> 2 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/na'> na </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/native%20client'> native client </a> <span dir='ltr'> 8 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/native%20file%20system'> native file system </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/New%20Features'> New Features </a> <span dir='ltr'> 5 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/notifications'> notifications </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/octane'> octane </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/open%20web'> open web </a> <span dir='ltr'> 4 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/origin%20trials'> origin trials </a> <span dir='ltr'> 2 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/pagespeed%20insights'> pagespeed insights </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/pagespeedinsights'> pagespeedinsights </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/passwords'> passwords </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/payment%20handler'> payment handler </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/payment%20request'> payment request </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/payments'> payments </a> <span dir='ltr'> 2 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/performance'> performance </a> <span dir='ltr'> 20 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/performance%20tools'> performance tools </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/permission%20UI'> permission UI </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/permissions'> permissions </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/play%20store'> play store </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/portals'> portals </a> <span dir='ltr'> 3 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/prefetching'> prefetching </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/privacy'> privacy </a> <span dir='ltr'> 2 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/privacy%20sandbox'> privacy sandbox </a> <span dir='ltr'> 4 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/private%20prefetch%20proxy'> private prefetch proxy </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/profile%20guided%20optimization'> profile guided optimization </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/progressive%20web%20apps'> progressive web apps </a> <span dir='ltr'> 2 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/Project%20Strobe'> Project Strobe </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/protection'> protection </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/pwa'> pwa </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/QUIC'> QUIC </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/quieter%20permissions'> quieter permissions </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/releases'> releases </a> <span dir='ltr'> 3 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/removals'> removals </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/rlz'> rlz </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/root%20program'> root program </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/safe%20browsing'> safe browsing </a> <span dir='ltr'> 2 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/Secure%20DNS'> Secure DNS </a> <span dir='ltr'> 2 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/security'> security </a> <span dir='ltr'> 36 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/site%20isolation'> site isolation </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/slow%20loading'> slow loading </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/sms%20receiver'> sms receiver </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/spam%20policy'> spam policy </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/spdy'> spdy </a> <span dir='ltr'> 2 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/spectre'> spectre </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/speed'> speed </a> <span dir='ltr'> 4 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/ssl'> ssl </a> <span dir='ltr'> 2 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/store%20listing'> store listing </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/strobe'> strobe </a> <span dir='ltr'> 2 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/subscription%20pages'> subscription pages </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/suspicious%20site%20reporter%20extension'> suspicious site reporter extension </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/TCP'> TCP </a> <span dir='ltr'> 1 </span> </li> <li> <span dir='ltr'> the fast and the curious </span> <span dir='ltr'> 23 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/TLS'> TLS </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/tools'> tools </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/tracing'> tracing </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/transparency'> transparency </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/trusted%20web%20activities'> trusted web activities </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/twa'> twa </a> <span dir='ltr'> 2 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/user%20agent%20string'> user agent string </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/user%20data%20policy'> user data policy </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/v8'> v8 </a> <span dir='ltr'> 6 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/video'> video </a> <span dir='ltr'> 2 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/wasm'> wasm </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/web'> web </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/web%20apps'> web apps </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/web%20assembly'> web assembly </a> <span dir='ltr'> 2 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/web%20developers'> web developers </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/web%20intents'> web intents </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/web%20packaging'> web packaging </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/web%20payments'> web payments </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/web%20platform'> web platform </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/web%20request%20api'> web request api </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/web%20vitals'> web vitals </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/web.dev'> web.dev </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/web.dev%20live'> web.dev live </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/webapi'> webapi </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/webassembly'> webassembly </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/webaudio'> webaudio </a> <span dir='ltr'> 3 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/webgl'> webgl </a> <span dir='ltr'> 7 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/webkit'> webkit </a> <span dir='ltr'> 5 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/WebM'> WebM </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/webmaster'> webmaster </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/webp'> webp </a> <span dir='ltr'> 5 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/webrtc'> webrtc </a> <span dir='ltr'> 6 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/websockets'> websockets </a> <span dir='ltr'> 5 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/webtiming'> webtiming </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/writable-files'> writable-files </a> <span dir='ltr'> 1 </span> </li> <li> <a dir='ltr' href='https://blog.chromium.org/search/label/yerba%20beuna%20center%20for%20the%20arts'> yerba beuna center for the arts </a> <span dir='ltr'> 1 </span> </li> </ul> <div class='clear'></div> </div> </div><div class='widget BlogArchive' data-version='1' id='BlogArchive1'> <div class='tab'> <i class='material-icons icon'>  </i> <h2> Archive </h2> <i class='material-icons arrow'>  </i> </div> <div class='widget-content'> <div id='ArchiveList'> <div id='BlogArchive1_ArchiveList'> <ul class='hierarchy'> <li class='archivedate expanded'> <div class='intervalToggle'> <span class='new-toggle' href='javascript:void(0)'> <i class='material-icons arrow'>  </i> </span> <a class='toggle' href='javascript:void(0)' style='display: none'> <span class='zippy toggle-open'> <i class='material-icons'>  </i>   </span> </a> <a class='post-count-link' href='https://blog.chromium.org/2024/'> 2024 </a> </div> <div class='items'> <ul class='hierarchy'> <li class='archivedate expanded'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2024/08/'> Aug </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2024/06/'> Jun </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2024/05/'> May </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2024/04/'> Apr </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2024/03/'> Mar </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2024/02/'> Feb </a> </div> <div class='items'> </div> </li> </ul> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class='intervalToggle'> <span class='new-toggle' href='javascript:void(0)'> <i class='material-icons arrow'>  </i> </span> <a class='toggle' href='javascript:void(0)' style='display: none'> <span class='zippy'> <i class='material-icons'>  </i>   </span> </a> <a class='post-count-link' href='https://blog.chromium.org/2023/'> 2023 </a> </div> <div class='items'> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2023/11/'> Nov </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2023/10/'> Oct </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2023/09/'> Sep </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2023/08/'> Aug </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2023/06/'> Jun </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2023/05/'> May </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2023/04/'> Apr </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2023/02/'> Feb </a> </div> <div class='items'> </div> </li> </ul> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class='intervalToggle'> <span class='new-toggle' href='javascript:void(0)'> <i class='material-icons arrow'>  </i> </span> <a class='toggle' href='javascript:void(0)' style='display: none'> <span class='zippy'> <i class='material-icons'>  </i>   </span> </a> <a class='post-count-link' href='https://blog.chromium.org/2022/'> 2022 </a> </div> <div class='items'> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2022/12/'> Dec </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2022/09/'> Sep </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2022/08/'> Aug </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2022/06/'> Jun </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2022/05/'> May </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2022/04/'> Apr </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2022/03/'> Mar </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2022/02/'> Feb </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2022/01/'> Jan </a> </div> <div class='items'> </div> </li> </ul> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class='intervalToggle'> <span class='new-toggle' href='javascript:void(0)'> <i class='material-icons arrow'>  </i> </span> <a class='toggle' href='javascript:void(0)' style='display: none'> <span class='zippy'> <i class='material-icons'>  </i>   </span> </a> <a class='post-count-link' href='https://blog.chromium.org/2021/'> 2021 </a> </div> <div class='items'> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2021/12/'> Dec </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2021/11/'> Nov </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2021/10/'> Oct </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2021/09/'> Sep </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2021/08/'> Aug </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2021/07/'> Jul </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2021/06/'> Jun </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2021/05/'> May </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2021/04/'> Apr </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2021/03/'> Mar </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2021/02/'> Feb </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2021/01/'> Jan </a> </div> <div class='items'> </div> </li> </ul> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class='intervalToggle'> <span class='new-toggle' href='javascript:void(0)'> <i class='material-icons arrow'>  </i> </span> <a class='toggle' href='javascript:void(0)' style='display: none'> <span class='zippy'> <i class='material-icons'>  </i>   </span> </a> <a class='post-count-link' href='https://blog.chromium.org/2020/'> 2020 </a> </div> <div class='items'> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2020/12/'> Dec </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2020/11/'> Nov </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2020/10/'> Oct </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2020/09/'> Sep </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2020/08/'> Aug </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2020/07/'> Jul </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2020/06/'> Jun </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2020/05/'> May </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2020/04/'> Apr </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2020/03/'> Mar </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2020/02/'> Feb </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2020/01/'> Jan </a> </div> <div class='items'> </div> </li> </ul> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class='intervalToggle'> <span class='new-toggle' href='javascript:void(0)'> <i class='material-icons arrow'>  </i> </span> <a class='toggle' href='javascript:void(0)' style='display: none'> <span class='zippy'> <i class='material-icons'>  </i>   </span> </a> <a class='post-count-link' href='https://blog.chromium.org/2019/'> 2019 </a> </div> <div class='items'> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2019/12/'> Dec </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2019/11/'> Nov </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2019/10/'> Oct </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2019/09/'> Sep </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2019/08/'> Aug </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2019/07/'> Jul </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2019/06/'> Jun </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2019/05/'> May </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2019/04/'> Apr </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2019/03/'> Mar </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2019/02/'> Feb </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2019/01/'> Jan </a> </div> <div class='items'> </div> </li> </ul> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class='intervalToggle'> <span class='new-toggle' href='javascript:void(0)'> <i class='material-icons arrow'>  </i> </span> <a class='toggle' href='javascript:void(0)' style='display: none'> <span class='zippy'> <i class='material-icons'>  </i>   </span> </a> <a class='post-count-link' href='https://blog.chromium.org/2018/'> 2018 </a> </div> <div class='items'> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2018/12/'> Dec </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2018/11/'> Nov </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2018/10/'> Oct </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2018/09/'> Sep </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2018/08/'> Aug </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2018/07/'> Jul </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2018/06/'> Jun </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2018/05/'> May </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2018/04/'> Apr </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2018/03/'> Mar </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2018/02/'> Feb </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2018/01/'> Jan </a> </div> <div class='items'> </div> </li> </ul> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class='intervalToggle'> <span class='new-toggle' href='javascript:void(0)'> <i class='material-icons arrow'>  </i> </span> <a class='toggle' href='javascript:void(0)' style='display: none'> <span class='zippy'> <i class='material-icons'>  </i>   </span> </a> <a class='post-count-link' href='https://blog.chromium.org/2017/'> 2017 </a> </div> <div class='items'> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2017/12/'> Dec </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2017/11/'> Nov </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2017/10/'> Oct </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2017/09/'> Sep </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2017/08/'> Aug </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2017/07/'> Jul </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2017/06/'> Jun </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2017/05/'> May </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2017/04/'> Apr </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2017/03/'> Mar </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2017/02/'> Feb </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2017/01/'> Jan </a> </div> <div class='items'> </div> </li> </ul> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class='intervalToggle'> <span class='new-toggle' href='javascript:void(0)'> <i class='material-icons arrow'>  </i> </span> <a class='toggle' href='javascript:void(0)' style='display: none'> <span class='zippy'> <i class='material-icons'>  </i>   </span> </a> <a class='post-count-link' href='https://blog.chromium.org/2016/'> 2016 </a> </div> <div class='items'> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2016/12/'> Dec </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2016/11/'> Nov </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2016/10/'> Oct </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2016/09/'> Sep </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2016/08/'> Aug </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2016/06/'> Jun </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2016/05/'> May </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2016/04/'> Apr </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2016/03/'> Mar </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2016/02/'> Feb </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2016/01/'> Jan </a> </div> <div class='items'> </div> </li> </ul> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class='intervalToggle'> <span class='new-toggle' href='javascript:void(0)'> <i class='material-icons arrow'>  </i> </span> <a class='toggle' href='javascript:void(0)' style='display: none'> <span class='zippy'> <i class='material-icons'>  </i>   </span> </a> <a class='post-count-link' href='https://blog.chromium.org/2015/'> 2015 </a> </div> <div class='items'> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2015/12/'> Dec </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2015/11/'> Nov </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2015/10/'> Oct </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2015/09/'> Sep </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2015/08/'> Aug </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2015/07/'> Jul </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2015/06/'> Jun </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2015/05/'> May </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2015/04/'> Apr </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2015/03/'> Mar </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2015/02/'> Feb </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2015/01/'> Jan </a> </div> <div class='items'> </div> </li> </ul> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class='intervalToggle'> <span class='new-toggle' href='javascript:void(0)'> <i class='material-icons arrow'>  </i> </span> <a class='toggle' href='javascript:void(0)' style='display: none'> <span class='zippy'> <i class='material-icons'>  </i>   </span> </a> <a class='post-count-link' href='https://blog.chromium.org/2014/'> 2014 </a> </div> <div class='items'> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2014/12/'> Dec </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2014/11/'> Nov </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2014/10/'> Oct </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2014/09/'> Sep </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2014/08/'> Aug </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2014/07/'> Jul </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2014/06/'> Jun </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2014/05/'> May </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2014/04/'> Apr </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2014/03/'> Mar </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2014/02/'> Feb </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2014/01/'> Jan </a> </div> <div class='items'> </div> </li> </ul> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class='intervalToggle'> <span class='new-toggle' href='javascript:void(0)'> <i class='material-icons arrow'>  </i> </span> <a class='toggle' href='javascript:void(0)' style='display: none'> <span class='zippy'> <i class='material-icons'>  </i>   </span> </a> <a class='post-count-link' href='https://blog.chromium.org/2013/'> 2013 </a> </div> <div class='items'> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2013/12/'> Dec </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2013/11/'> Nov </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2013/10/'> Oct </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2013/09/'> Sep </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2013/08/'> Aug </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2013/07/'> Jul </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2013/06/'> Jun </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2013/05/'> May </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2013/04/'> Apr </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2013/03/'> Mar </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2013/02/'> Feb </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2013/01/'> Jan </a> </div> <div class='items'> </div> </li> </ul> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class='intervalToggle'> <span class='new-toggle' href='javascript:void(0)'> <i class='material-icons arrow'>  </i> </span> <a class='toggle' href='javascript:void(0)' style='display: none'> <span class='zippy'> <i class='material-icons'>  </i>   </span> </a> <a class='post-count-link' href='https://blog.chromium.org/2012/'> 2012 </a> </div> <div class='items'> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2012/12/'> Dec </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2012/11/'> Nov </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2012/10/'> Oct </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2012/09/'> Sep </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2012/08/'> Aug </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2012/07/'> Jul </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2012/06/'> Jun </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2012/05/'> May </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2012/04/'> Apr </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2012/03/'> Mar </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2012/02/'> Feb </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2012/01/'> Jan </a> </div> <div class='items'> </div> </li> </ul> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class='intervalToggle'> <span class='new-toggle' href='javascript:void(0)'> <i class='material-icons arrow'>  </i> </span> <a class='toggle' href='javascript:void(0)' style='display: none'> <span class='zippy'> <i class='material-icons'>  </i>   </span> </a> <a class='post-count-link' href='https://blog.chromium.org/2011/'> 2011 </a> </div> <div class='items'> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2011/12/'> Dec </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2011/11/'> Nov </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2011/10/'> Oct </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2011/09/'> Sep </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2011/08/'> Aug </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2011/07/'> Jul </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2011/06/'> Jun </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2011/05/'> May </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2011/04/'> Apr </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2011/03/'> Mar </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2011/02/'> Feb </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2011/01/'> Jan </a> </div> <div class='items'> </div> </li> </ul> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class='intervalToggle'> <span class='new-toggle' href='javascript:void(0)'> <i class='material-icons arrow'>  </i> </span> <a class='toggle' href='javascript:void(0)' style='display: none'> <span class='zippy'> <i class='material-icons'>  </i>   </span> </a> <a class='post-count-link' href='https://blog.chromium.org/2010/'> 2010 </a> </div> <div class='items'> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2010/12/'> Dec </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2010/11/'> Nov </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2010/10/'> Oct </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2010/09/'> Sep </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2010/08/'> Aug </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2010/07/'> Jul </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2010/06/'> Jun </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2010/05/'> May </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2010/04/'> Apr </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2010/03/'> Mar </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2010/02/'> Feb </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2010/01/'> Jan </a> </div> <div class='items'> </div> </li> </ul> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class='intervalToggle'> <span class='new-toggle' href='javascript:void(0)'> <i class='material-icons arrow'>  </i> </span> <a class='toggle' href='javascript:void(0)' style='display: none'> <span class='zippy'> <i class='material-icons'>  </i>   </span> </a> <a class='post-count-link' href='https://blog.chromium.org/2009/'> 2009 </a> </div> <div class='items'> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2009/12/'> Dec </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2009/11/'> Nov </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2009/09/'> Sep </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2009/08/'> Aug </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2009/07/'> Jul </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2009/06/'> Jun </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2009/05/'> May </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2009/04/'> Apr </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2009/03/'> Mar </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2009/02/'> Feb </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2009/01/'> Jan </a> </div> <div class='items'> </div> </li> </ul> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class='intervalToggle'> <span class='new-toggle' href='javascript:void(0)'> <i class='material-icons arrow'>  </i> </span> <a class='toggle' href='javascript:void(0)' style='display: none'> <span class='zippy'> <i class='material-icons'>  </i>   </span> </a> <a class='post-count-link' href='https://blog.chromium.org/2008/'> 2008 </a> </div> <div class='items'> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2008/12/'> Dec </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2008/11/'> Nov </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2008/10/'> Oct </a> </div> <div class='items'> </div> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <div class=''> <a class='post-count-link' href='https://blog.chromium.org/2008/09/'> Sep </a> </div> <div class='items'> </div> </li> </ul> </div> </li> </ul> </div> </div> <div class='clear'></div> </div> </div><div class='widget HTML' data-version='1' id='HTML6'> <div class='widget-content'> <a href="http://blog.chromium.org/atom.xml"> <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAihJREFUeNrsWa9Pw0AU7viRMDFRBAkzJDMIBIhJJhCzk7NILIqMv4AEhdz+BCY3OYssAlGBoAJREpZwAlHEBO8lr8nSvNeVbu1dyX3JlzTrXfa+u/e9d7c5joWFhYVO1Fa8PwH2gK6m+BRwAvSlAdsrgr8E1jUuMH73GTAEzrkBWymTewZlihhLmgDXIAFuHgGVQOUF7OSYM1p6PgTuA1vAZlUEvAnPdapcMY0VICECekQ0XRfYrqoHsAGNgXfAoMomRiFDEhOZkkL3S88hMaB2LwXp0bj+ps2edpToZpjfoIDQtBeU+xjoDzP2G/gCPKZ5f8WsCAFJoJgOCcFdWSTeL9YQMSvTA1h9BkI5jaiXhLpSCL/8mVZY0UpyJ9ZdOkniu1dmJ96BpzQu9w6s28gcOq9j6pwLdR8/36NK5CQKwJSMrb2MhhSglBpt4UjsrdsnNu0B3J0HCozbCc4TjyY2srEgos/4RQljCzNxl4ireQD8FOq+T+W0mTB2g7njhlR+Sy2jsXFvU658U8YTbeaGpdIu7mWkEAq5ZtIjIhFZdtfX7QHckSvB2B6zC3VdAkZk0kAQwaXTk/CzTXK3wjIExCs6ZJpTnE4uY1KV+KzFzA3KTiFPENHJkOPcsfpLhwe4btoSuvUqAR+6TOxlCE6ZfKUsJLgsqGW8OpqAGx2X+sLxrwUog+JUeQRMDBIwyXOcnlPtPnL0/UsT/8LnOxYWFhZG4leAAQAAQHEaYuzHbAAAAABJRU5ErkJggg==" class="sidebar-icon" /> <h2>Feed</h2> </a> </div> <div class='clear'></div> </div></div> <div class='section' id='sidebar-bottom'><div class='widget HTML' data-version='1' id='HTML4'> <div class='widget-content'> <div class="share followgooglewrapper"> <button data-href="https://twitter.com/intent/follow?original_referer=http://blog.chromium.org/&screen_name=ChromiumDev" onclick='sharingPopup(this);' id='twitter-share'><span class="twitter-follow">Follow @ChromiumDev</span></button> <script> function sharingPopup (button) { var url = button.getAttribute("data-href"); window.open( url,'popUpWindow','height=500,width=500,left=10,top=10,resizable=yes,scrollbars=yes,toolbar=yes,menubar=no,location=no,directories=no,status=yes'); } </script> </div> </div> <div class='clear'></div> </div><div class='widget HTML' data-version='1' id='HTML1'> <div class='widget-content'> Give us feedback in our <a href="http://support.google.com/bin/static.py?hl=en&page=portal_groups.cs">Product Forums</a>. </div> <div class='clear'></div> </div></div> </div> </div> <div style='clear:both;'></div> </div> <!-- Footer --> <div class='google-footer-outer loading'> <div id='google-footer'> <a href='//www.google.com/'> <img class='google-logo-dark' height='36' src='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAALgAAABICAYAAABFoT/eAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAACLVJREFUeNrsXd+L20YQ3vOprdLqiMXFXE2qB7dcwEcTSB7ykIc+9A/PQx/yEMq1TWhNuYIpJriNr7XpmZ5IxFEvmW2EKs3Ornb1w50PxIFP0kiz387OzM6uhGAwGAxGP3Ho+f7x7ri1O7LdccPqZjSNA4dEHsLfaHcEFedJom93x9Xu2OyOFTcBo6sED3fHZHeMEELrkAHJF0B8Rr+gDFsZ5n0luLTQ95AXs4W06D/tjpR50xtM4CjD0y48YGB4rnyZxNOzyA7zBHr+nLnDaJLg0mo/ALekCasg3Z4XbM0ZdTEgnDPeHY8bIne+Qz2GvwyGNwsuyT218KWvIIBMcwGpLiipcolecjMxfBDchNyS1EvxLiOSIecp31q6IJ/C3yrIrMqMm4jhg+AxkdwbIO3aUO4KjqqMjCT3uaazMBhWBJfuxH3CtRfiXf66DhSRZWbmlMnNaILgZxrXJQO/eO3wORZwvwm4JUxuhheCjzVBYAbW1ces45YDSoZrFNOEE835M8FT6oyeEnws8Fz3QnBxFKPHBMem4GU+m6fPGb0leCTwWcM5B36MPgeZI01gudyDdw3hPeXfo8L/rmCUWnuMMdqUL2WqWeRbhf+twfVsO7YagZGNC79fw7OthEVtkiJ4jJzTd3KPwf3CRqhhiTu23AP5sl0/0xiwISQXpNwLIJK87mHF+U8ddzzdmgKlGzlPYjyxGJQouIhNT4k9AqWEFkqfguIvagTWbcq3KW1WE3xS3m8NtA9WS451xofwjKT5kkDoK/b6mDk5FfXr1lWDL4BofZEv2/SRsK/EHGlGdBdu8QNRb8HMCFwt7Yy3DDI/QP7fx5z3VLhdlJEIs4rKNuXXJXdxZPdB7kfCzWqwCO4V1LHgLjInX3tQ1KzCR52Cz+vDj1dydeRuS74rcvs2Pi6fT5H8OaaUQPQPYcWwRSGXyhhscn5dpAnEFMkuEZetbfkTAnlSuH4DxisE+aMGeJAQ3lFl7C4LJE6QWCaCd583ORQ1jYAwjFctal7nOs2ZZvicwvlZx+RHGrcoAwKUVX8uwcc/9TT65INeDOr5shL9LDRB6QTeIy3zwfdh3WOi6axLCEhSjXU7F3h6LqggUtvyJxpynwu8tDkD98fXApOxRj8zoZ9MnGveYVIVZKaGrkBXCY65BCYNN9NkjpKOyQ81Q79JgdxS+Jn3SDTEXRI7SWzaiSTB32oI3nU3BvMfM0urhOVYgwKhuiAfc4tM07wXwm1ZRoQYSl2NUwiu01fEAHVcpixd745FvVz4dzUUc0o8rwoLy8ZSwU6CyFx1RP5II9+1bFPEFs9HWbNLiimDXE+vCm7u1CS47cofzD3aEhVY57mxRo5zlqdt+RFC1JUH2S7bcVXg4liTMakaBZZVxiTICRoivcn1sEUBlk24JmaC6kxUbYmWoqvyfck2xZGGnDFYa9MMzkYQ1ijkCX6qidybrgePiQ0QIQqoi6qRLeqQfIoRsEHaQJLBdHOnLGetSdm/IPcymJuS1PAnbQPH0MOw/39C1vL11DiLOqIsbDI8QcHvGiLnySi2qUXBicaqUSxN5LEB0g7Jt3ENXJLPJ5S1tnaZBoWbpRqrmjRE7qHmpSmNHdQcYrEUadoh+TbBnc9ri7iycI1kzPeNcLDIvbiqXpez9Tmdq6zGREPuzECBoxrPMiI2WtvyNwhJba2wy3JZ6ky5dD1lSvmZS3e4SPA1wcf1VTFHKX+cGwZzdUYcqpvUtvwrD/InDttVlyZeAKlNN5MKbAiurHhKIPlUuJvlTCCiDjSKSCsUmCFWbGLZwCESfK07JB8LvMYWVtw0D00JEHV8Mq2HkqPbE0oHLvvK2g0o8ETg+4cfwTlZDT9JDoWygu4uQQE/ivIvtcnfPkaCqhiupz7jWOAzqL/vjtcdkv9G4MVMt+EaylfuImiPAXEUjRF3pjjaHiPPZ6If9TGGAO4ZY0am6jOCb+DQ+ZCqLkIpOIPrdNfIjnFPY6nyFut7TS/fanrziOBOKMupKw94WaLMtuVnSFt9CPrWWdJE6PeltCX432DEBoh+5Dv8RRhdis8YAv9uyq4/JAwtlEApgBe9Cw9xDD3tdk4Jn0MDfiHwPHcRPxBePCMER3GuIx7kGlv9fkZ4V9lolx2Uv4X7hEj7qJ3LDoAMGbTRMRibu4L2xQ8bgt8AyU+Q+x7nYrvDnH4iuO5LxKsYwPVbkPMvKF9Zky9wXzRfVWizi62r9X5VHf55h+WHhDjGBZ4WRhyTr6z5SlCoLMxLSpBZFsQ9F80uQFbF/6aFWi+Ev51vzzsuX+msyzuQXXjUz8zEBy+zpq9yweXAoxJW4JbYrDS6gYDqGHxPl+TKeiBfxj9/EBIElPYeOA4y8/qRQfknjvSzgRgtq0Pw/M1eQeMdOSb2Bnrhr6Led+1vcp2x7oTFHMnedFW+Ivlty062BUt74oHgSj+vHepnhunn0JJAMtBZgDI/qmGtMujRv8DDpo47zBJ8UtPOuAR/7rKn8t9AJ0tBdmBAmJ/Fu71yxp4I3qh+DhyRqbi5Y1ShVPlSb8X7bRNcfgZFl+WRGYo7uecrWq1r8X5bhmzP5OdlDwsGRm1suSxkg5rYm7ConyGQ3Zl+DgSD8V/kPwrWBMG9YcBtyShBnTLdTiHgttw7qAW7cqh/ZnmPKr/6ignOaKsdyxbsToT5UkPsW00bJjijDXficcX/JsLs6w2BwGtherdckH3w/kNXRPVI0OqJQoHX42/66IMfMj/2huRjxIidgKV/W0JS+bsstDoTeAHcrI8E5zTh/sDkqxL5rZup55/3USlswfcHf4IrQplVDgW9XFlOqnwr6pVPMMEZTuC60EttvdzbLbaZ4PsFVa3nohhO+vW+yn/ZB2fUhpysmQrzBcTSai9EszuZMcEZ1lCFVrp9zGXhm69iLyY4oxFIa178lPe12I/P2DAYDAaDwWAwGAwGg8FgMBgMBoPBYDD2Cf8IMADDRGoQTe+E9AAAAABJRU5ErkJggg==' style='margin-top: -16px;' width='92'/> </a> <ul> <li> <a href='//www.google.com/'> Google </a> </li> <li> <a href='//www.google.com/policies/privacy/'> Privacy </a> </li> <li> <a href='//www.google.com/policies/terms/'> Terms </a> </li> </ul> </div> </div> <script type='text/javascript'> //<![CDATA[ // Social sharing popups. var postEl = document.getElementsByClassName('social-wrapper'); var postCount = postEl.length; for(i=0; i<postCount;i++){ postEl[i].addEventListener("click", function(event){ var postUrl = this.getAttribute("data-href"); window.open( postUrl,'popUpWindow','height=500,width=500,left=10,top=10,resizable=yes,scrollbars=yes,toolbar=yes,menubar=no,location=no,directories=no,status=yes'); });} //]]> </script> <script type='text/javascript'> //<![CDATA[ var BreakpointHandler = function() { this.initted = false; this.isHomePage = false; this.isMobile = false; }; BreakpointHandler.prototype.finalizeSummary = function(summaryHtml, lastNode) { // Use $.trim for IE8 compatibility summaryHtml = $.trim(summaryHtml).replace(/(<br>|\s)+$/,''); if (lastNode.nodeType == 3) { var lastChar = summaryHtml.slice(-1); if (!lastChar.match(/[.”"?]/)) { if (!lastChar.match(/[A-Za-z]/)) { summaryHtml = summaryHtml.slice(0, -1); } summaryHtml += ' ...'; } } else if (lastNode.nodeType == 1 && (lastNode.nodeName == 'I' || lastNode.nodeName == 'A')) { summaryHtml += ' ...'; } return summaryHtml; }; BreakpointHandler.prototype.generateSummaryFromContent = function(content, numWords) { var seenWords = 0; var summaryHtml = ''; for (var i=0; i < content.childNodes.length; i++) { var node = content.childNodes[i]; var nodeText; if (node.nodeType == 1) { if (node.hasAttribute('data-about-pullquote')) { continue; } nodeText = node.textContent; if (nodeText === undefined) { // innerText for IE8 nodeText = node.innerText; } if (node.nodeName == 'DIV' || node.nodeName == 'B') { // Don't end early if we haven't seen enough words. if (seenWords < 10) { continue; } if (i > 0) { summaryHtml = this.finalizeSummary(summaryHtml, content.childNodes[i-1]); } break; } summaryHtml += node.outerHTML; } else if (node.nodeType == 3) { nodeText = node.nodeValue; summaryHtml += nodeText + ' '; } var words = nodeText.match(/\S+\s*/g); if (!words) { continue; } var remain = numWords - seenWords; if (words.length >= remain) { summaryHtml = this.finalizeSummary(summaryHtml, node); break; } seenWords += words.length; } return summaryHtml; }; BreakpointHandler.prototype.detect = function() { var match, pl = /\+/g, search = /([^&=]+)=?([^&]*)/g, decode = function (s) { return decodeURIComponent(s.replace(pl, " ")); }, query = window.location.search.substring(1); var urlParams = {}; while (match = search.exec(query)) urlParams[decode(match[1])] = decode(match[2]); this.isListPage = $('html').hasClass('list-page'); this.isMobile = urlParams['m'] === '1'; this.isHomePage = window.location.pathname == '/'; }; BreakpointHandler.prototype.initContent = function() { var self = this; $('.post').each(function(index) { var body = $(this).children('.post-body')[0]; var content = $(body).children('.post-content')[0]; $(content).addClass('post-original'); var data = $(content).children('script').html(); data = self.rewriteForSSL(data); // If exists, extract specified editor's preview. var match = data.match(/([\s\S]+?)<div data-is-preview.+?>([\s\S]+)<\/div>/m); if (match) { data = match[1]; } // Prevent big images from loading when they aren't needed. // This must be done as a pre-injection step, since image loading can't be // canceled once embedded into the DOM. if (self.isListPage && self.isMobile) { data = data.replace(/<(img|iframe) .+?>/g, ''); } // Insert template to be rendered as nodes. content.innerHTML = data; if (self.isListPage) { var summary = document.createElement('div'); $(summary).addClass('post-content'); $(summary).addClass('post-summary'); body.insertBefore(summary, content); if (match) { // Use provided summary. summary.innerHTML = match[2]; } else { // Generate a summary. // Summary generation relies on DOM, so it must occur after content is // inserted into the page. summary.innerHTML = self.generateSummaryFromContent(content, 30); } // Add read more link to summary. var titleAnchor = $(this).find('.title a')[0]; var link = titleAnchor.cloneNode(true); link.innerHTML = 'Read More'; $(link).addClass('read-more'); summary.appendChild(link); } }); // Firefox does not allow for proper styling of BR. if (navigator.userAgent.indexOf('Firefox') > -1) { $('.post-content br').replaceWith('<span class="space"></span>'); } $('.loading').removeClass('loading'); }; BreakpointHandler.prototype.process = function() { if (!this.initted) { var makeInsecureImageRegex = function(hosts) { var whitelist = hosts.join('|').replace(/\./g,'\\.'); // Normal image tags, plus input images (yes, this is possible!) return new RegExp('(<(img|input)[^>]+?src=("|\'))http:\/\/(' + whitelist +')', 'g'); }; this.sslImageRegex = makeInsecureImageRegex(BreakpointHandler.KNOWN_HTTPS_HOSTS); this.sslImageCurrentDomainRegex = makeInsecureImageRegex([window.location.hostname]); this.detect(); this.initContent(); this.initted = true; } }; BreakpointHandler.KNOWN_HTTPS_HOSTS = [ "www.google.org", "www.google.com", "services.google.com", "blogger.com", "draft.blogger.com", "www.blogger.com", "photos1.blogger.com", "photos2.blogger.com", "photos3.blogger.com", "blogblog.com", "img1.blogblog.com", "img2.blogblog.com", "www.blogblog.com", "www1.blogblog.com", "www2.blogblog.com", "0.bp.blogspot.com", "1.bp.blogspot.com", "2.bp.blogspot.com", "3.bp.blogspot.com", "4.bp.blogspot.com", "lh3.googleusercontent.com", "lh4.googleusercontent.com", "lh5.googleusercontent.com", "lh6.googleusercontent.com", "themes.googleusercontent.com", ]; BreakpointHandler.prototype.rewriteForSSL = function(html) { // Handle HTTP -> HTTPS source replacement of images, movies, and other embedded content. return html.replace(this.sslImageRegex, '$1https://$4') .replace(this.sslImageCurrentDomainRegex, '$1//$4') .replace(/(<(embed|iframe)[^>]+?src=("|'))http:\/\/([^"']*?(youtube|picasaweb\.google)\.com)/g, '$1https://$4') // Slideshow SWF takes a image host, so we need to rewrite that parameter. .replace(/(<embed[^>]+?feed=http(?=[^s]))/g, '$1s'); }; $(document).ready(function() { var handler = new BreakpointHandler(); handler.process(); // Top-level navigation. $(".BlogArchive .tab").click(function(ev) { ev.preventDefault(); $(this).parent().toggleClass('active'); $(this).siblings().slideToggle(300); }); $(".Label .tab").click(function(ev) { ev.preventDefault(); $(this).parent().toggleClass('active'); $(this).siblings().slideToggle(300); }); // Blog archive year expansion. $('.BlogArchive .intervalToggle').click(function(ev) { ev.preventDefault(); if ($(this).parent().hasClass('collapsed')) { $(this).parent().removeClass('collapsed'); $(this).parent().addClass('expanded'); } else { $(this).parent().removeClass('expanded'); $(this).parent().addClass('collapsed'); } }); // Reverse order of months. $('.BlogArchive .intervalToggle + div').each(function(_, items) { var year = $(this); year.children().each(function(_, month) { year.prepend(month); }); }); // Set anchors to open in new tab. $('.post-content img').parent().each(function(_, node) { if (node.nodeName == 'A') { $(this).attr('target', '_blank'); } }); // Process search requests. $('.searchBox input').on("keypress", function(ev) { if (ev.which == 13) { window.location.href = 'https://www.google.com/search?q=site%3A' + window.location.hostname + '%20' + encodeURIComponent ($(this).val()); } }); }); //]]> </script> <script type="text/javascript" src="https://www.blogger.com/static/v1/widgets/984859869-widgets.js"></script> <script type='text/javascript'> window['__wavt'] = 'AOuZoY4RC4ie0mzKFJi-kCZwREHShD3-yw:1732410859453';_WidgetManager._Init('//www.blogger.com/rearrange?blogID\x3d2471378914199150966','//blog.chromium.org/search/label/the%20fast%20and%20the%20curious','2471378914199150966'); _WidgetManager._SetDataContext([{'name': 'blog', 'data': {'blogId': '2471378914199150966', 'title': 'Chromium Blog', 'url': 'https://blog.chromium.org/search/label/the%20fast%20and%20the%20curious', 'canonicalUrl': 'https://blog.chromium.org/search/label/the%20fast%20and%20the%20curious', 'homepageUrl': 'https://blog.chromium.org/', 'searchUrl': 'https://blog.chromium.org/search', 'canonicalHomepageUrl': 'https://blog.chromium.org/', 'blogspotFaviconUrl': 'https://blog.chromium.org/favicon.ico', 'bloggerUrl': 'https://www.blogger.com', 'hasCustomDomain': true, 'httpsEnabled': true, 'enabledCommentProfileImages': true, 'gPlusViewType': 'FILTERED_POSTMOD', 'adultContent': false, 'analyticsAccountNumber': 'UA-37592578-1', 'encoding': 'UTF-8', 'locale': 'en', 'localeUnderscoreDelimited': 'en', 'languageDirection': 'ltr', 'isPrivate': false, 'isMobile': false, 'isMobileRequest': false, 'mobileClass': '', 'isPrivateBlog': false, 'isDynamicViewsAvailable': true, 'feedLinks': '\x3clink rel\x3d\x22alternate\x22 type\x3d\x22application/atom+xml\x22 title\x3d\x22Chromium Blog - Atom\x22 href\x3d\x22https://blog.chromium.org/feeds/posts/default\x22 /\x3e\n\x3clink rel\x3d\x22alternate\x22 type\x3d\x22application/rss+xml\x22 title\x3d\x22Chromium Blog - RSS\x22 href\x3d\x22https://blog.chromium.org/feeds/posts/default?alt\x3drss\x22 /\x3e\n\x3clink rel\x3d\x22service.post\x22 type\x3d\x22application/atom+xml\x22 title\x3d\x22Chromium Blog - Atom\x22 href\x3d\x22https://www.blogger.com/feeds/2471378914199150966/posts/default\x22 /\x3e\n', 'meTag': '', 'adsenseHostId': 'ca-host-pub-1556223355139109', 'adsenseHasAds': false, 'adsenseAutoAds': false, 'boqCommentIframeForm': true, 'loginRedirectParam': '', 'view': '', 'dynamicViewsCommentsSrc': '//www.blogblog.com/dynamicviews/4224c15c4e7c9321/js/comments.js', 'dynamicViewsScriptSrc': '//www.blogblog.com/dynamicviews/d78375fb222d99b3', 'plusOneApiSrc': 'https://apis.google.com/js/platform.js', 'disableGComments': true, 'interstitialAccepted': false, 'sharing': {'platforms': [{'name': 'Get link', 'key': 'link', 'shareMessage': 'Get link', 'target': ''}, {'name': 'Facebook', 'key': 'facebook', 'shareMessage': 'Share to Facebook', 'target': 'facebook'}, {'name': 'BlogThis!', 'key': 'blogThis', 'shareMessage': 'BlogThis!', 'target': 'blog'}, {'name': 'X', 'key': 'twitter', 'shareMessage': 'Share to X', 'target': 'twitter'}, {'name': 'Pinterest', 'key': 'pinterest', 'shareMessage': 'Share to Pinterest', 'target': 'pinterest'}, {'name': 'Email', 'key': 'email', 'shareMessage': 'Email', 'target': 'email'}], 'disableGooglePlus': true, 'googlePlusShareButtonWidth': 0, 'googlePlusBootstrap': '\x3cscript type\x3d\x22text/javascript\x22\x3ewindow.___gcfg \x3d {\x27lang\x27: \x27en\x27};\x3c/script\x3e'}, 'hasCustomJumpLinkMessage': false, 'jumpLinkMessage': 'Read more', 'pageType': 'index', 'searchLabel': 'the fast and the curious', 'pageName': 'the fast and the curious', 'pageTitle': 'Chromium Blog: the fast and the curious'}}, {'name': 'features', 'data': {}}, {'name': 'messages', 'data': {'edit': 'Edit', 'linkCopiedToClipboard': 'Link copied to clipboard!', 'ok': 'Ok', 'postLink': 'Post Link'}}, {'name': 'template', 'data': {'name': 'custom', 'localizedName': 'Custom', 'isResponsive': false, 'isAlternateRendering': false, 'isCustom': true}}, {'name': 'view', 'data': {'classic': {'name': 'classic', 'url': '?view\x3dclassic'}, 'flipcard': {'name': 'flipcard', 'url': '?view\x3dflipcard'}, 'magazine': {'name': 'magazine', 'url': '?view\x3dmagazine'}, 'mosaic': {'name': 'mosaic', 'url': '?view\x3dmosaic'}, 'sidebar': {'name': 'sidebar', 'url': '?view\x3dsidebar'}, 'snapshot': {'name': 'snapshot', 'url': '?view\x3dsnapshot'}, 'timeslide': {'name': 'timeslide', 'url': '?view\x3dtimeslide'}, 'isMobile': false, 'title': 'Chromium Blog', 'description': 'News and developments from the open source browser project', 'url': 'https://blog.chromium.org/search/label/the%20fast%20and%20the%20curious', 'type': 'feed', 'isSingleItem': false, 'isMultipleItems': true, 'isError': false, 'isPage': false, 'isPost': false, 'isHomepage': false, 'isArchive': false, 'isSearch': true, 'isLabelSearch': true, 'search': {'label': 'the fast and the curious', 'resultsMessage': 'Showing posts with the label the fast and the curious', 'resultsMessageHtml': 'Showing posts with the label \x3cspan class\x3d\x27search-label\x27\x3ethe fast and the curious\x3c/span\x3e'}}}]); _WidgetManager._RegisterWidget('_HeaderView', new _WidgetInfo('Header1', 'header', document.getElementById('Header1'), {}, 'displayModeFull')); _WidgetManager._RegisterWidget('_BlogView', new _WidgetInfo('Blog1', 'main', document.getElementById('Blog1'), {'cmtInteractionsEnabled': false, 'navMessage': 'Showing posts with label \x3cb\x3ethe fast and the curious\x3c/b\x3e. \x3ca href\x3d\x22https://blog.chromium.org/\x22\x3eShow all posts\x3c/a\x3e'}, 'displayModeFull')); _WidgetManager._RegisterWidget('_HTMLView', new _WidgetInfo('HTML8', 'sidebar-top', document.getElementById('HTML8'), {}, 'displayModeFull')); _WidgetManager._RegisterWidget('_LabelView', new _WidgetInfo('Label1', 'sidebar', document.getElementById('Label1'), {}, 'displayModeFull')); _WidgetManager._RegisterWidget('_BlogArchiveView', new _WidgetInfo('BlogArchive1', 'sidebar', document.getElementById('BlogArchive1'), {'languageDirection': 'ltr', 'loadingMessage': 'Loading\x26hellip;'}, 'displayModeFull')); _WidgetManager._RegisterWidget('_HTMLView', new _WidgetInfo('HTML6', 'sidebar', document.getElementById('HTML6'), {}, 'displayModeFull')); _WidgetManager._RegisterWidget('_HTMLView', new _WidgetInfo('HTML4', 'sidebar-bottom', document.getElementById('HTML4'), {}, 'displayModeFull')); _WidgetManager._RegisterWidget('_HTMLView', new _WidgetInfo('HTML1', 'sidebar-bottom', document.getElementById('HTML1'), {}, 'displayModeFull')); </script> </body> </html>