前端场景面试大杂烩:⼩程序为什么会有两个线程?web应⽤中如何对静态资源加载失败的场景做降级处理?....

371 阅读4分钟

接上文继续来看!

PékinexpressGIF.gif

⼩程序为什么会有两个线程?

⼩程序之所以有两个线程,是为了实现⼩程序的⾼效运⾏和良好的⽤⼾体验。

  • 1.渲染线程(UI线程): 渲染线程负责⼩程序界⾯的渲染和响应⽤⼾的交互。它使⽤WebView进⾏⻚⾯渲染,包括解析和 绘制DOM、布局、样式计算和渲染等操作。渲染线程是单线程的,所有的界⾯操作都在这个线程 中进⾏。
  • 2.逻辑线程(JS线程): 逻辑线程负责⼩程序的逻辑运算和数据处理。它是基于JavaScript运⾏的,负责处理⽤⼾交互、业 务逻辑、数据请求、事件处理等操作。逻辑线程是独⽴于渲染线程的,可以并⾏处理多个任务,避 免阻塞界⾯的渲染和响应。

将界⾯渲染和逻辑运算分离成两个线程的设计有以下好处:

  • 响应速度:逻辑线程和渲染线程分开,可以并⾏执⾏,提⾼了⼩程序的响应速度和⽤⼾体验。
  • 防⽌阻塞:逻辑线程的运⾏不会阻塞渲染线程,避免了⻓时间的计算或数据处理导致界⾯卡顿或⽆ 响应的情况。
  • 资源隔离:渲染线程和逻辑线程是独⽴的,它们有各⾃的资源和运⾏环境,可以避免相互⼲扰和影响。

需要注意的是,⼩程序的渲染线程和逻辑线程之间通过微信客⼾端进⾏通信和交互。逻辑线程可以发 送请求给微信客⼾端,然后客⼾端将渲染指令发送给渲染线程进⾏界⾯渲染,同时渲染线程可以将⽤ ⼾的交互事件发送给逻辑线程进⾏处理。这种通信⽅式保证了渲染和逻辑的协同⼯作,实现了⼩程序 的正常运⾏。 ⼩程序之所以有两个线程,是为了提⾼渲染速度、避免阻塞和资源隔离。渲染线程负责界⾯渲染,逻 辑线程负责业务逻辑和数据处理,两者通过微信客⼾端进⾏通信和交互,共同实现⼩程序的功能和性能。

web应⽤中如何对静态资源加载失败的场景做降级处理?

一、图片加载失败的降级处理

方法 1:使用 onerror 事件

<img src="real-img.jpg" onerror="this.src='fallback.jpg'" alt="头像" />

方法 2:JS 批量处理

document.querySelectorAll('img').forEach(img => {
  img.onerror = () => {
    img.src = '/default.png';
  };
});

二、CSS 加载失败的处理(间接处理)

CSS 加载失败通常不会抛出错误,但你可以设置 样式默认值 或用 JS 检查关键样式是否生效:

window.addEventListener('load', () => {
  const styleCheck = window.getComputedStyle(document.body).getPropertyValue('font-family');
  if (!styleCheck || styleCheck === 'initial') {
    // fallback
    const link = document.createElement('link');
    link.rel = 'stylesheet';
    link.href = '/fallback.css';
    document.head.appendChild(link);
  }
});

✅ 三、JS 脚本加载失败的降级处理

方法 1:使用 <script>onerror

<script src="main.js" onerror="loadFallback()"></script>
<script>
  function loadFallback() {
    const script = document.createElement('script');
    script.src = '/fallback.js';
    document.body.appendChild(script);
  }
</script>

方法 2:使用 window.onerrorwindow.addEventListener('error')

window.addEventListener('error', function (e) {
  if (e.target.tagName === 'SCRIPT' && e.target.src.includes('main.js')) {
    console.warn('main.js 加载失败,准备加载备用脚本');
    loadFallback();
  }
}, true);

✅ 四、动态资源懒加载失败(如模块/路由组件)

使用 Webpack + Vue/React 等框架时,可以对 import() 失败做处理:

import('some/module')
  .then(module => module.init())
  .catch(() => {
    // fallback logic
    import('./fallback-module').then(fallback => fallback.init());
  });

✅ 五、整体资源加载失败时的应急处理策略

  • 设置静态资源 CDN + 本地回退 机制
  • 对关键 JS 模块打入入口文件,避免模块级加载失败
  • 使用 service worker 缓存关键资源
  • 在页面底部显示提示:“资源加载失败,请刷新重试或联系管理员”

如何通过设置失效时间清除本地存储的数据?

要清除本地存储的数据,可以通过设置失效时间来实现。以下是⼀种常⻅的⽅法:

  1. 将数据存储到本地存储中,例如使⽤localStorage或sessionStorage。
  2. 在存储数据时,同时设置⼀个失效时间。可以将失效时间存储为⼀个时间戳或特定的⽇期时间。
  3. 在读取数据时,检查当前时间是否超过了失效时间。如果超过了失效时间,则认为数据已过期,需 要清除。
  4. 如果数据已过期,则使⽤localStorage.removeItem(key)或sessionStorage.removeItem(key)⽅法 删除该数据。 以下是⼀个⽰例代码:
// 存储数据
functionsetLocalStorageData(key,data,expiration)
{
var item = { data: data, expiration: expiration }; localStorage.setItem(key, JSON.stringify(item));
} 
// 读取数据
functiongetLocalStorageData(key){
varitem=localStorage.getItem(key);
if (item) {
item =JSON.parse(item);
if (item.expiration && new Date().getTime() > item.expiration)
{
// 数据已过期,清除数据 
localStorage.removeItem(key);return null;
}
return item.data; 
}
return null; } // ⽰例⽤法
vardata={name:'John',age:30};
var expiration = newDate().getTime() + 36001000; 
// 设置失效时间为当前时间后的1⼩时 setLocalStorageData('user', data, expiration); 
var storedData = getLocalStorageData('user'); console.log(storedData);

在⽰例代码中,setLocalStorageData函数⽤于存储数据,并接受⼀个失效时间参数。 getLocalStorageData函数⽤于读取数据,并检查失效时间是否已过期。如果数据已过期,则清除数 据。⽰例中的失效时间设置为当前时间后的1⼩时。