• 前端性能优化面试问题


    一、从输入URL到页面加载显示完成都发生了什么?

    这个问题的根本:知识点广,区分度高。

    回答思路:渲染过程是重点,其他自己擅长的点可以适当展开。

    如何解答:

    1、UI thread(UI线程)先判断输入的是搜索还是URL地址,如果是搜索则启用浏览器设置的默认搜索引擎进行搜索,如果是URL则开始URL的相应解析请求。

    URL的组成结构可以细讲一下,如下图拆解图。

    2、UI线程执行完之后会通知Network thread(网络线程),开始发起网络请求。

    网络请求步骤:

      (1)、DNS查找IP

      (2)、协议是https,需要建立TLS连接

      (3)、如果收到301状态码,重新执行Network thread(网络线程)发起新请求,跟重定向新地址创建连接

      (4)、设置UA等信息,发送GET请求

      (5)、服务器上的应用处理请求,组织好Response信息返回给浏览器,对服务端熟悉的可以展开

      (6)、浏览器读取Response信息,分析数据类型

      (7)、安全检查

      (8)、通知UI线程数据准备就绪

    UI线程和网络线程都是属于Browser Process(浏览器进程)。

    3、Renderer process(渲染进程),重点回答

    在渲染进程里,我们最主要也最熟悉的线程是Main thread主线程,主要围绕主线程来回答。

    Raster Thread绘制线程,Compositor Thread复合线程。

      (1)解析文本构建DOM

      (2)边解析DOM边加载子资源,如图片,CSS等资源

      (3)JS阻塞解析,如果JS不对DOM做修改的操作,可以使用async/defer属性进行非阻塞加载

      (4)解析CSS,计算computed styles

      (5)构建布局树,位置和大小

      (6)创建绘制记录,确定绘制顺序,绘制前的准备工作

      (7)将页面拆分图层,构建图层树,提高绘制的效率

      (8)复合线程像素画图层,创建一条复合帧,即将所有绘制好的图层合并

    以上就是主要以渲染层面回答这个问题的知识点。如果还要继续扩展可以讲http头信息、缓存机制、状态码等。

    二、什么是首屏加载?怎么优化?

    这个问题的核心:

      (1)Web增量加载的特点决定了首屏性能不会完美

      (2)过长的白屏影响用户体验和留存

      (3)首屏(above the fold)=> 初次印象

    如何回答首屏:

    首屏的对于用户3个关键时刻:

      (1)白屏时页面发生了什么事情,什么时候可以出现内容,First Contentful Paint(FCP)

      (2)页面开始出现内容知道网站可访问,开始等待页面具体有意义的内容出现完成,Largest Contentful Paint(LCP)

      (3)内容出现后会想页面能不能用,什么时候可以进行交互,Time to Interactive(TTI)

    以上三个关键节点的量化指标:

    先回答以上首屏的节点和相应指标,后回答如何进行首屏优化:

    1、资源体积太大:资源压缩,传输压缩,代码拆分,Tree shaking,HTTP2,缓存

    2、首页内容太多:路由/组件/内容 lazy-loading,预渲染/SSR,Inline CSS

    3、加载顺序不合适:prefetch,preload

    三、JS是怎样管理内存?什么情况会造成内存泄漏?

    问题核心:内存泄漏严重影响性能,高级语言不等于不需要管理内存

    如何回答:

    1、JS相关的内存机制

    ——变量创建时自动分配内存,不使用时“自动”释放内存,俗称GC。

    ——所有的GC都是近似实现,只能通过判断变量是否还能再次访问到。

    ——局部变量,函数执行完,没有闭包引用,就会被标记回收。

    ——全局变量,直至浏览器卸载页面时释放。

    ——GC两种实现方式:

      (1)引用计数,无法解决循环引用的问题

      (2)标记清除,不能被访问到的被标记,然后进行清除,这是目前大多数浏览器的实现方式。

      标记清除也有缺陷,如下代码,b属性永远不会被访问,但是因为a一直被访问所以b不会被清除

    const obj = { a:new Array(1000),b:new Array(2000)}
    
    setInterval(()=>console.log(obj.a),1000)

    2、如何避免内存泄漏

      (1)避免意外的全局变量产生,如方法里面声明变量不使用var,let,const,造成意外的全局变量产生

      (2)避免反复运行引发大量闭包,如下代码

    var store;
    
    function outer(){
        var largeData = new Array(10000000);
        var prevStore = store;
       function inner(){
           if(prevStore) return   largeData 
        }
        return function(){}        
    }
    
    setInterval(function(){
        store = outer()
    },10)

      (3)避免脱离DOM元素,如下代码

    function createElement(){
      const div=document.createElement('div');
      div.id='detached';
      return div
    }
    
    const detachedDiv = createElement();
    
    document.body.appendChild(detachedDiv);
    
    function deleteElement(){
      document.body.removeChild(document.getElementById('detached'))
    }
    
    deleteElement()
    

      上述代码虽然detached这个DOM元素以及被删除掉了,但是detachedDiv这个变量引用了这个DOM元素,这个变量没有被回收那么这个DOM元素依然会存在内存中。

    放弃安逸,持续努力——成长
  • 相关阅读:
    Angular9 cdk-virtual-scroll-viewport' is not a known element 报错解决方案
    angular8打包时提示ERROR in Child compilation failed:解决方案
    angular8配置proxy本地跨域代理
    Vue-cli 本地跨域配置方法
    axios中url参数变量配置
    在vue-cli中使用axios时报错TypeError: Cannot set property 'lists' of undefined at eval
    nuxt.js element-ui踩坑记录(已解决)
    nuxt 关闭ESlint 语法检测
    javaScript学习之正则表达式初探
    直接在低版本IE6/7/8浏览器中使用HTML5的audio和video标签播放视频音频的办法
  • 原文地址:https://www.cnblogs.com/MarsPGY/p/15807157.html
Copyright © 2020-2023  润新知