微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

获得“折页之上”的高性能方法/渲染“折页之上”的关键元素?

如何解决获得“折页之上”的高性能方法/渲染“折页之上”的关键元素?

简短问题

我如何(尽可能可靠地)计算“首屈一指”的内容的视觉效果包括外部CSS和所应用的字体以及加载的所有图像。

完整问题

抱歉,这个问题有很多,我只是想表明我曾在这个问题上工作过,而且我在哪里工作,所以它并没有最终成为“我该如何做”类型的问题,并没有得到即时调查!!

我正在尝试确定是否可以在客户端浏览器中完全下载呈现“首屏”内容所需的所有资源。

这是纯粹使用浏览器API(即不使用屏幕快照时间轴)模拟SpeedIndex的更大目标的一部分。

我需要收集的东西

  1. 出现在页面折叠上方的所有元素。
  2. 确保已加载所有相关资产。
  3. 此外,这些数据还被发送到服务器进行分析,因此我想尽可能地将其保留在一个请求下。

我无法克服的挑战

  1. 必须运行使元素多次折叠的功能
  2. 确保所有关键资产实际上都以非常慢的连接加载。
  3. 确保该功能在网络流量很高时运行,如果网络上从来没有一个安静的2秒窗口(可能是由于每秒进行一次轮询服务器的老式聊天),它将永远不会触发。

首先,这不一定是完美的,这是一个近似值,但是我越精确,它就会越好!

此刻我的操作方式是使用PerformanceObserver列出所有下载的资源。

第二秒钟,我得到一个2秒的窗口,其中没有完成任何请求,我假设关键的CSS已下载并开始查看页面上的图像。

//getRects is the function to get all of the rectangles above the fold.
var rectInterval = setTimeout(getRects,2500);

 var xx = new PerformanceObserver(function (ll,p) {
        ll.getEntries().forEach(function (en) {
            if (en.name.indexOf(apiEndpoint) == -1) {
                if (en.entryType == "layout-shift") {
                    if (en.entryType == "resource"){
                    //any resources I reset the timer waiting for a quiet time
                    clearTimeout(rectInterval);
                    rectInterval = setTimeout(getRects,2000);
                }
                
            }
        });
    });
    xx.observe({
        entryTypes: ['largest-contentful-paint','longtask','resource','paint','navigation','mark','measure','layout-shift','first-input']
    });

我使用getRects函数getBoundingRect()中捕获页面上所有图像和带有背景图像的元素的尺寸,然后使用window.innerHeight等来计算它们是否出现在折叠上方。 / p>

这些是下载时要检查的候选人(以及以前的资源列表等)

var doc = window.document;
var browserWidth = window.innerWidth || doc.documentElement.clientWidth;
var browserHeight = window.innerHeight || doc.documentElement.clientHeight;

function checkRectangle(el){
    var rtrn = false;
    
    
    if (el.getBoundingClientRect) {
       var rect =  el.getBoundingClientRect();
       //check if the bottom is above the top to ensure the element has height,same for width.
       //Then the last 4 checks are to see if the element is in the above the fold viewport.
       
       if (rect.bottom <= rect.top || rect.right <= rect.left || rect.right < 0 || rect.left > browserWidth || rect.bottom < 0 || rect.top > browserHeight) {
           rtrn = false;
       }else{
           rtrn = {};
           rtrn.bot = rect.bottom;
           rtrn.top = rect.top;
           rtrn.left = rect.left;
           rtrn.right = rect.right;
       }
   }
   
   return rtrn;
}



//function to get the rectangles above the fold
function getRects(){
    
    var rects = [];
     var elements = doc.getElementsByTagName('*');
    var re = /url\(.*(http.*)\)/ig;
    for (var i = 0; i < elements.length; i++) {
        var el = elements[i];
        var style = getComputedStyle(el);
        
        if(el.tagName == "IMG"){
            var rect = checkRectangle(el);
            if(rect){
                //The URL is stored here for later processing where I match performance timings to the element,it is not relevant other than to show why I convert the `getBoundingClientRect()` to a simple object. 
                rect.url = el.src;
                rects.push(rect);
            }
        }
        //I also need to check for background images set in either CSS or with inline styles.
        if (style['background-image']) {
             var rect = checkRectangle(el);
             if(rect){
                var matches = re.exec(style['background-image']);
                if (matches && matches.length > 1){
                    rect.url = matches[1].replace('"','');
                    rects.push(rect);
                }
                
             }
            
        }
        
    }

那一点很好(尽管有一些缩小搜索范围的技巧,所以我不会遍历所有内容都很好),但是我的问题来自加载缓慢的网站。如果请求之间的间隔超过2秒(这种情况可能发生在特别慢的连接上,或者如果服务器离用户很远),那么我将无法获得完整的数据。

我的解决方法是然后监视其他网络请求(但再次等待两次请求之间的延迟2秒),然后重新运行该功能以收集上述折叠内容。如果该网站在滚动上使用延迟加载,这显然不能很好地工作,因为请求可以在整个页面生命周期中不断触发。

由于在一个非常沉重的页面上收集元素的尺寸可能会占用大量cpu,并且需要将此数据发送到服务器进行分析,因此我正在尝试找到一种更可靠的方法来确保所有或仅触发getRect一次但确保所有初始加载完成的方式。

假设如果有效负载足够小(例如小于1kb),则可以在服务器上稍后对数据进行任何处理

我考虑过的事情

  1. 寻找任何<links><scripts>等,并检查它们是否已加载。该问题来自于动态添加链接以及外部资源(即,在另一个样式表中链接的样式表)。这可能会更健壮,但会变得非常复杂。
  2. 将两次检查之间的时间(我等待的安静时间)设置得更长一些。显然,由于“安静时间”可能永远不会发生,因此交通繁忙的网站的问题更加严重。
  3. 使用MutationObserver监视页面,然后再次等待安静的时间。但是,据我所知,如果页面具有任何交互性,则会更频繁地触发该事件?
  4. 我知道,对于正确内联CSS的网站,我的方法会产生过多报告,这不是问题。

我是否走上正轨,可以解决这个难题,或者我可以根据window.performance数据(或类似的API)使用一些简单的公式,让我说“所有折叠元素都是加载并呈现。”

我希望这很清楚,但是任何问题都可以问,因为我知道这个问题中有很多内容可以简单地回答“如何检查所有关键资源是否已加载”。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。