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

rel=noopener可以提升性能

rel=noopener可以提升性能

原文链接: jakearchibald.com

如果你的链接指向其他站点,那么应该使用rel="noopener",尤其是点击后会在新标签页/窗口中打开的链接。

<a href="http://example.com" target="_blank" rel="noopener">
   Example site
</a>

如果没有这个属性,新页面就可以通过window.opener来访问你的window对象。幸好Web的源安全模型会阻止它读取你的页面,不幸的是利用某些陈旧的API可以把你的页面导航到不同的URL:window.opener.location = newURL

Web大侠Mathias Bynens曾详细写过这个问题,但我发现其实它还能提升性能。

(原文这里是一个Demo,有一个“Generate random numbers”按钮,点击可生成随机数。——译者注)

这里的随机数类似当前页面的生命体征。如果并不是每一帧都能生成随机数,说明有东西阻塞了线程。

单击下面的一个链接,打开一个需要大量JavaScript计算的页面(以下并非链接,请参见原文——译者注):

  • <a target="_blank">
  • <a target="_blank" rel="noopener">

没有rel="noopener",随机数会被新打开页面中的JavaScript阻断。不仅如此,所有主线程活动也会被阻塞,试试选择页面中的文本。但加了rel="noopener"之后,随机数生成一直保持在60fps。当然,是在Chrome或Opera中。

更新:Edge对点击任何链接都会中招儿。下面我们会详细说。

那为什么会这样?

Windows & processes

大多数浏览器都是多进程的,除了Firefox(他们正在改)。每个进程包含多个线程,包括我们常说的“主”线程。解析、样式计算、布局、绘制和非worker的JavaScript都在主线程里执行。就是说,一个域中的JavaScript与另一个标签页或窗口中的域中的JavaScript在不同的线程里。

然而,由于我们可以通过window.opener同步跨窗口地访问DOM,因此通过target="_blank"启动的窗口还在同一个进程(线程)中。通过window.open打开的iframe和窗口也一样。

rel="noopener"会阻止window.opener,因此不存在跨窗口访问。Chromium浏览器为此做过优化,会在独立的进程中打开新页面。

站点隔离

在Chrome总部,我们见证了把跨源iframe和新窗口迁移到新进程,无论是否有rel="noopener"。这意味着受限的跨窗口访问会变成异步的,这样一来的好处就是提升了安全性和性能。

与此同时,rel="noopener" 能在今天为你提供性能和安全的双重好处!

更新:Edge已经针对新窗口的情况进行了优化,iframe还没有。参见Fremy的留言。

有意思的现象:注意,我上面一直在说“域”(domain)而不是“源”(origin)。这是因为可怕的document.domain允许两个域同步地变成同一个源的部分。我去!

相关文章:

  • node.js开发:nodemon
  • 网站备份策略
  • web前端: Vue cli3 库模式搭建组件库并发布到 npm
  • 整理一个坛子里的笑话...稍微改编一下,就叫做《MM和一个程序员相亲的故事》!...
  • JQuery Delegate IOS上失效解决方案
  • deplate(Viki) 全面定制
  • webpack-dev-server默认打开指定chrome浏览器的方式
  • 发现CSDN给我开了一个专栏!
  • vue 组件预览图片
  • 中国教育中的0分作文
  • React Fiber是什么
  • 类似v-console
  • Substance 打造个性 NetBeans
  • eslint关闭相应规则的方法
  • 如何修复:Windows上面的WScript的脚本(.vbs)不能执行了?
  • classpath对获取配置文件的影响
  • flutter的key在widget list的作用以及必要性
  • JavaScript工作原理(五):深入了解WebSockets,HTTP/2和SSE,以及如何选择
  • Java方法详解
  • React的组件模式
  • 笨办法学C 练习34:动态数组
  • 大整数乘法-表格法
  • 对JS继承的一点思考
  • 基于Javascript, Springboot的管理系统报表查询页面代码设计
  • 简单易用的leetcode开发测试工具(npm)
  • 名企6年Java程序员的工作总结,写给在迷茫中的你!
  • 如何使用 JavaScript 解析 URL
  • 入职第二天:使用koa搭建node server是种怎样的体验
  • 系统认识JavaScript正则表达式
  • 限制Java线程池运行线程以及等待线程数量的策略
  • 阿里云服务器购买完整流程
  • ​软考-高级-系统架构设计师教程(清华第2版)【第12章 信息系统架构设计理论与实践(P420~465)-思维导图】​
  • # include “ “ 和 # include < >两者的区别
  • #宝哥教你#查看jquery绑定的事件函数
  • %3cscript放入php,跟bWAPP学WEB安全(PHP代码)--XSS跨站脚本攻击
  • ( )的作用是将计算机中的信息传送给用户,计算机应用基础 吉大15春学期《计算机应用基础》在线作业二及答案...
  • (day 12)JavaScript学习笔记(数组3)
  • (LeetCode C++)盛最多水的容器
  • (二)七种元启发算法(DBO、LO、SWO、COA、LSO、KOA、GRO)求解无人机路径规划MATLAB
  • (一) springboot详细介绍
  • (转)Google的Objective-C编码规范
  • .NET / MSBuild 扩展编译时什么时候用 BeforeTargets / AfterTargets 什么时候用 DependsOnTargets?
  • .NET Core WebAPI中使用swagger版本控制,添加注释
  • .net core 实现redis分片_基于 Redis 的分布式任务调度框架 earth-frost
  • .net开源工作流引擎ccflow表单数据返回值Pop分组模式和表格模式对比
  • .Net转Java自学之路—SpringMVC框架篇六(异常处理)
  • .sdf和.msp文件读取
  • /bin/bash^M: bad interpreter: No such file or directory
  • @ 代码随想录算法训练营第8周(C语言)|Day57(动态规划)
  • @31省区市高考时间表来了,祝考试成功
  • [].slice.call()将类数组转化为真正的数组
  • [C#][opencvsharp]opencvsharp sift和surf特征点匹配
  • [C++基础]-入门知识
  • [exgcd] Jzoj P1158 荒岛野人
  • [Flutter]WindowsPlatform上运行遇到的问题总结