我工作中用到的性能优化全面指南(2)

简介: 使用WebGL进行3D渲染WebGL是一种用于进行3D渲染的Web标准,它提供了底层的图形API,并且能够利用GPU进行加速,非常适合于进行复杂的3D渲染。

使用WebGL进行3D渲染

WebGL是一种用于进行3D渲染的Web标准,它提供了底层的图形API,并且能够利用GPU进行加速,非常适合于进行复杂的3D渲染。

var canvas = document.getElementById('myCanvas');
var gl = canvas.getContext('webgl');
// 设置清空颜色缓冲区的颜色
gl.clearColor(0.0, 0.0, 0.0, 1.0);
// 清空颜色缓冲区
gl.clear(gl.COLOR_BUFFER_BIT);

使用Service Workers进行资源缓存

Service Workers可以让你控制网页的缓存策略,进一步减少HTTP请求,提升网页的加载速度。例如,你可以将一些不常变化的资源文件预先缓存起来。

// 注册一个service worker
navigator.serviceWorker.register('/service-worker.js').then(function(registration) {
  console.log('ServiceWorker registration successful with scope: ', registration.scope);
}).catch(function(error) {
  console.log('ServiceWorker registration failed: ', error);
});
// service-worker.js
self.addEventListener('install', function(event) {
  event.waitUntil(
    caches.open('my-cache').then(function(cache) {
      return cache.addAll([
        '/style.css',
        '/script.js',
        // 更多资源...
      ]);
    })
  );
});
self.addEventListener('fetch', function(event) {
  event.respondWith(
    caches.match(event.request).then(function(response) {
      return response || fetch(event.request);
    })
  );
});

使用内容分发网络(CDN)

你可以将静态资源(如JavaScript、CSS、图片等)上传到CDN,这样用户可以从离他们最近的服务器下载资源,从而提高下载速度。

<!-- 从CDN加载jQuery库 -->
<script src="https://cdn.example.com/jquery.min.js"></script>

使用HTTP/2进行资源加载

HTTP/2支持头部压缩和多路复用,可以更高效地加载资源。如果你的服务器和用户的浏览器都支持HTTP/2,那么你可以使用它来提高性能。

// 假设我们有一个HTTP/2库
var client = new Http2Client('https://example.com');
client.get('/resource1');
client.get('/resource2');

使用Web Socket进行数据通信

如果你需要频繁地与服务器进行数据交换,可以使用Web Socket,它比HTTP有更低的开销。

var socket = new WebSocket('ws://example.com/socket');
socket.addEventListener('open', function() {
  socket.send('Hello, server');
});
socket.addEventListener('message', function(event) {
  console.log('Received message from server: ' + event.data);
});

使用Progressive Web Apps(PWA)技术

PWA可以让你的网站在离线时仍然可用,并且可以被添加到用户的主屏幕,提供类似于原生应用的体验。PWA需要使用Service Workers和Manifest等技术。

// 注册Service Worker
navigator.serviceWorker.register('/service-worker.js');
// 检测是否支持Manifest
if ('manifest' in document.createElement('link')) {
  var link = document.createElement('link');
  link.rel = 'manifest';
  link.href = '/manifest.json';
  document.head.appendChild(link);
}

使用WebRTC进行实时通信

WebRTC是一种提供实时通信(RTC)能力的技术,允许数据直接在浏览器之间传输,对于需要实时交互的应用,如视频聊天、实时游戏等,可以使用WebRTC来提高性能。

var pc = new RTCPeerConnection();
// 发送offer
pc.createOffer().then(function(offer) {
  return pc.setLocalDescription(offer);
}).then(function() {
  // 发送offer给其他浏览器...
});
// 收到answer
pc.setRemoteDescription(answer);

使用IndexedDB存储大量数据

如果你需要在客户端存储大量数据,可以使用IndexedDB。与localStorage相比,IndexedDB可以存储更大量的数据,并且支持事务和索引。

var db;
var request = indexedDB.open('myDatabase', 1);
request.onupgradeneeded = function(event) {
  db = event.target.result;
  var store = db.createObjectStore('myStore', { keyPath: 'id' });
  store.createIndex('nameIndex', 'name');
};
request.onsuccess = function(event) {
  db = event.target.result;
};
request.onerror = function(event) {
  // 错误处理...
};

使用Web Push进行后台消息推送

Web Push允许服务器在后台向浏览器推送消息,即使网页已经关闭。这需要在Service Worker中使用Push API和Notification API。

// 请求推送通知的权限
Notification.requestPermission().then(function(permission) {
  if (permission === 'granted') {
    console.log('Push notification permission granted');
  }
});
// 订阅推送服务
navigator.serviceWorker.ready.then(function(registration) {
  registration.pushManager.subscribe({ userVisibleOnly: true }).then(function(subscription) {
    console.log('Push subscription: ', subscription);
  });
});
// 在Service Worker中接收和显示推送通知
self.addEventListener('push', function(event) {
  var data = event.data.json();
  self.registration.showNotification(data.title, data);
});

通过服务器端渲染(SSR)改善首次页面加载性能

服务器端渲染意味着在服务器上生成HTML,然后将其发送到客户端。这可以加快首次页面加载速度,因为用户可以直接看到渲染好的页面,而不必等待JavaScript下载并执行。这对于性能要求很高的应用来说,是一种有效的优化手段。

// 服务器端
app.get('/', function(req, res) {
  const html = ReactDOMServer.renderToString(<MyApp />);
  res.send(`<!DOCTYPE html><html><body>${html}</body></html>`);
});

利用HTTP3/QUIC协议进行资源传输

HTTP3/QUIC协议是HTTP/2的后续版本,采用了全新的底层传输协议(即QUIC),以解决HTTP/2中存在的队头阻塞(Head-of-line Blocking)问题,从而进一步提高传输性能。如果你的服务器和用户的浏览器都支持HTTP3/QUIC,那么可以考虑使用它进行资源传输。

使用Service Worker与Background Sync实现离线体验

通过Service Worker,我们可以将网络请求与页面渲染解耦,从而实现离线体验。并且,结合Background Sync,我们可以在用户离线时提交表单或同步数据,并在用户重新联网时自动重试。

// 注册Service Worker
navigator.serviceWorker.register('/sw.js');
// 提交表单
fetch('/api/submit', {
  method: 'POST',
  body: new FormData(form)
}).catch(() => {
  // 如果请求失败,使用Background Sync重试
  navigator.serviceWorker.ready.then(reg => {
    return reg.sync.register('sync-submit');
  });
});
// 在Service Worker中监听sync事件
self.addEventListener('sync', event => {
  if (event.tag === 'sync-submit') {
    event.waitUntil(submitForm());
  }
});

使用PostMessage进行跨文档通信

如果你的应用涉及到多个窗口或者iframe,你可能需要在他们之间进行通信。使用postMessage方法可以进行跨文档通信,而不用担心同源策略的问题。

// 父窗口向子iframe发送消息
iframeElement.contentWindow.postMessage('Hello, child', 'https://child.example.com');
// 子iframe接收消息
window.addEventListener('message', function(event) {
  if (event.origin !== 'https://parent.example.com') return;
  console.log('Received message: ' + event.data);
});

使用Intersection Observer进行懒加载

Intersection Observer API可以让你知道一个元素何时进入或离开视口,这对于实现图片或者其他资源的懒加载来说非常有用。

var images = document.querySelectorAll('img.lazy');
var observer = new IntersectionObserver(function(entries, observer) {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      var img = entry.target;
      img.src = img.dataset.src;
      observer.unobserve(img);
    }
  });
});
images.forEach(img => {
  observer.observe(img);
});

利用OffscreenCanvas进行后台渲染

OffscreenCanvas API使得开发者可以在Web Worker线程中进行Canvas渲染,这可以提高渲染性能,尤其是在进行大量或者复杂的Canvas操作时。

var offscreen = new OffscreenCanvas(256, 256);
var ctx = offscreen.getContext('2d');
// 在后台线程中进行渲染...

利用Broadcast Channel进行跨标签页通信

Broadcast Channel API提供了一种在同源的不同浏览器上下文之间进行通信的方法,这对于需要在多个标签页之间同步数据的应用来说非常有用。

javascript

复制代码

var channel = new BroadcastChannel('my_channel');
// 发送消息
channel.postMessage('Hello, other tabs');
// 接收消息
channel.onmessage = function(event) {
  console.log('Received message: ' + event.data);
};

使用Web Cryptography API进行安全操作

Web Cryptography API 提供了一组底层的加密API,使得开发者可以在Web环境中进行安全的密码学操作,例如哈希、签名、加密、解密等。

window.crypto.subtle.digest('SHA-256', new TextEncoder().encode('Hello, world')).then(function(hash) {
  console.log(new Uint8Array(hash));
});


         

使用Blob对象进行大型数据操作

Blob对象代表了一段二进制数据,可以用来处理大量的数据,比如文件。它们可以直接从服务端获取,或者由客户端生成,这对于处理大型数据或者二进制数据很有用。

javascript

复制代码

var fileInput = document.querySelector('input[type="file"]');
fileInput.addEventListener('change', function(event) {
  var file = event.target.files[0];
  var reader = new FileReader();
  reader.onload = function(event) {
    var contents = event.target.result;
    processContents(contents);
  };
  reader.readAsArrayBuffer(file);
});

使用Page Visibility API进行页面可见性调整

Page Visibility API提供了一种方式来判断页面是否对用户可见。利用这个API,你可以在页面不可见时停止或减慢某些操作,例如动画或视频,从而节省CPU和电池使用。

document.addEventListener('visibilitychange', function() {
  if (document.hidden) {
    pauseAnimation();
  } else {
    resumeAnimation();
  }
});

使用WeakMap和WeakSet进行高效的内存管理

在处理大量数据时,如果不小心可能会产生内存泄漏。WeakMap和WeakSet可以用来保存对对象的引用,而不会阻止这些对象被垃圾回收。这在一些特定的应用场景中,例如缓存、记录对象状态等,可能非常有用。

 

let cache = new WeakMap();
function process(obj) {
  if (!cache.has(obj)) {
    let result = /* 对obj进行一些复杂的处理... */
    cache.set(obj, result);
  }
  return cache.get(obj);
}

使用requestAnimationFrame进行动画处理

requestAnimationFrame能够让浏览器在下一次重绘之前调用指定的函数进行更新动画,这样可以保证动画的流畅性,并且减少CPU的使用。

function animate() {
 // 更新动画...
  requestAnimationFrame(animate);
}
requestAnimationFrame(animate);

使用CSS3动画替代JavaScript动画

CSS3动画不仅可以提供更好的性能,还可以在主线程之外运行,从而避免阻塞UI。因此,我们应该尽可能地使用CSS3动画替代JavaScript动画。

css

复制代码

@keyframes fadeIn {
  from { opacity: 0; }
  to { opacity: 1; }
}
.myDiv {
  animation: fadeIn 2s ease
-in-out;
}

避免回流和重绘

回流和重绘是浏览器渲染过程中的两个步骤,它们对性能影响很大。优化的关键在于尽可能减少触发回流和重绘的操作,例如一次性修改样式,避免布局抖动等。

javascript

复制代码

var el = document.getElementById('my-el');
el.style.borderLeft = '1px';
el.style.borderRight = '2px';
el.style.padding = '5px';
// 尽量避免上面的写法,以下为优化后的写法
el.style.cssText += 'border-left: 1px; border-right: 2px; padding: 5px;';

使用CSS3硬件加速提高渲染性能

使用 CSS3 的 transform 属性做动画效果,可以触发硬件加速,从而提高渲染性能。

javascript

复制代码

element.style.transform = 'translate3d(0, 0, 0)';

避免使用同步布局

同步布局(或强制布局)是指浏览器强制在 DOM 修改和计算样式之后,立即进行布局。这会中断浏览器的优化过程,导致性能下降。一般出现在连续的样式修改和读取操作之间。

let div = document.querySelector('div');
// 写样式
div.style.width = '100px';
// 读样式,导致同步布局
let width = div.offsetWidth;
// 再写样式
div.style.height = width + 'px';  // 强制布局

为避免这个问题,可以将读操作移到所有写操作之后:

let div = document.querySelector('div');
// 写样式
div.style.width = '100px';
// 写样式
div.style.height = '100px';
// 读样式
let width = div.offsetWidth;

使用ArrayBuffer处理二进制数据

ArrayBuffer 提供了一种处理二进制数据的高效方式,例如图像,声音等。

var buffer = new ArrayBuffer(16);
var int32View = new Int32Array(buffer);
for (var i = 0; i < int32View.length; i++) {
  int32View[i] = i * 2;
}

利用ImageBitmap提高图像处理性能

ImageBitmap对象提供了一种在图像处理中避免内存拷贝的方法,可以提高图像处理的性能。

var img = new Image();
img.src = 'image.jpg';
img.onload = function() {
  createImageBitmap(img).then(function(imageBitmap) {
    // 在这里使用 imageBitmap
  });
};

标签:

JavaScript

 

相关实践学习
Serverless极速搭建Hexo博客
本场景介绍如何使用阿里云函数计算服务命令行工具快速搭建一个Hexo博客。
目录
相关文章
|
6月前
|
消息中间件 缓存 NoSQL
如何做性能优化?
如何做性能优化?
|
16天前
|
缓存 负载均衡 算法
性能优化:提升系统效率的关键
性能优化:提升系统效率的关键
32 1
|
4月前
|
SQL 缓存 Java
系统性能优化总结
系统性能优化总结
73 10
|
5月前
|
存储 JSON 数据格式
如何提升写入效率?Schemaless 写入性能优化实践分享
TDengine 是一款时序数据库,其Schemaless模式适应物联网数据动态变化。通过分析火焰图,发现parser和insert操作是性能瓶颈。优化措施包括减少标签解析、排序和子表生成的重复执行,提前判断schema变更,改进数据插入方法,减少内存分配和拷贝。通过这些优化,如在3.0版本中,line协议性能提升了2.5倍,telnet提升2倍,json提升近5倍。使用工具如火焰图和perf进行性能分析,以识别和解决瓶颈,实现性能提升。
36 0
|
6月前
|
缓存 监控 NoSQL
一次性能优化实践
【5月更文挑战第21天】为解决在线教育平台在高并发下数据库查询响应时间增加的问题,开发者采用Redis缓存策略。通过数据分层、LRU淘汰策略、异步更新及监控调优,成功提升性能,缓存命中率超90%,页面加载时间从3秒降至1秒,改善了用户体验。此实践强调了合理缓存策略、监控调优以及考虑数据访问模式在系统设计中的重要性。
75 2
|
6月前
|
缓存 小程序 前端开发
小程序 如何做性能优化?
小程序 如何做性能优化?
|
监控 网络协议 安全
聊聊服务器性能优化~(建议收藏)
聊聊服务器性能优化~(建议收藏)
414 0
|
前端开发
一次性能优化思考过程
最近业务上空闲了下来,也是把之前在开发时自身感受比较大的白屏时间放在了主线上去排查优化,这里记录一下笔者对于移动端vConsole脚本的引入问题全过程。
167 0
一次性能优化思考过程
|
存储 缓存 JavaScript
我工作中用到的性能优化全面指南(1)
在Web开发中,Web的性能优化是一个重要的话题。无论是页面加载速度,用户体验,或者是程序运行效率,都与Web的性能优化息息相关。 最小化和压缩代码 在构建过程中,为了减少文件的大小和加载时间,通常会对JavaScript代码进行最小化和压缩处理。这包括移除不必要的空格、换行、注释,以及缩短变量和函数名。工具如UglifyJS和Terser等可以帮助我们完成这个任务。
65 0
|
消息中间件 监控 固态存储
榨干服务器:一次惨无人道的性能优化
做过2B类系统的同学都知道,2B系统最恶心的操作就是什么都喜欢批量,这不,我最近就遇到了一个恶心的需求——50个用户同时每人导入1万条单据,每个单据七八十个字段,请给我优化。
下一篇
无影云桌面