要
H5页面给人的感觉通常是开发成本低、迭代速度快但使用体验不佳。其中最容易被用户感知的体验问题就是首屏速度,由于H5页面的所有资源都需要实时从网络上下载,提升这些资源的加载速度就可以明显提升首屏速度。我们通常将提前下发资源到App,并在打开H5页面时使用预载资源加速访问的技术称为“离线包”。
B站的离线包技术方案与大部分互联网公司实现的方案在底层逻辑上是一致的,都实现了基础的资源下发和拦截匹配机制。但在此基础上我们也有一些创新,例如页面快照技术、AB实验能力,同时也做了很多优化,包括用扫码调试降低调试成本、版本快速收敛、预约定时错峰发布等。目前我们的离线包技术已经接入183个项目,覆盖12个业务线,在公司内被广泛使用。
页面加载速度的瓶颈分析
当我们用工具分析一个典型H5活动页(2024纪录片开放周)时,可以发现一个页面的速度瓶颈主要在这些方面:
HTML请求
通常按照HTML是否动态生成,将其分为SSR(服务器端渲染)和CSR(客户端渲染)页面。
SSR受服务器负载、页面复杂度和网络拓扑影响,首字节时间相对较晚,但一旦收到HTML响应,浏览器引擎就会立刻开始解析和绘制,所以首屏时间相比CSR会更有优势。
CSR的优势在于可以很容易地使用部署在各地的CDN服务节点来加速,且可以配置一定时间的缓存,所以首字节时间更短,但所有页面结构都需要JS运行后才可以产出,首屏时间会晚很多。
通常CSR页面的响应时间大概在10ms-50ms,SSR页面通常50ms - 数百毫秒。SSR页面在等待服务器渲染上会耗费更多时间,根据之前一些案例的经验结果,SSR对中低端机型的首屏提升比离线包大,离线包在对高端机型的首屏提升比SSR大,其原因在于离线包下渲染页面属于单纯的CPU密集型任务,高端机型处理器较好,相对服务器端需要排队处理的SSR会有更快的响应。
主JS下载&编译
目前前端项目通常都会使用JS框架,叠加引入3-15个左右的第三方库,产出的JS Bundle一般会有数百KB-2M左右的大小,下载需要花费数百毫秒的时间。较大的JS文件也会让JS引擎的分析过程更加漫长,一般看CPU速度,需要十几毫秒到几十毫秒的时间。
在SSR项目中,主JS过大通常导致用户首次交互时间变晚,一些场景下,用户会发现页面一开始无法响应交互,在JS运行完成后才可以正常使用。
在CSR项目中,主JS过大会导致页面白屏时间较长,需要等待一段时间后才能出现页面内容。
请求页面主接口
单个接口通常消耗30ms-100ms的时间。但JS往往会等待接口返回后,才会开始生成实际的框架内虚拟DOM树,所以这个同步等待的时间越长,白屏时间也越长。SSR项目通常会在渲染服务器上调用这个接口,利用内网网络高带宽低延迟的特性,降低这块的耗时。CSR项目可以考虑提前加载时机(接口预取或请求前置)或缓存上一次的结果来尽量减少请求耗时。
应用虚拟DOM树生成
这一步通常都是Vue或者React这类框架在运行应用代码,生成虚拟DOM,进而将虚拟DOM挂载到实际的DOM树中。这个过程伴随大量的CPU密集计算,可能需要几十毫秒到百毫秒的时间才能完成。这一步由于视图结构受业务形态影响很大,通常难以优化,比较可行的方案是先加载首屏的、重要的组件,延后加载非首屏、不重要的组件。
加载首屏资源
当页面实际的DOM构建完成后,浏览器才会知道需要加载哪些资源,并开始下载。这个过程大概需要数百毫秒。这一步通常会使用CDN加速、文件名带哈希+强缓存、优化图片和其他资源体积等方式,优化加载速度。
综上,一般一个页面从开始加载到用户看到相对稳定的页面,通常需要1.2秒到2.5秒左右的时间。其中相当的一部分时间耗费在网络IO(下载资源和请求接口)上,剩余的主要就是JS编译运行的开销,以及浏览内核处理Layout和Render的时间。其中比较容易优化的主要是网络IO时间。而在JS代码运行和界面布局效率方面,在不同的业务场景下有较大的差异,需要根据业务场景量身定制。
离线包技术方案简介
离线包的技术基础就在于Webview为调用层提供的请求劫持能力,匹配资源路径后可直接返回本地文件内容。
Android系统可以直接使用shouldInterceptRequest API来实现,可以拦截https或者私有协议的请求。而IOS是基于WKURLSchemeHandler hook系统方法来实现https的拦截,但由于系统Bug在post请求中存在body丢失和上传图片可能导致进程崩溃的问题。对于这个问题,我们一方面要求H5页面使用JSAPI来发起POST请求,另一方面限制仅在命中离线包的情况下开启https拦截。在此限制下,因此这套方案基本可用。
解决了请求劫持问题,接下来就可以实现透明的资源加速能力了。我们需要先完成资源的准备:
代码资源的准备
资源准备的过程比较简单,与构建工具无关,只要收集页面所需的资源文件,并且配置好URL到本地路径的映射关系就可以了。
通常会有两种代码来源:
最后打包的目录,大概包含以下内容
一个典型的代码产出目录如图所示:
config.json示例:
离线包的下发机制
离线包的下发依赖Fawkes(客户端统一平台)的ModManager,使用与客户端统一的下发渠道,有利于统一调度,控制下载期间的CPU、带宽占用和存储空间占用。
ModManager是用于下发客户端资源的一个统一渠道,绝大部分需要动态下发的资源都会通过ModManager统一管理和分发,并具备了诸如增量包生成、资源错峰下发、热推送下发、版本和网络环境限制等诸多能力。复用这套基础能力省去了我们额外建立一套下发链路的成本,也能更容易地管控CDN流量以及客户端存储空间占用。
离线包平台有三种发布模式,分为常规发布、错峰发布和预约发布,这些发布模式的实现方案有一定的差异:
常规发布
代码包将直接发布到线上,所有符合限制条件(版本、时间、灰度等策略)的冷启动App的用户都将按照资源包优先级逐步下载到新版本。
如果用户本地没有这个包的旧版本,那么会下载全量包;如果已经存在较近的旧版本,则会下载增量包。但即使有增量更新能力,在用户使用的高峰时段,常规发布仍会带来较大的带宽压力,所以高峰期发布需要额外审批。
如图所示,在常规发布后,资源包的下载会快速制造一个流量高峰,而后随着覆盖率的提升,缓慢下降,直到大部分用户完成更新。因此,我们除了常规发布外,还需要更智能的发布策略来降低成本。
错峰发布
错峰发布模式下,会设置离线包延后1-3天生效,在此期间,会借用流量低谷下载离线资源包。从而有效利用CDN的闲时流量,节约成本。
错峰发布适合第一次发布的包,可以利用闲时流量缓解第一次全量下载对用户的流量压力。后续版本再发布时则可根据上线时间要求灵活使用发布模式。
预约发布
在离线包的实践中有这样一个问题:直播业务的大部分页面都接入了离线包,但某些页面常常需要在晚上高峰期上线发布,但在高峰期上线离线包又会带来很高昂的带宽费用。如何既保证可以及时发布,又可以兼顾离线包呢?我们设计了预约发布功能。
预约发布允许设置后续24小时内的某个低峰时间点发布。设置后,当前线上使用的包版本可以设置即刻失效,用户降级请求线上页面访问新版本内容。而新版本会在指定时间点发布,在此后更新完成的用户,就可以正常使用加速能力。
预约发布适合需要在高峰时段上线新功能,且对短时间内性能下降不敏感的业务。即可以取得足够快的发布速度,又可以避免较高的带宽费用。缺点是会影响这个时间段内用户访问页面的速度,也可能对线上服务造成突发压力。
资源匹配机制
如图所示,当Webview加载一个URL时,会经历以下环节:
版本控制和快速回滚策略
离线包由于是预先给客户端下发资源,所以不可避免地会遇到更新时效的问题。在更新时效上,我们之前在使用ModManager时会遇到这些问题:
考虑到前端离线包的主要目的是加速,不同于客户端包下载到资源才可以使用对应功能的限制,我们可以灵活利用线上兜底策略,来解决这几个问题。
于是在ModManager机制的基础上,我们又额外引入了一个接口(x/offline/version接口),用来告知客户端当前可以使用的版本白名单。客户端会在每次冷启动和切后台返回时刷新接口数据(有较短时间的限频和缓存逻辑),从而可以实现以下能力:
版本接口的大概形式是这样的:
这个接口采取版本白名单机制,在接口参数中确定了App环境信息后,会查询出这个环境这个App下可用的包版本列表。在发布新版本时,白名单里会同时出现2个版本,从而允许旧版本离线包仍然使用一段时间,在指定时间后,会只下发最新版本号,旧版用户在更新完成前会请求线上资源。
版本接口为了提供较高的时效性,每次切后台返回或者冷启动都会请求刷新,会有较高的QPS,我们在接口上做了充足的缓存策略,所有数据均是异步定时更新并完成计算,在请求到达时始终从内存缓存中返回数据,服务资源占用率比较可控
上图表示了一个设置了1小时旧版本过期的项目在占有率变化上的趋势。版本控制功能主要解决旧版本过期问题,可以使得旧版本在过期后立刻失效,而新版本不受影响。
调试流程优化
离线包由于需要等待客户端将包下载完成才可以体验,因此在开发调试阶段会带来很大的痛苦。为此,我们仿照小程序的开发流程,设计了扫码调试功能,在开发、预览等场景上,均可以使用扫码调试功能快速预览页面在离线包下的效果。
扫码后,在预览调试页面,会调用JSAPI要求客户端下载指定的zip资源包,放置到特定的调试目录。后续在App存续期间再次打开对应的H5页面时,会优先使用调试目录内的资源,而其他机制保持一致,因此在大部分场景下可以完美还原线上离线包的使用体验。
另外在打开的调试页面上,还会注入离线包调试工具,帮助业务发现有哪些未命中离线的资源以及查看Performance Timing API数据,帮助优化离线包的文件组合,提升加速效果。
HTML快照
在很多需要优化首屏速度的场景,使用SSR都是一个可行的方式,在服务器端提前渲染好整个页面的HTML结构,这样浏览器拉取到HTML后就可以立刻开始渲染,用户就能更快地看到内容。
SSR能够加速的核心条件是提前渲染完的HTML,如果我们可以缓存上一次的页面渲染结果,是否也可以用于加速下一次用户进入时的首屏速度呢?显然是可以的,只不过需要先解决一些问题,例如
基于上述问题,离线包HTML快照能力做了一些针对性的方案。不过我们可以先看一下这个功能的运行流程:
如图所示,当用户请求一个URL时,会先判断是否命中离线包,如果命中,则检查是否存在HTML快照,如果存在快照,那么使用快照HTML,否则使用离线包内附带的HTML。当页面完成加载后,会在页面上调用一个JSB,用来存储当前页面的快照。
关于快照,还设置了以下限制:
除此之外,对于设置的HTML内容,还需要注意以下问题:
这样基本可以解决上述提到的问题。HTML快照的技术基础是在基于一个假设,即页面DOM结构会与数据一一对应,所以相同的数据输入,无论多少次渲染都应该输出相同的DOM结构。那么只要提前缓存DOM结构,就可以在下次访问时先展示旧页面,再无缝切换到新页面。
这个假设虽然大部分情况下虽然成立,但却仍旧缺乏业务实践,具体在实践中会遇到哪些问题,需要在生产应用后才能有相对靠谱的最佳实践。这方面的实践会在今年展开,欢迎持续关注与合作。
AB实验
由于离线包会拦截入口HTML文件请求,在页面做了大改版需要页面级AB实验的场合,就无法在服务端来进行分流决策。为此,我们使用网址Rewrite能力使得同样一个URL在不同用户侧对应两份不同的离线包。
其大概流程如下:
上述方案可以实现页面的AB能力,但由于AB分流决策与页面打开的时机不同,所以无法上报进组数据,只能上报用户实际进入页面的数据,所以会影响部分数据的回收。
新旧版本的配置差异如上图所示。使用两个不同的URL,就可以分别对应两个不同的离线包,从而在不影响离线包本体设计的基础上实现AB能力。
适用场景与局限
离线包提供的几个核心能力,可以有效提升页面的首屏速度,但仍然因为技术实现和架构的原因,存在一些限制:
存在失效场景,需保留线上访问能力
在某些场景下,离线能力会暂时失效,从而会请求线上页面。接入离线包的业务需要自行确保线上URL可访问且功能正常,只能把离线包作为加速手段,而非最终部署目标。
失效的场景包括:App版本过低、尚未更新到可用版本的用户(新下载App用户或长期低活跃用户)、紧急下线或预约发布期间由业务触发的暂时禁用
增加上线复杂度
接入离线包后,需要在上线前完成离线包功能验证,且需要在线上页面上线完成后,再操作离线包发版。会增加一定的上线复杂度。
虽然离线包的资源预载和接口预载能力已经比较成熟,通常不会引入额外的问题,但仍然需要注意自测。
上线链路复杂的问题,通过在公司前端统一发布平台集成离线包发布流程来解决。
带来额外带宽成本
每一个上线发布的离线包,都会下发到绝大部分用户的手机中,而很多用户可能根本不是这个业务的目标用户。同时下发的过程也会带来额外的带宽成本,尤其是在高峰期上线时。
目前我们确实还没有精细化提升带宽使用率的能力,未来可能会看情况,采用人群包或其他方式,优化下发资源的精准度。
Webview本身的限制
目前由于IOS系统在使用https拦截能力时的一些Bug,需要格外注意这两个问题:
综上,哪些业务适合接入离线包呢?离线包通常适合以下类型的业务:
离线化的终点在哪里?
当我们将越来越多资源提前缓存在用户手机里,免去网络IO这一最大的速度瓶颈,就会发现其实它跟客户端界面业务差距并不会很大。这个存在形态位于Native和H5之间,它牺牲了一些发版的便利性,但获得了更快的加载速度。虽然我们无法修改承载H5的Webview本身,也必须要承受Webview带来的性能问题,但我们也很好奇如果将一个页面优化到极致,是否真的可以让用户无法通过加载速度区分哪些页面是Native实现,哪些页面是H5实现呢?
后续我们将在一些页面上实验这样的速度优化策略:
当这个实验做完后,会再写一篇文章,总结这样综合实践方案下的经验,为其他业务的优化提供参考。我们的目标是树立起H5性能的新标杆,让更多的业务可以使用H5来承载,释放业务迭代的潜力!
性能表现
全局性能表现:
Android:
IOS:
整体看,离线包对Android系统的页面加载提升服务比较明显,对IOS系统的提升相对幅度小一些,但也有可感知的速度提升。
从单独业务角度观察,从番剧片单页来看,离线包的速度提升效果如下:
由于PV数较小的性能数据不可置信,因此看可置信数据而言,在onload事件的平均时间上,非离线包状态的加载时间约为2700ms左右,简单接入离线包后,加载时间约为2300ms,提升400ms。
在经过对资源的详细分析,将所有线上加载的js文件都打入离线包后,加载时间下降到2016ms,可以再提升300ms。总体而言,离线包可以为简单H5页面能提供700ms的加载性能提升(onLoad)。且在用户观感上,页面基本可以在切换动画完成前展现。
配合页面的FCP数据,可以看到在优化后,页面的首屏渲染时间可以从1550下降到1230,能提升300ms,且基本接近“秒开”。
在其他更复杂的页面上(更多图片、更多JS),离线包可以取得更好的性能提升效果。
业界方案对比
B站方案与业界方案的差异点
综合来看,B站的离线包方案有以下亮点:
错峰发布:通过错峰发布,充分利用CDN闲时流量,可以用较低的成本下发资源
版本控制策略:通过版本控制策略,避免旧版本滞留,符合前端业务一次发布所有用户更新的常规心智,对于需要紧急更新或下线的场景比较重要
调试流程优化:扫码调试可以明显提高接入效率,保证线上稳定性是性能优化的第一前提。
HTML快照:利用上一次渲染结果优化下次进入的首屏速度,虽然有较多的调试成本,但也有一试的价值。这个方案在某些社区文章里有被简单提到过。
AB实验能力:保证页面重大改版期间性能不下降,且能回收AB实验数据,兼顾用户体验和业务诉求
同时,有些业界常见的方案我们选择不去实现,例如:
Webview预载
提前初始化一个Webview挂在后台,等需要的时候直接使用。这个方案在前期因为公司内各业务容器不统一而无法落地,现在统一后发现预载收益有限,B站App内的容器二次加载耗时基本在130ms以下,为了这点时间而长期占用较多的内存,在一个视频观看体验优先的App上并不明智。而如果为提升首次初始化耗时而在App启动时预载Webview,又会影响用户的启动速度,因此作罢。
接口预请求
同样也是收益不够高的问题。这里我们谈的是在Webview初始化时提前发起接口请求的方案。在一个充分优化的离线包上,理论上在html和js加载后,会很快开始接口请求,所以有概率在请求还没返回时,前端就开始从客户端取数据,处理这个中间状态有一定的成本,也会带来额外的调试心智负担。理论的性能优化表现应该在50-150ms左右,相对来说动力不足。
对于像Feed流预加载后续文章接口的实现方案,由于通用性不足,不作为全公司级离线包需要考虑的方案,可以在各业务层自行实现。
有一些技术是我们已经实现了,但其他人也都有类似实现的:
公共包技术:集合公共JS资源,避免多份打包,同时利用平台能力,自动完成公共资源更新
增量包下发:对每个版本的包,都会生成这个包和前N个版本差分计算的增量包,根据客户端当前版本下载增量包,降低CDN压力
热更新推送:可以对某些高优先级业务,开启热更新推送,助力快速更新
仅Wifi下载和版本限制:对下发条件做一定的限制,节约用户流量
Webview常驻方案
简介:对于Feed流或者频繁打开同类页面的场景,可以保持Webview常驻后台,点击链接时将Webview拉到前台,并替换页面的URL参数,页面拉取接口数据并展现。
差异点:
Webview常驻方案 | B站离线包方案 | |
性能 | 非常快。由于省去了容器初始化和页面JS初始化的诸多流程,这个方案的性能优于离线包,配合feed流数据接口预取,可以让用户几乎无法感知到加载过程。 | 性能比较常规,在不使用HTML快照这样的特殊方案时,性能与业界方案是类似的。 |
方案通用性 | 较差。适用场景相对局限,比较适合频繁往返于列表页到详情页的这类场景,例如新闻阅读类应用、商城类应用等。 | 通用性好,同样的方案可以在B站绝大部分H5业务上使用。漫画App、云视听小电视、直播姬等App的也已低成本接入 |
代码侵入性 | 强。需要代码做针对性适配,以及客户端配合才能完成一个特定场景下的落地 | 侵入性低,除了需要注意Post请求问题和History API在IOS上无法记录历史记录外,其他代码与线上业务完全相同 |
总体看,B站的离线包方案为了方案通用性,牺牲了一些性能表现,好处是可以比较简单地应用在各业务场景上,带来相对普遍的价值。
货拉拉的离线方案
简介:货拉拉方案与本文提到的方案在某些方面是有共通之处的,在基础加速层面上除了底层的技术实现思路采用了加载本地路径的方案,其他包括资源下发、多层降级机制等方面基本类似。
差异点:
由于技术实现原理类似,因此在性能和通用性上,两者差异较小。我们从另外的方面比较:
货拉拉方案 | B站离线包方案 | |
容器实现位置 | 基于通用容器上的一个独立增强容器,各业务容器基于此拓展 | 直接放入基础容器内,开箱即用 |
兼容性 | 存在跨域问题 | 基于https拦截,与线上几乎一致 |
代码侵入性 | 有少量侵入性,需要对本地加载的路径做一些适配 | 侵入性低,除了需要注意Post请求问题和History API在IOS上无法记录历史记录外,其他代码与线上业务完全相同 |
另外我们观察到货拉拉方案里离线包的URL映射是动态下发的,B站的离线包URL映射则是打包到包里的,另外通过一个动态接口控制当前可用的版本。
这两个方案都是可行的,总体来看,有这些差异:
动态下发URL映射 | 打包URL映射 | |
优势 | 方便灵活,可以很简单地修改映射关系 | 有利于这个包的逻辑独立性,这也是扫码调试功能好实现的一个因素 |
缺点 | 可追溯性差,配置不断在变化,配置和包资源无法一一匹配时,可能导致过去历史版本可能因为配置变更而不能再看 | 灵活度差,修改URL映射需要发一个新的包 |
支付宝的Nebula方案离线包能力
支付宝的离线包的定位并非是加速线上业务的能力,而是更接近离线H5应用的模式。在离线包未下载的时候,他会请求提前部署的降级资源,也就是使用的业务并不需要自行部署一套页面在线上,需要有一个域名和url,而是只需要使用它提供的方案就可以完成部署。
其运行机制,类似货拉拉方案,是用file协议加载,向H5页面提供一个虚拟域名供识别。
在API能力上,配备了一套JSAPI来满足业务的使用,所以看起来比较接近小程序的实现思路。
总体来讲,支付宝因为业务都是以一个个独立的H5App来承载的,H5 App之间彼此关联和交互较少,所以方案会接近小程序,而后续支付宝也确实往前走了一步,实现了小程序的能力。
B站由于页面基本都是自有的,且Native跳H5、H5跳Native的场景很多,需要为用户提供一个整体性的体验,所以方案更偏向“加速”,而非独立H5 App
UC的NSR方案
UC浏览器在新闻feed流页面加载中采用了NSR(Native Side Rendering),首先在列表页中加载离线页面模板,通过Ajax预加载页面数据,通过Native渲染生成Html数据并且缓存在客户端。
NSR本质是分布式SSR,将服务器的渲染工作放在了一个个独立的移动设备中,实现了页面的预加载,同时又不会增加额外的服务器压力。
下面看方案对比:
NSR方案 | B站离线包方案 | |
性能 | 更快,通过客户端渲染,可以不依赖Webview生命周期就可以提前渲染出所需的HTML | 一般,仍然需要等待容器初始化+html加载+JS编译执行+接口请求+框架渲染 |
方案通用性 | 相对一般,有一定的定制性 | 比较通用,整体都是在Web标准上做的一些优化 |
代码侵入性 | 较强侵入性。一个是代码编写接近常规带SSR的页面,另一方面NSR渲染结果和Webview内展现的过程是有一定逻辑的。 | 较低侵入性。使用常规方案几乎不需要改代码。 如需更快的性能,代码快照会类似这套方案,只不过复用的是上一次渲染的结果。当然使用代码快照也意味着带来更强的侵入性。 |
兼容性 | 需要额外考虑在客户端JS环境运行的兼容性 | 较好,与线上页面类似 |
腾讯的VasSonic方案
VasSonic除了常规的资源预载之外,还做了以下事情:
VasSonic 的方案整体思路和效果非常不错,特别是对于大部分 web 场景,通常我们的模板较少发生变化,大部分是数据部分变化,能够很好的通过局部刷新做到秒开效果。对于首次加载而言,通过并发请求和 webview 创建带来了不错的性能提升,还能无缝的支持离线包策略。
但是 VasSonic 定义了一套特殊的注释标记及拓展了头部,需要包括后台在内的前后端进行改造,对 web 侵入性非常强,接入的工作量及维护成本会非常大。
方案总结
总的来讲,离线包加速方案的各个技术决策其实就是在平衡通用性和性能。
通用性越好,能做的事情越少,方案约需要遵循Web标准,当然性能的提升幅度也会小一些。
抛开通用性,如果针对业务特定定制更多的优化方案,那么优化效果一定是可以做的更好的,当然也就更专用,难以大规模铺开。
B站的离线包在决策时更多考虑了通用性,因此得以在各业务线都能比较低成本地接入,有比较广泛的使用群体。在此基础上,例如电商业务也针对他们的业务特点做了更专用化的定制,例如Webview常驻方案,得到了更好的效果。所以可以认为离线包作为一个通用方案,提升了性能的下限,它并不与专用方案冲突,可以再额外使用专用方案来提升性能的上限。
参考文章
B站离线包在研发阶段基本遵循净室研发规则,除参考了业界方案的一些思路外,具体的方案设计和实现均为自研。
在本篇文章的方案对比方面,主要参考了以下文章:
【移动端h5秒开方案总结】https://blog.towavephone.com/mobile-h5-startup-way/
【货拉拉H5离线包原理与实践】https://juejin.cn/post/7103348563479887885
【CSR、SSR、NSR、ESR傻傻分不清楚,一文帮你理清前端渲染方案!】https://juejin.cn/post/6844904178519834638
【离线化集成方案-安全设计与优化】https://research.szltech.com/?p=1935
【WebView性能、体验分析与优化】https://tech.meituan.com/2017/06/09/webviewperf.html
【蚂蚁金服金融科技产品手册】https://docs-aliyun.cn-hangzhou.oss.aliyun-inc.com/assets/attach/87479/AntCloud_zh/1578025862524/10%20H5%20%E5%AE%B9%E5%99%A8%E5%92%8C%E7%A6%BB%E7%BA%BF%E5%8C%85%2020200101.pdf
作者:大前端
来源-微信公众号:哔哩哔哩技术
出处:https://mp.weixin.qq.com/s/WMf28adh30v67uuEn99F6Q
众号【传智播客博学谷】回复关键词:前端 PS Java(100G) Python(80G) 大数据 区块链 测试 PPT JS(40g+300教程) HTML 简历 领取相关学习资料!
一、HTML
1、<image>标签上title属性与alt属性的区别是什么?
alt属性是为了给那些不能看到你文档中图像的浏览者提供文字说明的。且长度必须少于100个英文字符或者用户必须保证替换文字尽可能的短。
这包括那些使用本来就不支持图像显示或者图像显示被关闭的浏览器的用户,视觉障碍的用户和使用屏幕阅读器的用户等。
title属性为设置该属性的元素提供建议性的信息。使用title属性提供非本质的额外信息。参考《alt和title属性的区别及应用》
2、分别写出以下几个HTML标签:文字加粗、下标、居中、字体
加粗:<b>、<strong>
下标:<sub>
居中:<center>
字体:<font>、<basefont>、参考《HTML标签列表》
3、请写出至少5个html5新增的标签,并说明其语义和应用场景
section:定义文档中的一个章节
nav:定义只包含导航链接的章节
header:定义页面或章节的头部。它经常包含 logo、页面标题和导航性的目录。
footer:定义页面或章节的尾部。它经常包含版权信息、法律信息链接和反馈建议用的地址。
aside:定义和页面内容关联度较低的内容——如果被删除,剩下的内容仍然很合理。
参考《HTML5 标签列表》
4、请说说你对标签语义化的理解?
a. 去掉或者丢失样式的时候能够让页面呈现出清晰的结构
b. 有利于SEO:和搜索引擎建立良好沟通,有助于爬虫抓取更多的有效信息:爬虫依赖于标签来确定上下文和各个关键字的权重;
c. 方便其他设备解析(如屏幕阅读器、盲人阅读器、移动设备)以意义的方式来渲染网页;
d. 便于团队开发和维护,语义化更具可读性,遵循W3C标准的团队都遵循这个标准,可以减少差异化。
5、Doctype作用? 严格模式与混杂模式如何区分?它们有何意义?
声明位于文档中的最前面,处于 标签之前。告知浏览器以何种模式来渲染文档。
严格模式的排版和 JS 运作模式是,以该浏览器支持的最高标准运行。
在混杂模式中,页面以宽松的向后兼容的方式显示。模拟老式浏览器的行为以防止站点无法工作。
DOCTYPE不存在或格式不正确会导致文档以混杂模式呈现。
6、你知道多少种Doctype文档类型?
标签可声明三种 DTD 类型,分别表示严格版本、过渡版本以及基于框架的 HTML 文档。
HTML 4.01 规定了三种文档类型:Strict、Transitional 以及 Frameset。
XHTML 1.0 规定了三种 XML 文档类型:Strict、Transitional 以及 Frameset。
Standards (标准)模式(也就是严格呈现模式)用于呈现遵循最新标准的网页,
Quirks(包容)模式(也就是松散呈现模式或者兼容模式)用于呈现为传统浏览器而设计的网页。
7、HTML与XHTML——二者有什么区别
a. XHTML 元素必须被正确地嵌套。
b. XHTML 元素必须被关闭。
c. 标签名必须用小写字母。
d. XHTML 文档必须拥有根元素。
参考《XHTML 与 HTML 之间的差异》
8、html5有哪些新特性、移除了那些元素?
a. HTML5 现在已经不是 SGML 的子集,主要是关于图像,位置,存储,多任务等功能的增加。
b. 拖拽释放(Drag and drop) API
c. 语义化更好的内容标签(header,nav,footer,aside,article,section)
d. 音频、视频API(audio,video)
e. 画布(Canvas) API
f. 地理(Geolocation) API
g. 本地离线存储 localStorage 长期存储数据,浏览器关闭后数据不丢失
h. sessionStorage 的数据在页面会话结束时会被清除
i. 表单控件,calendar、date、time、email、url、search
j. 新的技术webworker, websocket等
移除的元素:
a. 纯表现的元素:basefont,big,center, s,strike,tt,u;
b. 对可用性产生负面影响的元素:frame,frameset,noframes;
9、iframe的优缺点?
优点:
a. 解决加载缓慢的第三方内容如图标和广告等的加载问题
b. iframe无刷新文件上传
c. iframe跨域通信
缺点:
a. iframe会阻塞主页面的Onload事件
b. 无法被一些搜索引擎索引到
c. 页面会增加服务器的http请求
d. 会产生很多页面,不容易管理。
参考《iframe的一些记录》
10、Quirks模式是什么?它和Standards模式有什么区别?
在写程序时我们也会经常遇到这样的问题,如何保证原来的接口不变,又提供更强大的功能,尤其是新功能不兼容旧功能时。IE6以前的页面大家都不会去写DTD,所以IE6就假定 如果写了DTD,就意味着这个页面将采用对CSS支持更好的布局,而如果没有,则采用兼容之前的布局方式。这就是Quirks模式(怪癖模式,诡异模式,怪异模式)。
区别:总体会有布局、样式解析和脚本执行三个方面的区别。
a. 盒模型:在W3C标准中,如果设置一个元素的宽度和高度,指的是元素内容的宽度和高度,而在Quirks 模式下,IE的宽度和高度还包含了padding和border。
b. 设置行内元素的高宽:在Standards模式下,给等行内元素设置wdith和height都不会生效,而在quirks模式下,则会生效。
c. 设置百分比的高度:在standards模式下,一个元素的高度是由其包含的内容来决定的,如果父元素没有设置百分比的高度,子元素设置一个百分比的高度是无效的用
d. 设置水平居中:使用margin:0 auto在standards模式下可以使元素水平居中,但在quirks模式下却会失效。
11、请阐述table的缺点
a. 太深的嵌套,比如table>tr>td>h3,会导致搜索引擎读取困难,而且,最直接的损失就是大大增加了冗余代码量。
b. 灵活性差,比如要将tr设置border等属性,是不行的,得通过td
c. 代码臃肿,当在table中套用table的时候,阅读代码会显得异常混乱
d. 混乱的colspan与rowspan,用来布局时,频繁使用他们会造成整个文档顺序混乱。
e. 不够语义
参考《为什么说table表格布局不好?》
12、简述一下src与href的区别
src用于替换当前元素;href用于在当前文档和引用资源之间确立联系。
src是source的缩写,指向外部资源的位置,指向的内容将会嵌入到文档中当前标签所在位置
href是Hypertext Reference的缩写,指向网络资源所在位置,建立和当前元素(锚点)或当前文档(链接)之间的链接
公众号【传智播客博学谷】回复关键词:前端 PS Java Python 大数据 区块链 测试 PPT JS HTML 简历 领取相关学习资料!
么是HTML / HTM文件?他们相差一个字母有什么区别吗,如何查看或编辑源代码以及如何转换成其他格式,例如DOCX,PDF,JPG 等,针对这些问题编程狮W3Cschool整理以下资料希望能对你有所帮助:
HTM / HTML 文件是超文本标记语言(Hyper Text Markup Language)文件,是 Internet 上的标准网页文件类型。
由于 HTM 文件是纯文本文件,因此它们仅包含文本(例如您现在正在阅读的内容)以及对其他外部文件的文本引用(例如本文中的配图)。
HTM 和 HTML 文件还可以引用其他文件,例如视频,CSS 或 JS 文件。
HTM 与 HTML 没有本质意义的区别,只是为了满足 DOS 仅能识别 8+3 的文件名而已,因为一些老的系统 (win32) 不能识别四位文件名,所以某些网页服务器要求 index.html 最后一个 l 不能省略。MSIE 能自动识别和打开这些文件,但编写网页地址的时候必须是完全对应的,也就是说 index.htm 和 index.html 是两个不同的文件,对应着不同的地址。值得一提的是 UNIX 系统中对大小写敏感,不吻合的话就可能报没有文件或者找不到文件。
任何 Web 浏览器,例如 Edge,Firefox,Chrome,Opera,IE,360 安全浏览器等,都可以打开并正确显示 HTM 和 HTML 文件。换句话说,在浏览器中打开这些文件并“解码(decode)” HTM 或 HTML 文件使其能正确显示。
现在有很多简化编辑和创建 HTM / HTML 文件的工具。一些著名的免费 HTML 编辑器包括 Eclipse ,Komodo Edit 和 Bluefish 。另一个流行的具有许多高级功能的 HTM / HTML 编辑器是 Adobe Dreamweaver ,不过它是收费的。
虽然 Windows 系统自带的记事本等简单的文本编辑器的功能不如专用的 HTM 编辑器那么丰富,但是对 HTM 或 HTML 文件进行简单编辑修改还是可以的。不过,W3Cschool还是建议大家使用专用的编辑器,如 WebStorm、VS Code 等,它具更多专业功能。
这是一个非常简单的 HTML 页面以文本形式显示的示例:
源码:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>什么是HTM或HTML文件? - 编程狮(w3cschool.cn)</title>
</head>
<body>
<h1>什么是HTM或HTML文件?</h1>
<p>HTM / HTML 文件是超文本标记语言(Hyper Text Markup Language)文件,是 Internet 上的标准网页文件类型。</p>
<p>由于 HTM 文件是纯文本文件,因此它们仅包含文本(例如您现在正在阅读的内容)以及对其他外部文件的文本*引用*(例如本文中的配图)。</p>
<p>HTM 和 HTML 文件还可以引用其他文件,例如视频,CSS 或 JS 文件。</p>
</body>
</html>
当 Web 浏览器呈现信息时,HTML 文件的源代码被“转换”为真实的网页(尽管源代码已很精简了)。
HTM 文件以特定的语法(规则)构成,以使其中的代码和文本在浏览器中打开时能够正确显示。因此,将 HTM / HTML 文件转换为另一种格式可能会丢失页面上的所有功能。
如果你想要做的是将一个 HTM / HTML 文件转换为方便离线查看的文件,这时图片或 PDF 格式会方便很多。
在 Chrome 中,鼠标右键单击网页,出现的选项菜单中进入 “打印(P)...”(快捷键:CTRL + P) ,在打印选项中选择另存为 PDF,以将窗口中的页面转换为 PDF 文件。Chrome 浏览器的扩展功能也称为“全屏截屏”,可将 Chrome 浏览器中所有打开的 HTM / HTML 文件转换为 PNG 文件。
其他浏览器具有类似的功能,例如 Firefox 的 “另存为 PDF” 加载项。
您也可以使用专门用于 HTM / HTML 进行图像文件转换的网站,例如iWeb2Shot 或Web-capture 。
一个免费的文件转换器可以用来转换并保存 HTM / HTML 文件到您的计算机。如 FileZigZag 是一个免费的文档转换器网站,可将 HTM 转换为RTF,EPS,CSV,PDF 和许多其他格式。
HTM / HTML 文件不能转换为文本文件格式以外的任何格式。例如,HTML 文件永远不能转换为 MP3 音频文件。
HTML / HTM 文件应该很容易打开,因为它们只是任何 Web 浏览器都可以查看的文本文件。如果您的文件没有从上面建议的任何程序打开,则很有可能正在打开的这个文件并非超文本标记语言文件。
某些文件格式使用的文件扩展名与 HTML / HTM 非常相似,但实际上并非相同。一个主要的示例是用于压缩 HTML 电子书文件的 HTMLZ 文件扩展名。有 HTML 文件在内的 HTMLZ 文件,但整个包的格式为 ZIP,不会在 Web 浏览器或文本编辑器打开。
在此示例中,您需要特定的 HTMLZ 文件查看器,例如Caliber 。或者,由于此文件格式实际上是存档,因此您可以使用 7-Zip 之类的文件解压缩器将其打开,然后您可以使用网络浏览器或上述任何其他 HTML 查看器/编辑器打开任何单独的 HTML 文件。
TMLANGUAGE 是另一个可能与 HTML / HTM 文件混淆的文件扩展名。这些实际上是TextMate 用于 macOS 的 TextMate 语言语法文件。
以上就是编程狮W3Cschool为你整理的关于《什么是HTM或HTML文件?如何打开、编辑和转换HTM和HTML文件?》的全部内容,现希望可以帮到你~
*请认真填写需求信息,我们会在24小时内与您取得联系。