杂-面试题

目录

怎么判断localStorage存满了?

async await promise try...catch

如果在失效时间前修改了强缓存的文件,怎么让强缓存也更新

webpack打包生成文件名

给没有生成的元素绑定事件

js异步处理除了async和defer还有什么

前端性能监控


怎么判断localStorage存满了?

(1)JSON.stringify(localStroage).length和5m上限比较

(2)遍历每个item,之后根据getItem(item).lenght 判断长度  之后把长度全部加起来, 之后进行1024计算  看超过没超过5兆

// 得到localStorage已使用容量
(function(){
    if(!window.localStorage) {
        console.log('浏览器不支持localStorage');
    }
    var size = 0;
    for(item in window.localStorage) {
        if(window.localStorage.hasOwnProperty(item)) {
            size += window.localStorage.getItem(item).length;
        }
    }  
    console.log('当前localStorage已使用容量为' + (size / 1024).toFixed(2) + 'KB');  // 再除以1024,就是M单位
})()

(3)onerror监控   \try catch  (LocalStorage的异常处理)

当达到localStorage容量上限时,会抛出 QUOTA_EXCEEDED_ERR(各浏览器不一样

const QUOTA_EXCEEDED_ERR_CODE = 22    //Chrome
function write (key, data) {
    try {
        localStorage.setItem(key, data);  //写入数据
    } catch (e) {
        if (e.code === QUOTA_EXCEEDED_ERR_CODE) {
            localStorage.clear();
            localStorage.setItem(key, data);
        }
    }
}

怎么避免 localStorage 存满的问题?

1、划分域名。各域名下的存储空间由各业务组统一规划使用

2、跨页面传数据:考虑单页应用、优先采用 url 传数据

3、最后的兜底方案:清掉别人的存储

localStorage的方法getItem、setItem、removeItem、clear...

//核心localStorage管理代码,对localStorage进行模块化为了将错误信息以JSON格式记载。
define(function() {
     var METHOD = {
         GET : 0,
         SET : 1,
         REMOVE : 2,
         CLEAR : 3
     }, 
     _localStorageFactory = function(method, key, value) {
         if(localStorage) {
             switch(method) {
                 case METHOD.GET:
                     return localStorage.getItem(key);
                 case METHOD.SET:
                     localStorage.setItem(key, value);
                     break;
                 case METHOD.REMOVE:
                     localStorage.removeItem(key);
                     break;
                 case METHOD.CLEAR:
                     localStorage.clear();
                     break;
             }
             return true;
         }
         return false;
     };
     
     return {
         getItem : function(type, key) {
             var item = JSON.parse(_localStorageFactory(METHOD.GET, type));
             if(item) {
                 return item[key];
             }
             return null;
         },
         setItem : function(type, key, value) {
             var item = JSON.parse(_localStorageFactory(METHOD.GET, type));
 
             if(!item) {
                 _localStorageFactory(METHOD.SET, type, '{"' + key + '": ' + JSON.stringify(value) + '}');
             } else {
                 item[key] = value;
                 _localStorageFactory(METHOD.SET, type, JSON.stringify(item));
             }
         },
         removeItem : function(type, key) {
             var items = _localStorageFactory(METHOD.GET, type);
             delete items[key];
 
             _localStorageFactory(METHOD.SET, type, items);
         },
         clear : function(type) {
             _localStorageFactory(METHOD.REMOVE, type);
         },
         clearAll : function() {
             _localStorageFactory(METHOD.CLEAR);
         }
     };
 });

async await promise try...catch

async function buildData(name) {
      try {
        let response1 = await axios.get('/api/user?name=' + name);
        let userInfo = response1.data;
        
        let response2 = await axios.get('/api/topics?user_id' + userInfo._id);
        let posts = response2.data;
        // i got it.
      } catch(err) {
        console.log(err);
      }  
    }
    
    buildData('xiaoming');

如果在失效时间前修改了强缓存的文件,怎么让强缓存也更新

(1)手动清除缓存、自动推送资源

(2)webpack打包文件名加上hash(版本号/时间),强缓存失效内更改,就会重新请求。发现url中的hash值变化了,就重新强缓存。 (url不允许改变)

采用webpack设置入口文件index.html的cache-control为no-cache,即入口文件不使用强缓存,只使用协商缓存,其他文件可使用强缓存,这样尽管发请求,还在强缓存过期时间内,也会拉取最新的资源


(3) 给静态资源都带上版本号,每次请求如果版本号改了,会请求新的资源的,但是index.html别做缓存

webpack打包生成文件名

output参数的 - filename属性,表示的是如何命名生成出来的入口文件

chunkFilename属性,指定的是除入口文件外的chunk的命名(这些chunk通常是由于webpack对代码的优化所形成的,比如因应实际运行的情况来异步加载)。

规则有以下三种:

  • [name],指代入口文件的name,也就是entry参数的key,因此可以在name里利用/,即可达到控制文件目录结构的效果。
  • [hash],指代本次编译的一个hash版本,每一次打包都会生成一个唯一的 hash;在缓存的层面来说,相当于一次全量的替换。
  • [chunkhash],指代的是当前chunk的一个hash版本,在两次编译中,如果某个chunk根本没有发生变化,那么该chunk的hash也就不会发生变化。这在缓存的层面上来说,就是把缓存的粒度精细到具体某个chunk,只要chunk不变,该chunk的浏览器缓存就可以继续使用。
output: {
    path: config.build.assetsRoot,
    filename: utils.assetsPath('js/[name].[chunkhash].' + Version + '.js'),
    chunkFilename: utils.assetsPath('js/[id].[chunkhash].' + Version + '.js')
},

给没有生成的元素绑定事件

用事件代理(事件冒泡)

默认情况下,事件使用冒泡事件流,不使用捕获事件流。在Firefox和Safari里,可以显式的指定使用捕获事件流,方法是在注册事件时obj.addEventListener(evtype,fn,useCapture)传入useCapture参数,将这个参数设为true。(从根元素到被点击的元素,从上到下)

js异步处理除了async和defer还有什么

异步加载或许还有webpack的懒加载

还可以用一个方法动态创建script标签,在load事件触发时回调这个方法

前端性能监控

本地:谷歌的performance.timing ( Navigation Timing API )(合成监控 - 模拟)

(2)真实用户监控(RUM):

100w个用户,怎么检测用户性能(回答前端监控,埋点

前端监控可以分为三类:数据监控、性能监控和异常监控。

常见的性能监控数据包括:

  • 不同用户,不同机型和不同系统下的首屏加载时间
  • 白屏时间
  • http等请求的响应时间
  • 静态资源整体下载时间
  • 页面渲染时间
  • 页面交互动画完成时间

实现前端监控的步骤为:前端埋点和上报、数据处理和数据分析。

常见的前端埋点方法分为三种:代码埋点、可视化埋点和无痕埋点。

(1)代码埋点,就是以嵌入代码的形式进行埋点,比如需要监控用户的点击事件,会选择在用户点击时,插入一段代码,记录这个监听行为或者将监听行为以某一种数据格式直接传递给server端。此外比如需要统计产品的PV和UV的时候,需要在网页的初始化时,发送用户的访问信息等。

优点:可以在任意时刻,精确的发送或保存所需要的数据信息。

缺点:工作量较大,每一个组件的埋点都需要添加相应的代码

(2)可视化埋点,提供一个可视化系统,输入为业务代码,可以在业务代码中自定义的增加埋点事件等等,最后输出的代码耦合了业务代码和埋点代码。(用可视化交互的手段代替代码埋点)

也就是用一个系统来实现手动插入代码埋点的过程。

缺点:可视化埋点可以埋点的控件有限,不能手动定制。

(3)无埋点(全部埋点),是前端的任意一个事件都被绑定一个标识,所有的事件都记录下来。通过定期上传记录文件,配合文件解析,解析出来我们想要的数据,并生成可视化报告。。

比如从页面的js代码中,找出dom上被绑定的事件,然后进行全埋点。

优点:由于采集的是全量数据,所以产品迭代过程中不需要关注埋点逻辑,也不会出现漏埋、误埋等现象。

缺点:

  • 无埋点采集全量数据,给数据传输和服务器增加压力
  • 无法灵活的定制各个事件所需要上传的数据

采集真实用户性能数据:

  • 使用标准的 API;
  • 定义合适的指标;
  • 采集正确的数据;
  • 上报关联的维度。

navigator.sendBeacon

大部分现代浏览器都支持 navigator.sendBeacon 方法。这个方法可以用来发送一些统计和诊断的小量数据,特别适合上报统计的场景。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值