我工作中用到的性能优化全面指南(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

 

目录
相关文章
|
jenkins 持续交付 数据安全/隐私保护
Docker 打包镜像 | 发布至阿里云镜像仓库
Docker 打包镜像 | 发布至阿里云镜像仓库
2939 1
|
3月前
|
人工智能 自然语言处理 开发者
周报不是流水账,这个AI指令帮你写出让老板点赞的工作汇报
一个帮助技术人快速生成专业工作周报的AI指令,通过结构化输入和价值导向表达,让你的周报从流水账变成让老板点赞的高质量汇报,15分钟搞定原本需要1小时的周报撰写。
1157 80
|
3月前
|
数据采集 Web App开发 调度
我为什么彻底切到Playwright
本文分享从Puppeteer迁移到Playwright的实战经验,详解架构升级动因、模块重构与核心代码。Playwright凭借更强的隔离性、原生反检测支持、简洁代理配置及多浏览器兼容,彻底解决Puppeteer时代资源争抢、稳定性差等痛点,助力构建高可用、易维护的现代数据系统。
185 1
|
29天前
|
数据采集 人工智能 自然语言处理
Coze 智能体工作流:从零搭建企业级 AI Agent 的工程化实践
AI智能体运营工程师是连接大模型与真实业务的工程化桥梁,以Coze/LangChain等工具为核心,通过工作流编排、Python数据处理、RAG知识库与API集成,将模糊需求转化为可执行、可评估、可优化的智能体系统,实现从对话工具到业务交付系统的质变。(239字)
|
3月前
|
人工智能 自然语言处理 大数据
💡 反常识观点:好的项目计划书不是写出来的,是问出来的【提示词工程】
深度解析项目计划书从"写作思维"到"问答思维"的认知革命,通过完整的AI指令框架和实战案例,帮助开发者掌握深度问答方法,提升项目决策质量和成功概率。文章强调AI不是写作工具,而是思维升级的助推器。
198 11
|
数据采集 JavaScript 前端开发
网页抓取进阶:如何提取复杂网页信息
在信息爆炸时代,从复杂网页中高效抓取数据对开发者和分析师至关重要。本文探讨如何利用 `webpage` 对象结合代理IP技术,轻松抓取如大众点评这类动态加载且具备反爬机制的网站数据。通过 Python 的 `requests`、`BeautifulSoup` 和 `Selenium`,结合代理IP,详细讲解了如何应对动态内容加载、反爬机制等问题,并提供了具体代码实现。通过这种方法,可以批量抓取商家信息,为数据分析提供支持。
1376 1
网页抓取进阶:如何提取复杂网页信息
|
11月前
|
数据采集 存储 监控
网站价格监控:动态价格数据的实时抓取案例
本案例展示了如何利用爬虫技术实时抓取京东等电商平台的商品信息、价格及用户评价,通过代理IP、Cookie和User-Agent确保数据稳定采集。关键数据分析包括价格动态监控、评价趋势分析和竞争情报获取,助力商家制定策略。代码从简单请求逐步演进为具备异常处理、数据解析等功能的完整体系,并设计了「技术关系图谱」,直观展示系统模块间的关系,为开发者提供全局视角和技术路径参考。
1564 0
网站价格监控:动态价格数据的实时抓取案例
|
Web App开发 移动开发 前端开发
如何解决不同浏览器的样式兼容性问题?
如何解决不同浏览器的样式兼容性问题?
862 0
|
边缘计算 安全 物联网
5G与4G LTE的比较:主要改进与优势
5G与4G LTE的比较:主要改进与优势
3650 1
|
数据采集 存储 安全
利用爬虫技术自动化采集汽车之家的车型参数数据
汽车之家是一个专业的汽车网站,提供了丰富的汽车信息,包括车型参数、图片、视频、评测、报价等。如果我们想要获取这些信息,我们可以通过浏览器手动访问网站,或者利用爬虫技术自动化采集数据。本文将介绍如何使用Python编写一个简单的爬虫程序,实现对汽车之家的车型参数数据的自动化采集,并使用亿牛云爬虫代理服务来提高爬虫的稳定性和效率。
1114 0
利用爬虫技术自动化采集汽车之家的车型参数数据

热门文章

最新文章