您当前的位置:首页 > 电脑百科 > 程序开发 > 前端

高级Web应用开发前沿技术简述

时间:2022-07-26 09:40:40  来源:  作者:移动Labs

作者:毛小俊

单位:中国移动智慧家庭运营中心

 

Tips:

  • 本文主要面向使用JAVAScript、WebAssembly、WebGL的Web 应用开发者。
  • 本文提及部分特性或API在Safari14.2以下版本中可能暂未支持,可以使用Safari Technology Preview - 14.2[1]调试。
  • 具体API的使用和支持情况可以参考 MDN Web Docs[2],但文档更新可能会有延迟。
  • 文末有示例代码链接。

本文知识目录:

高级Web应用开发前沿技术简述

 

1 JavaScript语法增强

1.1 使用#修饰类的属性、静态变量、方法,保证它们仅在类的内部可见

需要注意的是增加#后,#已经是名称的一部分,比如#_startTime才是一个完整的变量名。

//class with private variable and function
class PrivateStopWatchWithOneButton {
  //使用#定义私有变量
  #_startTime = 0;
  
  //使用#定义私有静态变量
  static #stopWatchCount = 0;
  
  click(){
    if (!this.#_startTime) {
      this.#start();




    }else{
      this.#stop();
    }
  }




  //使用#定义私有方法
  #start() {
    PrivateStopWatchWithOneButton.#stopWatchCount++;
    this.#_startTime = Date.now();
    console.log('StopWatch started');
  }
}




function demo(){
  var counter = new StopWatchWithOneButton();
  counter.click();
  counter.#stopWatchCount = 0; //SyntaxError
  counter.#start();//SyntaxError
}

1.2 WeakRef一种新的弱引用方法

Map和Set是JavaScript中常用的集合类型,为了实现更高效的垃圾回收,在部分情况下需要通过WeakMap和WeakSet实现对集合对象的弱引用,但是WeakMap和WeakSet没有Iterator接口,因而无法实现迭代的逻辑。所以Apple今年给出了几个新的接口,比如通过WeakRef获得对象的弱引用,同时可以通过FinalizationRegistry得知弱引用的对象被垃圾回收的时机,然后在注册的回调中执行一些清理操作。

其中关键的几个概念:

  • WeakRef:允许您保留对另一个对象的弱引用,而不会阻止被弱引用对象被GC回收。
  • FinalizationRegistry:可以让你在对象被垃圾回收时请求一个回调。
  • deref:返回WeakRef实例的目标对象,如果目标对象已被垃圾收集,则返回undefined 。

下面是一段伪代码:

class StopWatchWithOneButton {
  _startTime = 0;
  click(){
    //...
  }
  //some detAIl implimentation...
}




const allStopWatches  = new Map();
var nextAvailableIdentifier = 1;
function removeStopwatch(identifier){
  /*
  当map中引用的StopWatchWithOneButton对象由于某种原因(生命周期结束/手动销毁)被系统回收后,
  需要将当前的Map数据清理一下。
  */
  allStopWatches.delete(identifier);
}




//通过FinalizationRegistry新建一个注册表,同时注册关联的回调函数
const finalizationRegistry = new FinalizationRegistry(removeStopwatch);




function createStopwatch(){
  let identifier = nextAvailableIdentifier++;
  let stopwatch = new StopWatchWithOneButton();




  //WeakRef()获得stopwatch的弱引用
  allStopWatches.set(identifier, new WeakRef(stopwatch));
  /*将stopwatch注册到finalizationRegistry这个注册表中,当stopwatch被垃圾回收时,
    便会调用上面的removeStopwatch函数,实现allStopWatches这个map数据的清理。
  */
  finalizationRegistry.register(stopwatch, identifier);




  return stopwatch;
}




function clickAllStopwatches(){
  console.log('ready to click all buttons');
  for(let weakStopwatch in allStopWatches.values()){
    //迭代获取weakStopwatch,通过deref()判断对象是否被GC
    weakStopwatch.deref()?.click();
  }
}

但是由于FinalizationRegistry的运行依赖于GC,GC的运行又依赖于event loop机制,所以存在一些不确定性。比如回调时机可能和你预期的不一致,所以在使用之前要评估下你的场景是否适用这几个方法,避免掉到坑里。

1.3 采用await方式import Module

await这个概念出现在了很多的编程语言中,它的最主要特征就是简化异步调用,让代码的可读性极大增强。原来await只能在async函数中使用,但是现在也可以在import module的时候使用,让module之间的依赖管理变得更加简单,比如像下面这样:

上述await方法的使用,有以下两个效果:

1️⃣stopwatch = new StopWatchWithOneButton();会在import执行完成之后再执行。

2️⃣如果被import的stopwatchInModule.js中有异步任务执行,stopwatch = new StopWatchWithOneButton();会在异步任务执行完成后继续执行。

需要注意的是,await用来import module的时候仅在module类型的script中有效,其他类型的script会直接报错。

1.4 在worker中使用module

由于JavaScript采用的是单线程模型,Web worker则为JavaScript创造了多线程环境,主线程可以通过创建Worker在子线程中执行一些脚本,将一些计算密集型或者高延迟的任务放到后台运行,保证UI交互的流畅性。而Module则可以实现动态import、对加载和执行实现优化、实现依赖管理。所以在worker中使用Module可以更轻松的将一些heavy work转移到后台线程。module现在可以应用于多种不同类型的worker中,比如:web worker、service worker和worklet。

具体的使用方法如下:

//在web worker中的用法
let worker = new Worker(moduleScriptURL,{type:"module"})
//在service worker中的用法
nivagator.serviceWorker.register(scriptURL,{type:"module"});
//在worklet中的用法
var audioContext = new AudioContext();
dusioContext.audioWorklet.addModule(moduleScriptURL);

1.5 Internationalization API的更新

更新了5个国际化的API,分别如下:

  • Intl.NumberFormat 设置数字显示格式
  • Intl.DateTimeFormat 根据不同国家设置时间/日期的显示格式
  • Intl.Segmenter 根据不同语言的语法规则进行分词
  • Intl.ListFormat 根据不同语言的语法进行连词
  • Intl.DisplayNames 自动根据当前页面设置的语言,展示语言切换内容

其中最值得一提的是Intl.Segmenter,可以实现语句的分词功能,在做一些算法的时候进行分词是一项基本的工作,在此基础之上可以做很多有趣的功能,更详细的代码参见demo,感兴趣的同学不妨一试。

 

2 WebAssembly

2008年很多浏览器中开始引入JITs,实现了js运行速度的骤然提升,而WebAssembly被认为可能是web应用性能提升的又一个转折点,funkykarts[3]就是一个采用WebAssembly的例子,其实funkykarts的源码是使用C++来实现的,那在Web中的这一切又是怎么做到的呢?

WebAssembly 可以理解为一种web版的汇编,其实它并不是一种编程语言,但是可为C/C++/Rust等高级语言提供一个高效的编译目标,使Web应用程序获得和原生App相媲美的性能。这就意味着,对于一个现成的Native应用,为了将它移植到web中,不需要从头开始编写JavaScript代码,通过WebAssembly将它编译成浏览器支持的wasm模块,然后通过Webassembly API执行调用即可。这一过程如下图所示:

高级Web应用开发前沿技术简述

 

上图中Emscripten是一种生成wasm的工具,目前常见的这类工具还包括:

高级Web应用开发前沿技术简述

 

目前Chrome、FireFox和Safari都已支持WebAssembly,在具体的功能上还存在些微差异,具体的支持情况可以可以在 WebAssembly 官网[4]找到。

从WebAssembly 展示的信息可以看到Chrome、FireFox、Safari等浏览器对WebAssembly增加了多项功能的支持,具体包括在以下几个方面:

  • 通过采用新的内存指令让批量内存操作具备更好的性能。比如批量的复制和初始化操作。
  • 通过新的指令告诉用户进程在部分情况下无需捕获异常。比如在在float和int之间转换时的正溢出。
  • 新增了符号扩展运算符,实现低位数转高位数,所谓的低位数转高位数的基本原理就是在低位数的左边补上低位数的符号位,直到数字位数达到要求。用来实现WebAssembly的i64类型和JavaScript的BigInt数据类型之间的转换,这一改进可以提高代码的执行速度并且比之前的实现方法更加简单。
  • 增加了新的引用类型,允许WebAssembly模块持有JavaScript和DOM对象的引用,并且可以传递和保存它们。
  • 通过数据流式的下载和编译,缩短了整体执行时间。

 

3 New Web APIs

这部分主要是介绍部分新颖的API以及他们各自适用的不同场景,有些功能还是很有意思的,比如Speech Recogintion可以借助Siri引擎实现实时文本转换,Web Share功能今年新增了文件共享,而Storage Access在保证用户Cookies安全性的前提下增加了适用范围。下面分别介绍一下它们:

3.1 WebGL2.0

WebGL是实现页面渲染的不二法门,可以帮助开发者在Web中实现非常绚丽的画面效果,就像下图这样,Apple这次在Safari和Webkit中为我们带来了WebGL2.0的支持,下面我们就简单解下什么是WebGL2.0:

WebGL2.0是基于OpenGL ES 3.0实现的Web API,核心是WebGL2RenderingContext接口,在WebGL1的基础上增加了很多的新特性,比如:

  • 增加了3d纹理,能够渲染出像云朵一样的volumetric effects(容积效果)。
  • 它的WebGLSampler可以用来存储一系列采样参数,在着色器中使用纹理更加灵活。
  • 增加了Transform Feedback来帮助在GPU上实现高性能的粒子系统效果。

由于旧版本的Safari不支持WebGL2.0,所以之前只能通过WebGL1.0实现部分效果,但是从14.2版本开始,所有苹果设备上的Safari都可以支持WebGL2.0,更重要的是今年Apple将WebGL的底层实现从OpenGL迁移到了Metal,这就意味着可以使用IOS模拟器愉快的调试WebGL代码了,同时可以使用Xcode frame debugger来分析webGL的代码,对开发者来说是真的很香。

但是由于WebGL毕竟是相对底层的API,可能不是那么容易上手,所以Apple推荐开发者使用现成的封装库提高开发的效率,比如A-frame、babylon.js、playcanvas、three.js等.

3.2 WebM & VP9

WebM是一种免版权的视频文件格式,它定义了文件的容器结构、视频和音频格式,WebM文件由使用VP8或VP9视频编解码器压缩的视频流和使用Vorbis或Opus音频编解码器压缩的音频流组成。WebM和MP4等格式相比,在保证出色视频质量的前提下有更高的压缩率,国外的YouTube,国内的腾讯视频都支持WebM格式视频的上传发布。Safari也终于在今年增加了对WebM的支持。

  • macOS11.3 支持VP8/VP9视频格式 + Vorbis音频的WebM文件
  • macOS12 支持VP8/VP9视频格式 + Vorbis/Opus音频的WebM文件
  • iPadOS15 支持通过Media Source Extension API来播放WebM文件

由于不同设备对WebM支持的情况存在差异,在实际编码中可以通过MediaCapabilities API判断当前设备是否支持WebM。

const mediaconfig = {
  type = 'media-source',
  video:{
    contentType: 'video/webm; codecs="vp09.00.10.08"'
    width: 1920, height:1080, bitrate:2646242,
  }
};
navigator.mediaCapabilities.decodingInfo(mediaConfig).then(
  //do something else
)

上文提及的VP9是一种在性能上可以和H265一较高下的视频编码技术,目前可以应用于macOS/iPadOS上的Streaming和WebRTC应用中,但是在其他设备上还需要根据上述的API来判断是否支持。如果希望web内容中的视频具备更好的浏览器兼容性,还是更推荐H264或者HEVC的编码格式,HEVC对高视频的支持更加完善。

3.3 Storage Access

在网页中播放来自第三方的视频内容是一种很常见的应用形态,比如要在main.domain的Web页面中播放来自video.domain的视频内容,通常有两种方式:

1.直接从video.domain获取内容。

2.创建一个iframe用于加载video.domain的内容。

但是出于安全考虑,由于IPT策略的限制,默认情况下第三方的iframe是没有权限访问宿主站点下的storage数据的。也就是说假如video.com的资源请求是从main.com发起的,这个请求就无法访问video.com域名下存储的cookies信息。这就意味着video.com在向授权用户提供资源的时候会出现问题,没有cookies就意味着无法通过认证。

高级Web应用开发前沿技术简述

 

这时候借助The Storage Access API向用户申请了授权,像这样:

高级Web应用开发前沿技术简述

 

那么第三方iframe就可以拿到宿主站点存储的cookies信息了。

高级Web应用开发前沿技术简述

 

这个The Storage Access API现有主流浏览器和webkit已经支持,具体用法如下:

document.hasStorageAccess().then(hasAccess => {
  if (hasAccess) {
    // storage access has been granted already.
  } else {
    // storage access hasn't been granted already;
    // you may want to call requestStorageAccess().
  }
});

为了增加适用范围,今年又新增了两个特性:

1.可以在per-page scope中申请用户授权,这样做的目的就是一旦用户对一个第三方iframe进行了授权,在同一页面上的所有其他资源也可以获得相同的访问授权,也就不用为每一个iframe都进行访问授权了。

2.允许嵌套在iframe中的iframe向宿主获取Cookies信息。

3.4 Media Recorder & Audio Worklet

这部分主要介绍如果通过Media Recorder在Web上实现录音功能,随后通过Audio Worklet实现音频的加工。下面这部分代码就是录音功能的简单实现。需要注意的在处理录音逻辑之前,需要首先通过
navigator.mediaDevices.getUserMedia的方式向用户申请录音权限。

var recorder;
async function startRecording() {
  try{
    //await方式向用户获取录音权限
    let stream = await navigator.mediaDevices.getUserMedia({ audio: true});
    recorder = new MediaRecorder(stream);
    recorder.addEventListener('dataavailable', onDataAvailable);
    recorder.addEventListener('stop', onStop);
    recorder.start();
  } catch(error){
    console.log(error);
  }
}




function stopRecording() {
  if(recorder) {
    recorder.stop();
  }
}




//create downlaodable data
var dataChunks = [];
function onDataAvailable(event) {
  dataChunks.push(event.data);
}




function onStop() {
  const blob = new Blob(dataChunks, {'type': 'audio/mp3'});
  let audio = document.getElementById('audio');
  audio.src = URL.createObjectURL(blob);
}




Audio Worklet API的作用是通过调用自定义脚本实现音频处理,这里的脚本可以是js或wasm。当前的Module和自定义的js之间通过AudioWorkletNode实现连接。与之前Safari中运行自定义脚本的解决方案ScriptProcessorNode相比,它减少了渲染线程和主线程之间的频繁切换,确保了更低延迟的实现音频处理。使用方法如下:




//使用AudioWorklet自定义语音处理脚本
let stream = await navigator.mediaDevices.getUserMedia({ audio: true});//获取用户授权
//process input data using AudioWorklet API
let audioContext = new AudioContext();
let source = audioContext.createMediaStreamSource(stream);//创建一个source
await audioContext.audioWorklet.addModule('distortion-processor.js');
const workletNode = new AudioWorkletNode(audioContext, 'distortion-processor');
let destination = audioContext.createMediaStreamDestination();
source.connect(workletNode).connect(destination);//把连接了自定义实现的workletNode和输出关联在一起




mediaRecorder = new MediaRecorder(destination.stream);
mediaRecorder.addEventListener('dataavailable', onDataAvailable);
mediaRecorder.addEventListener('stop', onStop);
mediaRecorder.start();
其中distortion-processor.js就是自定义的音频处理脚本,实现如下:
//audio processing script for AudioWorklet
//这个类必须继承自AudioWorkletProcessor,并且实现其中的process方法
class DistorationProcessor extends AudioWorkletProcessor {
  process(inputs, outputs) {
    const input = inputs[0];
    const output = outputs[0];




    for (let i = 0; i < output.length; ++i) {
      output[i].set(input[i]);//实现自定义的音频处理方法,这里只是为了演示把数据取出来又重新放进去~~
    }
    return true;//返回true表示当前处理节点仍旧处于活跃状态,用户可以根据自己的业务逻辑确定是否关闭该节点。
  }
}




registerProcessor('distortion-processor', DistorationProcessor);//全局注册一下,保证可以创建AudioWorkletNode

3.5 WebShare

通过WebShare API可以唤起系统原生的共享功能,在macOS和iOS系统上支持的渠道包括邮件、备忘录、短信、AirDrop等,但是在此之前由于只支持URL的共享,所以实用性并不是很强,也很少有Web页面会特地去使用这个功能。但是在最新版的Safari中增加了对文件共享的支持,包括图片、视频、音频在内多种形式的内容都可以被分享出去,关于分享渠道,除了前面提及的邮件等,还可以分享到微信、QQ等三方App,甚至可以通过Extension的形式为自己的App在系统的共享功能中增加入口,这样就可以实现Web页面内容的快速社交化分享了~,调用也很简单,通过navigator.canShare()判断是否支持共享,通过navigator.share唤起共享,具体如下:

function share() {
  let file = new File([blob], 'memo.mp3');//这是使用前文Media Recorder API生成的音频文件
  let filesArray = [file];//注意这里需要array类型的入参,意味着一次可以共享多个文件
  if (navigator.canShare && navigator.canShare({files: filesArray})) {
    navigator.share({
      files: filesArray,
      title: 'memo.mp3',
      text:'I just created a really interesting recording!',
    })
  }
}

3.6 Speech Recognition

这是一项很酷的功能,简单来说就是在Web应用中实现语音到文本的实时转换,至于转换的准确率可以不用担心,因为这套API在macOS上采用的就是Siri引擎,同时支持多种语言,只需要在api中明确需要转换的语言类型即可。使用下面的方法就可以初始化并启动强大的识别功能了:

//start and stop speech recognition
var recognition;
function startRecognition(){
  if (webkitSpeechRecognition) {
    recognition = new webkitSpeechRecognition();
    recognition.continuous = true;//要求识别持续进行,直到停止。
    recognition.interimResults = true;//设置是否允许临时结果,临时结果是识别的中间过程,这时候返回结果的isFinal = false。
    recognition.lang = 'cmn-Hans-CN'; //普通话 (中国大陆)
    recognition.onresult = onRecognitionResult;//收到结果回调时执行的方法
    recognition.onend = onRecognitionEnd;//识别结束时调用的方法




    recognition.start();
  }
}




function stopRecognition(){
  if(recognition){
    recognition.stop();
  }
}

在demo中笔者尝试用Media Recorder录了一段语音,然后使用Speech Recognition进行转换,测试下来整体感觉翻译的很流畅,速度很快,准确率基本上没有问题,需要注意的是由于需要使用Siri引擎,所以要在系统偏好或设置中打开Siri或听写功能。具体的使用效果你们可以感受一下。

高级Web应用开发前沿技术简述

 


高级Web应用开发前沿技术简述

 


高级Web应用开发前沿技术简述

 

这部分功能看起来是比较值得期待的,语音输入作为一个交互入口,应该会有比较强的可用场景,比如语音搜索、在线笔记等。

3.7 MediaSession

当用户在Safari中播放音视频时,macOS的状态栏和iOS的负一屏就会出现一个Now Playing widget,但是点击这个widget后会发现其实它只是展示了一个网页标题,并没有其他的任何信息,不过现在通过media session API就可以在widget中增加更丰富的内容,比如播放进度、快进、快退、暂停操作等,总之media session API在Web应用和系统的其他组件之间实现了媒体状态的共享,这也是WWDC21 很重要的一部分内容,更详细的内容可以参考另外一个session: Coordinate media playback in Safari with Group Activities [5].

 

4 关于Demo和调试

为了便于大家调试本文提及的部分功能,我把demo的代码放在了这里[6]。

可以使用Mac自带的Apache进行调试,调试的步骤如下:

  • 运行 Apache $ sudo apachectl start
  • 退出 Apache $ sudo apachectl stop
  • 把工程文件夹放到以下位置中 /Library/WebServer/Documents
  • 在浏览器中访问:在地址栏中输入地址 http://localhost/工程文件夹名称/,回车。

⚠注意: 不再需要使用后一定要记得退出,否则会消耗电脑性能。

 

5 总结

为了增强用户体验和提高开发效率,Web开发近些年增加的亮点还是不少的,总体可以总结如下:

  1. JS语法增强是一些十分实用的小功能,对开发者来说增加了不少便利性。
  2. 在web页面中增加WebM & VP9的支持会是音视频网站的福音。
  3. 支持语音录制和编辑暂时想到的使用场景是在网页上进行便捷的语音搜索,更强的使用场景有待探索。
  4. 对Storage Access的改进是一个十分实用场景需求。
  5. 对WebGL2的支持算是为开发者省去了不少兼容性的烦恼。

希望对Web开发者有所帮助~

 

参考文献

[1]https://developer.apple.com/safari/technology-preview/

[2]https://developer.mozilla.org/en-US/

[3]https://www.funkykarts.rocks/demo.html

[4]https://webassembly.org/roadmap/

[5]https://developer.apple.com/videos/play/wwdc2021/10189/

[6]https://gitee.com/lysqj/wwdc2021/tree/develop/



Tags:Web应用   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除。
▌相关推荐
如何保护应用?Web应用防火墙详细解读
如今,多云环境、API安全功能扩展、合作伙伴集成即时可用、可用性和可视化增强以及提高自动化程度已经成为基本要求。伴随企业应用架构的迁移,在用户端,需要在部署环境不断扩展...【详细内容】
2023-12-06  Search: Web应用  点击:(146)  评论:(0)  加入收藏
什么是web应用防护系统(WAF)?
Web应用防护系统(WAF)是一种专门为Web应用提供保护的产品,它通过执行一系列针对HTTP/HTTPS的安全策略来实现这一目标。WAF可以过滤、监控和阻止任何流向Web应用程序的恶意HTTP/...【详细内容】
2023-11-26  Search: Web应用  点击:(194)  评论:(0)  加入收藏
通过实例理解Web应用跨域问题
在开发Web应用的过程中,我们经常会遇到所谓“跨域问题(Cross Origin Problem)”。跨域问题是由于浏览器的同源策略(Same-origin policy)[1]导致的,它限制了不同源(Origin:域名...【详细内容】
2023-11-20  Search: Web应用  点击:(164)  评论:(0)  加入收藏
使用Docker来编排Web应用
前言使用docker可以轻松构建一个项目并运行,然而在真实的使用场景中,我们的项目并非是单一的,而是多个项目相互依赖组成一个web应用。考虑这样一个场景,一个正在运行的web应用,它...【详细内容】
2023-11-16  Search: Web应用  点击:(300)  评论:(0)  加入收藏
打造高质量Web应用程序:React 和 Vue 框架对比和实践经验总结
React 和 Vue 是两个目前非常流行的JavaScript框架,用于构建高质量的Web应用程序。它们都有自己的优点和适用场景,并且都被广泛使用。下面将对React和Vue进行对比,并总结一些实...【详细内容】
2023-10-27  Search: Web应用  点击:(294)  评论:(0)  加入收藏
掌握Nginx的高级用法,构建高性能Web应用
Nginx是一款高性能的Web服务器和反向代理服务器,它广泛用于构建高性能、可靠和安全的Web应用程序。除了基本的用法外,Nginx还提供了一些高级功能和配置选项,可以进一步优化性能...【详细内容】
2023-10-26  Search: Web应用  点击:(220)  评论:(0)  加入收藏
如何使用Docker进行Web应用的快速部署
本文将向大家介绍如何使用Docker进行Web应用的快速部署。作为一种轻量级容器技术,Docker可以极大地简化系统部署的流程,提高开发和运维效率。跟随本文的步骤,让我们一起探索Doc...【详细内容】
2023-09-15  Search: Web应用  点击:(225)  评论:(0)  加入收藏
Django 入门:构建Python Web应用的全面指南
引言Django 是一个强大的Python Web框架,它以快速开发和高度可扩展性而闻名。本文将带您深入了解Django的基本概念和核心功能,帮助您从零开始构建一个简单的Web应用。什么是Dj...【详细内容】
2023-08-20  Search: Web应用  点击:(144)  评论:(0)  加入收藏
什么是Web应用程序防火墙,WAF与其他网络安全工具差异在哪?
一、什么是Web 应用程序防火墙 (WAF) ? WAF软件产品被广泛应用于保护Web应用程序和网站免受威胁或攻击,它通过监控用户、应用程序和其他互联网来源之间的流量,有效防御跨站点伪...【详细内容】
2023-08-14  Search: Web应用  点击:(259)  评论:(0)  加入收藏
HTTP缓存如何提高Web应用程序的性能?
缓存是一种可以帮助网络连接更快的技术,因为需要传输的东西越少越好。许多资源可能非常大,检索的时间和实际成本(例如,在移动设备上)都非常昂贵。HTTP缓存是用于减少HTTP请求次数...【详细内容】
2023-03-30  Search: Web应用  点击:(130)  评论:(0)  加入收藏
▌简易百科推荐
20k级别前端是怎么使用LocalStorage的,想知道吗?
当咱们把咱们想缓存的东西,存在localStorage、sessionStorage中,在开发过程中,确实有利于咱们的开发,咱们想看的时候也是一目了然,点击Application就可以看到。前言大家好,我是林...【详细内容】
2024-03-26  前端之神  微信公众号  Tags:前端   点击:(14)  评论:(0)  加入收藏
前端不存在了?盲测64%的人更喜欢GPT-4V的设计,杨笛一等团队新作
3 月 9 日央视的一档节目上,百度创始人、董事长兼 CEO 李彦宏指出,以后不会存在「程序员」这种职业了,因为只要会说话,人人都会具备程序员的能力。「未来的编程语言只会剩下两种...【详细内容】
2024-03-11  机器之心Pro    Tags:前端   点击:(17)  评论:(0)  加入收藏
前端开始“锈化”?Vue团队开源JS打包工具:基于Rust、速度极快、尤雨溪主导
Vue 团队已正式开源Rolldown &mdash;&mdash; 基于 Rust 的 JavaScrip 打包工具。Rolldown 是使用 Rust 开发的 Rollup 替代品,它提供与 Rollup 兼容的应用程序接口和插件接口...【详细内容】
2024-03-09  OSC开源社区    Tags:Vue   点击:(23)  评论:(0)  加入收藏
两年前端经验还不会手写Promise?
什么是promise?当我们处理异步操作时,我们经常需要进行一系列的操作,如请求数据、处理数据、渲染UI等。在过去,这些操作通常通过回调函数来处理,但是回调函数嵌套过多会导致代码...【详细内容】
2024-03-07  海燕技术栈  微信公众号  Tags:Promise   点击:(31)  评论:(0)  加入收藏
网站开发中的前端和后端开发有什么区别
前端开发和后端开发都是干什么的?有哪些区别?通俗地讲,前端干的工作是用户可以直接看得见的,而后端开发的工作主要在服务端,用户不太能直接看到。虽然前端开发和后端开发的工作有...【详细内容】
2024-02-21  CarryData    Tags:前端   点击:(37)  评论:(0)  加入收藏
网站程序开发中的前后端分离技术
随着互联网的快速发展和技术的不断创新,传统的网站开发模式已经难以满足日益增长的业务需求。为了提高开发效率、增强系统的可维护性和可扩展性,前后端分离技术逐渐成为了网站...【详细内容】
2024-01-31  网站建设派迪星航    Tags:前后端分离   点击:(27)  评论:(0)  加入收藏
如何优雅的实现前端国际化?
JavaScript 中每个常见问题都有许多成熟的解决方案。当然,国际化 (i18n) 也不例外,有很多成熟的 JavaScript i18n 库可供选择,下面就来分享一些热门的前端国际化库!i18nexti18ne...【详细内容】
2024-01-17  前端充电宝  微信公众号  Tags:前端   点击:(78)  评论:(0)  加入收藏
Vue中Scope是怎么做样式隔离的?
scope样式隔离在 Vue 中,样式隔离是通过 scoped 特性实现的。当在一个组件的 <style> 标签上添加 scoped 特性时,Vue 会自动为这个样式块中的所有选择器添加一个唯一的属性,以...【详细内容】
2024-01-04  海燕技术栈  微信公众号  Tags:Vue   点击:(85)  评论:(0)  加入收藏
vue3中 ref和 reactive的区别 ?
最近有朋友在面试过程中经常被问到这么一个问题,vue3 中的ref 和 reactive的区别在哪里,为什么 要定义两个API 一个 api不能实现 响应式更新吗??带着这个疑问 ,我们 接下来进行逐...【详细内容】
2024-01-03  互联网高级架构师  今日头条  Tags:vue3   点击:(47)  评论:(0)  加入收藏
React18 与 Vue3 全方面对比
1. 编程风格 & 视图风格1.1 编程风格 React 语法少、难度大;Vue 语法多,难度小例如指令:Vue<input v-model="username"/><ul> <li v-for="(item,index) in list" :key="inde...【详细内容】
2024-01-03  爱做梦的程序员  今日头条  Tags:Vue3   点击:(78)  评论:(0)  加入收藏
站内最新
站内热门
站内头条