当前位置: 首页 > news >正文

如何查询网站关键词密度新浪网页游戏

如何查询网站关键词密度,新浪网页游戏,电脑手机网站建设,网站如何做链接Service Work离线体验与性能优化 引言 先放个意外事件#xff0c;万事开头难#x1f923;#x1f923;#x1f923; 原计划是分享离线应用与数据资源缓存的应用实践#xff0c;结果发现这一技术已被web标准废弃 曾经做过一个PC应用#xff0c;业务需求要求应用具备容灾…Service Work离线体验与性能优化 引言 先放个意外事件万事开头难 原计划是分享离线应用与数据资源缓存的应用实践结果发现这一技术已被web标准废弃 曾经做过一个PC应用业务需求要求应用具备容灾机制能够在无网络情况下离线使用并在网络恢复后同步数据。这需要利用缓存技术来实现。 传统前端缓存技术 HTTP缓存 工作原理HTTP缓存通过请求头中的过期时间和标识符来判断是否使用缓存。局限性依赖于服务器配置不适用于复杂的离线场景。 浏览器缓存 主要形式localStorage、sessionStorage、cookie。用途存储少量的数据但不适合大规模数据缓存。 应用缓存–Application Cache 全称Offline Web Application。特点通过manifest文件标注要缓存的静态文件清单。问题更新机制复杂页面更新延迟已被Web标准废弃 它的缓存内容被存在浏览器的Application Cache中。主要是通过manifest文件来标注要被缓存的静态文件清单。但是在缓存静态文件的同时也会默认缓存html文件。这导致页面的更新只能通过manifest文件中的版本号来决定。而且即使我们更新了version用户的第一次访问还是会访问到老的页面只有下一次再访问才能访问到新的页面。所以应用缓存只适合那种常年不变化的静态网站。 数据库缓存 选项WebSQL已废弃、IndexedDB。IndexedDB浏览器提供的本地数据库支持大量数据存储和索引适合复杂的数据缓存需求。 IndexedDB 就是浏览器提供的本地数据库它可以被网页脚本创建和操作。IndexedDB 允许储存大量数据提供查找接口还能建立索引。这些都是 LocalStorage 所不具备的。就数据库类型而言IndexedDB 不属于关系型数据库不支持 SQL 查询语句更接近 NoSQL 数据库。 因此通过ManifestindexDB可做到应用可离线使用数据缓存且不丢失。 Manifest配置需要缓存的静态资源打包过后的dist文件内容indexDB对业务数据进行存储 既然manifest这一方案已被废弃。于是转战Service Worker这一更优方案。 Service Worker概述 什么是 Service Worker 定义一种可编程的网络代理允许你拦截和处理应用发出的所有网络请求包括拦截和处理网络请求、管理缓存和处理推送通知等。功能离线支持、推送通知、缓存管理等。 Service Worker的应用场景 离线支持通过缓存静态资源和动态内容确保应用在没有网络连接时仍然可以使用缓存管理提高应用性能通过缓存减少网络请求次数和加快页面加载速度。推送通知Service Worker 可以处理推送通知即使用户没有打开应用也能接收消息。 三、Service Worker的特点 独立于主线程 Service Worker 运行在独立的线程中不会阻塞主页面的执行是后台运行的脚本。生命周期管理Service Worker 有安装、激活和更新等生命周期事件被install后就永远存在除非被手动卸载。跨域与安全限制同源策略必须是https的协议才能使用。不能直接操纵dom因为Service Worker是个独立于网页运行的脚本。可拦截请求和返回缓存文件。Service Worker可以通过fetch这个api来拦截网络和处理网络请求再配合cacheStorage来实现web页面的缓存管理以及与前端postMessage通信。 Service Worker的生命周期 当一个Service Worker被注册成功后它将开始它的生命周期我们对Service Worker的操作一般都是在其生命周期里面进行的。Service Worker的生命周期分为这么几个状态 安装中, 安装后, 激活中, 激活后, 废弃。 安装( Installing ) 这个状态发生在 Service Worker 注册之后表示开始安装这个状态会触发 install 事件一般会在install事件的回调里面进行静态资源的离线缓存 如果这些静态资源缓存失败了那 Service Worker 安装就会失败生命周期终止。安装后( Installed ) 当成功捕获缓存到的资源时Service Worker 会变为这个状态当此时没有其他的Service Worker 线程在工作时会立即进入激活状态如果此时有正在工作的Service Worker 工作线程则会等待其他的 Service Worker 线程被关闭后才会被激活。可以使用 self.skipWaiting() 方法强制正在等待的servicework工作线程进入激活状态。激活( Activating ) 在这个状态下会触发activate事件在activate 事件的回调中去清理旧版缓存。激活后( Activated ) 在这个状态下servicework会取得对整个页面的控制废弃状态 ( redundant ) 这个状态表示一个 Service Worker 的生命周期结束。新版本的 Service Worker 替换了旧版本的 Service Worker会出现这个状态 Service Worker的缓存机制 Service Worker 技术不可或缺的一个方面是 Cache 接口它是一种完全独立于 HTTP 缓存的缓存机制。可在 Service Worker 作用域和主线程作用域内访问 Cache 接口。 HTTP缓存会受到 HTTP 标头中指定的缓存指令的影响而 Cache 接口可通过 JavaScript 进行编程。这意味着网络请求的响应可以基于最适合指定网站的任何逻辑。例如 在第一次请求时将静态资源存储在缓存中并且仅为每个后续请求从缓存中提供这些资源将网页标记存储在缓存中但仅在离线场景中提供缓存中的标记。从缓存中为某些资产提供过时的响应但要在后台通过网络对其进行更新。从网络流式传输部分内容并将其与缓存中的 App Shell 组合起来以提升感知性能。 Service Worker的简单实践 浏览器兼容性检查 首先在开始使用 Service Worker 之前你需要确保用户的浏览器支持这项技术。Service Worker 对象存在于navigator对象下可以通过以下代码来检查 if (serviceWorker in navigator) {// 浏览器支持 Service Worker} else {console.log(Service Worker not supported); }注册Service Worker 注册是启动 Service Worker 的第一步。通常是在主应用中通过 JavaScript 来完成这个过程在主线程中调用navigator.serviceWorker.register()方法来注册 Service Worker register 方法接受两个参数 第一个参数表示ServiceWork.js相对于origin的路径 第二个参数是 Serivce Worker 的配置项可选填其中比较重要的是 scope 属性用来指定你想让 service worker 控制的内容的目录。 默认值为servicework.js所在的目录。这个属性所表示的路径不能在 service worker 文件的路径之上默认是 Serivce Worker 文件所在的目录。 成功注册或返回一个promise。 if (serviceWorker in navigator) {// 浏览器支持 Service Workerwindow.addEventListener(load, () {navigator.serviceWorker.register(/service-worker.js).then((registration) {console.log(Service Worker registered with scope:, registration.scope)}).catch((error) {console.error(Service Worker registration failed:, error)}) })} else {console.log(Service Worker not supported); }此代码在主线程上运行并执行以下操作 1、由于用户首次访问网站发生在没有注册的 Service Worker 的情况下 等到页面完全加载后再注册一个。 这样可以在 Service Worker 预缓存任何内容时避免带宽争用。 2、进行快速检查有助于避免在不支持此功能的浏览器出现错误。 3、当页面完全加载且支持 Service Worker 时注册 /service-worker.js。 Service Worker-安装Installing 安装事件发生在 Service Worker 首次安装时每个 Service Worker 仅调用一次 install并且在更新之前不会再次触发。 self.addEventListener(install, event {event.waitUntil(caches.open(缓存版本ID).then(cache {return cache.addAll([/,...]);})); });此代码会创建一个新的 Cache 实例并预缓存资产。 此处重点关注event.waitUntil事件 event.waitUntil 接受 promise 并等待该 promise 得到解决。 该 promise 执行两项异步操作 创建名为 ‘缓存版本ID’ 的新 Cache 实例。 创建缓存后 资源网址数组使用其异步缓存资源预缓存 addAll 方法。 如果传递给 event.waitUntil 的 promise 已拒绝。 如果发生这种情况Service Worker 会被丢弃。 Service Worker-激活 如果注册和安装成功 Service Worker 激活并且其状态变为 ‘activating’ 你可以在这里执行清理旧版本资源的操作 self.addEventListener(activate, event {const cacheWhitelist [缓存版本ID];event.waitUntil(caches.keys().then(cacheNames {return Promise.all(cacheNames.map(cacheName {if (cacheWhitelist.indexOf(cacheName) -1) {return caches.delete(cacheName);}}));})); });Service Worker-捕获 Fetch 通过监听Service Worker的 fetch 事件来拦截网络请求 调用 event 上的 respondWith() 方法来劫持当前servicework控制域下的 HTTP 请求该方法会直接返回一个Promise 结果 这个结果就会是http请求的响应。上面代码中就一个简单的逻辑先劫持http请求然后看看缓存中是否有这个请求的资源如果有则直接返回如果没有就去请求服务器上的资源。 event.respondWith 方法只能在 Service Worker 的 fetch 事件中使用。 self.addEventListener(fetch, event {event.respondWith(caches.match(event.request).then(response {if (response) {console.log(Serving from cache:, event.request.url);return response;}console.log(Fetching from network:, event.request.url);return fetch(event.request).then(networkResponse {if (networkResponse networkResponse.ok) {console.log(Caching new response:, event.request.url);return caches.open(f69905188ac970f1).then(cache {cache.put(event.request, networkResponse.clone());return networkResponse;});}throw new Error(Network response not ok);}).catch(error {console.error(Fetch failed:, error);throw error;});})); });开始Service Worker监听到fetch事件。缓存中是否存在请求资源检查缓存中是否有匹配的请求资源。从缓存返回资源如果缓存中有匹配资源直接返回该资源。发起网络请求如果缓存中没有匹配资源则发起网络请求。网络请求是否成功检查网络请求是否成功。响应状态是否为OK检查网络响应的状态码是否为200OK。缓存新响应如果网络请求成功且响应状态为OK则将响应缓存。抛出错误如果响应状态不是OK则抛出错误。捕获错误并抛出如果网络请求失败则捕获错误并抛出。结束流程结束。 Service Worker资源缓存-插件自动生成 通过上述资料可知资料缓存需要配置缓存ID和所需要的缓存文件路径而每次打包的文件名都是混淆之后的人工写是非常不实际所以我们可以通过插件帮我们自动生成Service Worker文件自动插入到dist目录下 配置插件进行自动化生产 在vite项目中根据Rollup接口提供的writeBundle()钩子函数拿到构建后的文件列表自动生成service-worker.js import path from path import * as fs from fs import * as crypto from crypto// 定义插件选项类型 interface ManifestPluginOptions {outputPath: stringversion?: stringserviceWorkerFileName?: string }export default function ServiceWorkerManifestPlugin(options: ManifestPluginOptions) {const { outputPath, version, serviceWorkerFileName } options// 生成随机版本号const generateRandomVersion (): string {return crypto.randomBytes(8).toString(hex)}const manifestVersion version || generateRandomVersion()// 使用默认的 service-worker.js 文件名如果没有传入自定义文件名const serviceWorkerPath /${serviceWorkerFileName || service-worker.js}// 递归遍历目录并获取所有文件路径const getAllFiles (dirPath: string, relativePath: string ): string[] {let files: string[] []const entries fs.readdirSync(dirPath, { withFileTypes: true })for (const entry of entries) {const fullPath path.join(dirPath, entry.name)const relativeFullPath path.join(relativePath, entry.name)if (entry.isDirectory()) {files files.concat(getAllFiles(fullPath, relativeFullPath))} else {files.push(/${relativeFullPath})}}return files}// 生成 service-worker.js 文件内容const generateServiceWorkerContent (cachedFiles: string[], manifestVersion: string): string {return self.addEventListener(install, event {event.waitUntil(caches.open(${manifestVersion}).then(cache {return cache.addAll([${cachedFiles.map((file) ${file}).join(,\n)}]);})); });//Service Worker监听到fetch事件。 self.addEventListener(fetch, event {event.respondWith(// 缓存中是否存在请求资源检查缓存中是否有匹配的请求资源。caches.match(event.request).then(response {// 从缓存返回资源如果缓存中有匹配资源直接返回该资源。if (response) {console.log(Serving from cache:, event.request.url);return response;}console.log(Fetching from network:, event.request.url);// 发起网络请求如果缓存中没有匹配资源则发起网络请求。return fetch(event.request).then(networkResponse {// 缓存新资源如果网络请求成功则将新资源缓存。if (networkResponse networkResponse.ok) {console.log(Caching new response:, event.request.url);// 缓存新响应如果网络请求成功且响应状态为OK则将响应缓存。return caches.open(${manifestVersion}).then(cache {cache.put(event.request, networkResponse.clone());return networkResponse;});}// 如果响应状态不是OK则抛出错误。throw new Error(Network response not ok);}).catch(error {console.error(Fetch failed:, error);throw error;});})); });self.addEventListener(activate, event {const cacheWhitelist [${manifestVersion}];event.waitUntil(caches.keys().then(cacheNames {return Promise.all(cacheNames.map(cacheName {if (cacheWhitelist.indexOf(cacheName) -1) {return caches.delete(cacheName);}}));})); }); }// 修改 index.html 文件const modifyIndexHtml (indexPath: string, serviceWorkerPath: string): void {try {let indexContent fs.readFileSync(indexPath, utf-8)// 确保 html 标签存在if (indexContent.includes(html)) {// 添加 Service Worker 注册脚本const serviceWorkerRegistrationScript scriptif (serviceWorker in navigator) {// 浏览器支持 Service Workerwindow.addEventListener(load, () {navigator.serviceWorker.register(${serviceWorkerPath}).then(registration {console.log(Service Worker registered with scope:, registration.scope);}).catch(error {console.error(Service Worker registration failed:, error);});});} else {console.log(Service Worker not supported);} /script // 将脚本插入到 /head 标签之前indexContent indexContent.replace(/head, ${serviceWorkerRegistrationScript}/head)fs.writeFileSync(indexPath, indexContent)console.log(index.html modified successfully.)} else {console.warn(index.html does not contain a html tag.)}} catch (error) {console.error(Failed to modify index.html:, error)}}return {name: manifest-plugin, // 必须的将会在 warning 和 error 中显示writeBundle() {try {const cachedFiles getAllFiles(outputPath)// 确保 service-worker.js 也被缓存if (!cachedFiles.includes(serviceWorkerPath)) {cachedFiles.push(serviceWorkerPath)}// 生成 service-worker.js 文件内容const serviceWorkerContent generateServiceWorkerContent(cachedFiles, manifestVersion)// 写入 service-worker.js 文件const serviceWorkerFilePath path.join(outputPath, serviceWorkerPath.replace(/^\//, ))fs.writeFileSync(serviceWorkerFilePath, serviceWorkerContent)console.log(service-worker.js generated successfully.)// 修改 index.html 文件const indexPath path.join(outputPath, index.html)if (fs.existsSync(indexPath)) {modifyIndexHtml(indexPath, serviceWorkerPath)} else {console.warn(index.html not found in the output directory.)}} catch (error) {console.error(Failed to write bundle:, error)}},} }Service Worker调试与监控 使用Chrome DevTools 查看缓存在“Application”面板中查看当前注册的Service Workers及其缓存内容。模拟离线通过DevTools的“Network”面板模拟不同的网络状况测试应用的离线表现。日志记录利用console.log()配合DevTools的日志功能追踪Service Worker内部发生的事件及执行过程。 通过Chrome DevTools可看到我们的文件被正确的缓存且通过Application工具管理我们的Service Workers
http://www.hkea.cn/news/14273191/

相关文章:

  • 网站域名空间管理php网站开发 实战教程
  • 昌乐网站制作价格奇墙网站建设
  • 免费的网站登录模板什么是网络营销定价中除免费策略外
  • 大型网站 网站建设企业网站成功案例
  • 问答系统网站模板福田最新通告: 请到访过以下场所
  • 关键词搜索引擎工具爱站酒店做爰视频网站
  • 微信网站价格网页设计代码如何写实训报告过程
  • 会HTML怎么做网站网站短期培训学校
  • 中心网站建设管理工作无投入网站推广
  • dnf可以去哪个网站做代练网站推广经验
  • 网站付费推广有哪些利用渗透的网站做寄生虫
  • 好的企业网站建设企业集团网站建设方案论文
  • 电子商城网站建设流程企业网站优化服务主要围绕哪些要素?为什么?
  • 昆明网站seo报价马鞍山建设网站
  • 怎么做网站快捷方式龙岗营销网站建设公司哪家好
  • 网站首页被k怎么恢复网站推送
  • 企业网站系统功能设计说明济南网站seo 优帮云
  • wordpress博客小程序优化是什么工作
  • 产品类网站开发网站有什么用
  • 网站实名认证需要什么怎么做网站免费优化
  • 网站百度分享怎么做贵金属企业网站源码
  • 北京网站开发学习网络会议系统有哪些
  • 网站移动端生成器wordpress建站教程 cms
  • 广州那里有学做拼多多网站的品牌网站建设小蝌蚪2a
  • 金华竞价排名 金华企业网站建设线下营销活动有哪些
  • 网站建设添加视频教程网络营销推广公司策划方案
  • 音乐网站还可以做怎么查权重查询
  • wordpress+短视频主题seo赚钱项目
  • 湖州本地做网站网站控制面板地址
  • 上海模板网站建站北京视频网站建设