스트리밍은 대부분의 브라우저와
Developer 앱에서 사용할 수 있습니다.
-
What's new in Web Inspector
The Web Inspector makes introspection and debugging simpler than ever. Discover how you can use debugger stepping, editing cookies, and overriding network loaded resources to provide you with powerful development capabilities and help you create faster, more efficient websites.
리소스
관련 비디오
WWDC21
WWDC20
-
다운로드
Hello and welcome to WWDC.
Hi my name is Devin and I'm thrilled to be able to show you some of the many improvements and new features added to Web Inspector in the last year.
To start let's enable Web Inspector in Safari.
First, click on the Safari menu bar item and select Preferences to show Safari's Preferences. Go to the Advanced Tab and enable "Show Develop menu in menu bar." In the now visible Develop menu, click "Show Web Inspector." And there it is! Web Inspector is your one stop shop for all introspection and debugging tools for Web content whether that be in Safari, a WKWebView in an app or even a JSContext. Before we dive into individual features, let's take a look at some of the changes that have been made to the overall interface. We've merged the toolbar and dashboard into the tab bar to save on vertical space. Additionally, we've tightened the spacing around many controls throughout the interface, allowing you to see more content in Web Inspector without having to sacrifice on visibility of content in the inspected page. These changes also are not limited to when docked to the bottom, as they also apply when docked to the side and even when undocked into a separate window. We've also improved Accessibility support for navigating around Web Inspector when using a screen reader. For those of you that prefer Dark Mode, we've created Dark Mode variants for all of the icons throughout Web Inspector as well as added a way to toggle Dark Mode independently from the rest of the system in the Settings Tab. Because there is no longer a dashboard, the Network Tab now shows the Inspected Page Statistics below the main table and has been expanded to include the number of unique domains, the total transfer size and a count of all redirects. This year, we've added new features to almost every tab as well as adding a few entirely new tabs. So let's go through each, starting with the new Sources Tab. For those of you who've used Web Inspector in the past, the Sources Tab takes all of the best features of the Resources Tab and the Debugger Tab and combines them into a single tab.
The Sources Tab lists all resources loaded by the inspected page since Web Inspector was opened, including long-lived things like 'WebSocket's or more ephemeral things like XHRs or 'fetch's. The Sources Tab is also the primary place for JavaScript debugging, containing all of the JavaScript debugger stepping controls and many of the breakpoint adding capabilities provided by Web Inspector. And new this year, the Sources Tab is home to the network overriding capabilities provided by Web Inspector, which we'll see in a minute. So let's take a look. When viewing resources in the Sources Tab, Web Inspector will provide alternate representations for applicable content, giving you another way to explore and examine the content to understand what's going on or fix any issues. Right now, we're looking at the Response content of this resource, which we can see is HTML text. In this case, the is filled with a lot of and text, meaning that we'd have to scroll down to see any of the content of the . Additionally, it's harder to see where tags begin and end when they're all scrunched up like this in a text. It would be a lot easier to navigate if we could visualize this response content as a DOM tree instead, just like in the Elements Tab.
Clicking on the Response breadcrumb item will show a dropdown with all of the alternate representations Web Inspector provides for this resource. Selecting the "Response (DOM Tree)" will visualize the response content as a DOM tree, just like we want it. Similar alternate representations are also provided for when the content is valid JSON, showing an object tree as if it were logged in the Console. These alternate representations are also available when content is sent as part of a request.
In situations that you do find an issue in the resource's response, it's not always easy to make a change to the source code that the resource was loaded from, as it may exist on a faraway server or involve complicated pre-processing steps.
I am very excited to tell you that this year, Web Inspector has added a new feature to solve this exact problem. We call them "Local Overrides." Creating one is as simple as clicking the "Create Override" button when viewing any resource which will automatically copy the current contents of that resource into a new local override for that resource. They are fully editable and are preserved by Web Inspector across sessions of both the inspector page and Web Inspector itself. So let's try making a simple change to see a local override in action. Scrolling down in the content area, we can see the "WebKit" text in the . We can change this "WebKit" text to something like "Hello WWDC!" instead. If we take a look at the inspected page and reload, we can see that the "WebKit" text in the of the inspected page changes to match the edits we just made. Even better, local overrides support more than just modifying the response's content. If you right-click on the local override in Web Inspector and select the "Edit Local Override…" action, it's also possible to modify the HTTP status code or any HTTP headers. When the inspected page loads anything over the network that matches any local override's URL, the entire response, including the HTTP status code and any HTTP headers, will be completely replaced by the local override as it's been configured. Whenever this happens, the icon of the overridden resource will change, indicating that it was replaced. And this overridden icon is shown anywhere that the resource can be seen throughout Web Inspector. As further proof, if we select the overridden resource and scroll down, the same modifications we made to the content are also present. All resources, including the main resource like we just saw and even non-text resources, like images, can be overridden and fully configured from within Web Inspector. Sometimes, however, it's not necessarily a particular resource that you want to change but really a JavaScript API provided by WebKit. In these cases, you'll want to use the new Inspector Bootstrap Script which can be added from the add resource button in the bottom corner of the navigation sidebar in the Sources Tab, by selecting the Inspector Bootstrap Script action. Similar to how local overrides allow you to modify resources loaded over the network, the Inspector Bootstrap Script can be thought of as a way to modify the JavaScript API surface itself. The contents of the Inspector Bootstrap Script are guaranteed to run before anything else in the inspected page. Hence, the "bootstrap" name. This allows you to do things like swizzle built-in functions to see where they get called or setup some global state that causes your code to log additional debugging information.
Just like local overrides, the Inspector Bootstrap Script is preserved by Web Inspector across sessions of both the inspected page and Web Inspector itself. Speaking of debugging JavaScript, we've also added a number of new global breakpoints.
The Debugger Statements breakpoint controls whether or not JavaScript execution is paused at 'debugger' statements. Previously, the only way to control this was to completely disable all breakpoints. We felt this was unnecessarily restrictive, so we created this separate control to allow you to use other types of breakpoints while simultaneously disabling 'debugger' statements specifically. The other new breakpoints, since they relate to specific APIs, must be enabled by clicking on the add breakpoint button which will show a menu with actions that each enable one of these new breakpoints. So let's go through each of them one by one. The All Microtasks breakpoint will pause JavaScript execution whenever any microtask is about to be executed, such as from 'Promise' objects or the 'queueMicrotask()' global function. Along these lines, the All Animation Frames breakpoint does the same for 'requestAnimationFrame' callbacks. The All Timeouts breakpoint does the same for 'setTimeout' callbacks and the All Intervals breakpoint does the same for 'setInterval' callbacks. Lastly, the All Events breakpoint will pause before any callback is invoked for any event listener, even those unrelated to the DOM. But sometimes these global breakpoints are almost too global, in the sense that they pause more often than desired. Let's take a look at an example using the All Events breakpoint.
I have a simple page that uses jQuery to add an event listener to a element. Because I've enabled the All Events breakpoint, I would expect to pause inside this event listener. But in reality, jQuery wraps my event listener callback with its own logic. So instead, we pause in jQuery's event listener wrapper which is not really ideal as none of this is my code. Really, what I want to do is have this breakpoint pause in my code after all of jQuery's code has run.
Script blackboxing is a new feature that allows you to do just that – instructing the JavaScript debugger to defer any pause that would occur in a script to pause at the first expression to execute outside of that script. We can do this to jQuery by hovering over the jQuery resource in the navigation sidebar and clicking on the button that appears. Now, if we trigger this breakpoint again, we should pause in our event listener instead. If, for some reason, you still do want to dig into the library/framework code, Web Inspector will still show any call frames from blackboxed Script, greying them out to indicate their blackboxed nature. For larger libraries and frameworks, it's also possible to blackbox multiple scripts at once by configuring regular expression patterns to match against the script's URL in the Settings Tab.
In addition to some of the global breakpoints we've seen so far, Web Inpector also allows you to set breakpoints on specific lines of JavaScript even after pretty printing. Clicking on any line in the gutter area of the content preview, Will add a JavaScript breakpoint that will pause right before that line executes. Because JavaScript is so flexible with its syntax, however, it's not uncommon to see lots of operations combined onto a single line using a mix of various operators. In this case, the logical "or" operator. Previously, if I wanted to pause inside the 'c' function call and I didn't know where 'c' was declared to set a breakpoint, the only way to do this would be to use the Step In JavaScript debugger action to step into "a()". And, then, step out to move past 'a', then, step in again to go inside 'b', And finally, step back out, again, to arrive at 'c'.
This is a very tedious process with lots of opportunity for mistakes which can be incredibly frustrating, especially in cases where the starting state is hard to reach. This has led us to introduce a new JavaScript debugger action which we call Step.
Unlike the Step Over JavaScript debugger action, which resumes and re-pauses execution before the next statement in the current call frame, which in this case, would be after the entire 'foo' variable declaration, this new Step debugger action will resume and re-pause Javascript execution before the next expression in the current call frame. And just like that, we've resumed, executed 'a' and re-paused on the same line without ever having to Step in or Step out. Once more, we can Step to resume execute 'b' and re-pause arriving at the call for 'c'.
This Step JavaScript debugger action provides more fine grained control over how the JavaScript debugger execution head moves through the program, allowing for fewer stepping mistakes and even less actions in total.
But sometimes scripts are inlined in HTML. In the past, there was no way to pretty print this inlined script content or even any of the surrounding HTML. As a result, it was often difficult to set breakpoints or even step through code in a nicely readable way. I'm very happy to say that in the latest Safari, Web Inspector now supports formatting HTML and other XML-like content, including inline scripts and style sheets, allowing support for all of the existing JavaScript debugger and stepping capabilities too. Simply click on the pretty print button in the top right of any text-based content preview, to toggle between the original content and the pretty printed version.
Web Inspector will also attempt to detect when HTML has been minified and automatically toggle pretty printing, just like it has always done for JavaScript and CSS content. So speaking of Web Inspector functionality, there's so much more than just viewing resources. So, let's move on to some of the other powerful or more specialized features starting with the Timelines Tab.
The Timelines Tab contains the majority of performance profiling tools offered by Web Inspector. It captures activity in the inspected page during what we call a "recording" which organizes and plots the data into one of a handful of different timelines based on the type of data.
Timeline recordings can also be exported and imported allowing you to share them with others or save them for later use. The main change this year in the Timelines Tab, is an introduction of an entirely new timeline, which you can activate by clicking the Edit button in the main graph area. This will put us in edit mode where we can enable or disable any of the various timelines. The new timeline we've added this year is the Media & Animations timeline which captures events related to media elements, like or , and also captures the lifecycle of CSS animations and CSS transitions. After checking the checkbox to enable the Media & Animations timeline and clicking the Done button to leave Edit mode, if we reload the inspected page we can see a list of all media elements, CSS animations and CSS transitions that have had any activity during the recorded interval. Each individual media element, CSS animation or CSStransition has its own row in the table with links to any related DOM node or information about the CSS 'animation-name' or CSS 'transition-property'. The Media & Animations timeline can also be used to correlate activity captured in other timelines with state changes in any media elements, such as a video being paused or the creation or destruction of any CSS animations or CSS transitions to figure out what's going on and understand why. And that's a quick look at the Media & Animations timeline in the Timelines Tab. Let's move on to the Storage Tab. So the Storage Tab contains a list of all of the data stored by the inspected page in the browser via things like cookies or LocalStorage or IndexedDB. This year, we've added filtering capabilities for all storage types and improved editing and deleting capabilities especially for cookies. The new filtering capabilities take the form of an always visible filter bar shown at the top of most storage views. As an example, filtering cookies is as simple as typing some text into the filter bar which is compared against the various fields of each cookie, hiding any rows that had no matches. The second major feature is the ability to edit cookies. Double clicking on one of a cookie's cells, will show a popover with inputs for each field of that cookie. All modifications made in this popover will be applied as soon as the popover is dismissed. It is also possible to add entirely new cookies by clicking on the add cookie button which will show a similar popover. But, this time, all of the inputs will be empty. Note, that a name is required in order for a cookie to be added. Just like HTTP cookies, or those set by 'document.cookie', they will persist beyond Web Inspector, so be careful what you add. But many other features of the web are not persistent, so let's take a look at tooling for some of those. Starting with the all new Graphics Tab.
For those of you who've used Web Inspector in the past few years, you may remember using the Canvas Tab. The Graphics Tab expands the scope and functionality of the Canvas Tab still showing all contexts and shaders and supporting taking recordings of JavaScript API calls made to contexts, but now also listing all web animations including those created by CSS animations and CSS transitions, providing in-depth information about each. The previously available information about all contexts in the inspected page is still shown in the Canvases section at the top, followed by the new sections for the various types of animations created by the web animations API separated by how they're created, such as from JavaScript, CSS animations or CSS transitions.
Clicking on one of these animations will expand the details sidebar which contains all of the information about the selected animation, such as the ID which can be thought of as the animation's name, the associated node of the animation, the configured timing parameters, like the number of iterations or the total duration, the keyframes list, each item containing a list of CSS properties and values that are interpolated between as the animation progresses, and, finally, for animations that are created by the JavaScript API, a backtrace for how the animation was created.
Clicking the markup icon in the header of any animation, will show a context menu with a number of utility actions, such as Log Animation which will save the JavaScript object for that Web Animation in a temporary variable in the Console (in this case '$1'), allowing us to have easy access for manipulating it using the powerful Web Animations API. For more information about the new Web Animations API, be sure to check out the "What's New for Web Developer" session in your Developer app. But sometimes animations are configured incorrectly, which causes performance problems. So, let's take a look at the new Layers Tab to see how it can help. The Layers Tab shows a live view of the layer tree of the inspected page, listing the memory cost and the paint count for each layer. While it's not exactly one to one, it's generally a good idea to keep the number of unintended layers as low as possible, as a greater number of layers can be associated with increased memory use and worse performance. The keyword there though is "unintended" which really requires you, the developer, to know your layout and when things should and should not create a layer. To assist with this, clicking on a layer either in the visualization itself or in the detailed sidebar, will show information about that layer, such as why it was created. In the case of the currently selected layer, it was created because the associated node was being animated by CSS and how to CSS 'will-change' property. The entire layer tree visualization can also be manipulated using common orbit controls such as rotating vertically by clicking and dragging up and down, rotating horizontally by clicking and dragging left and right, zooming by scrolling in and out and panning by right-clicking and dragging, making it easy to find layers visually to find out more about them. So now let's move on to our final tab, the Console. The Console Tab lists all of the various messages logged by the inspected page and allows arbitrary JavaScript evaluation in the inspected page. Special functionality is also exposed while evaluating JavaScript, intended to make inspecting and debugging JavaScript easier by providing more information previously known only to WebKit. There are a whole bunch of these Console-only specially exposed bits of functionality that are new this year, but there are two that are particularly noteworthy. The first is called "queryInstances." So let's imagine a simple JavaScript class hierarchy of an 'Animal' base class with a 'Pet' subclass. Now let's say that we want to find all instances of this 'Pet' subclass. One way to do it, would be to examine a captured heap snapshot in the Timelines Tab, but that includes a lot of other information that is likely not relevant. So instead, 'queryInstances' when given a constructor, will scan the entire JavaScript heap for instances of objects that inherit from that given constructor, returning them all in an array that can be further manipulated in the Console. As we can see here, there is one instance of this 'Pet' class, which is held in the variable with the name 'buddy.' Note, however, that due to the nature of JavaScript inheritance, the term "instance" also applies to subclass objects as well. As an example, if we call 'queryInstances' with the 'Animal' constructor, we will not only see the previously seen 'buddy' variable but we will also see an instance of 'Animal' held by the 'cat' variable and even the entire 'Pet' class as it also inherits from the 'Animal' class. For more flexibility, it's also possible to provide a prototype instead of a constructor which will have the exact same result we saw earlier with the related constructor.
The second noteworthy function is called 'queryHolders.' So again, let's imagine a simple JavaScript class called 'Person.' Similar to reality, each 'Person' can have a 'parent.' This is represented in JavaScript as a 'parent' property whose value is the other 'Person' object. This is called a strong reference and is a common cause a memory leaks in JavaScript programs. If we wanted to find all objects that have a strong reference to a given object, we could examine a captured heap snapshot in the Timelines Tab, but again this may include other information that is likely not relevant.
Instead we can use the 'queryHolders' Console function which, when given an object, will scan the entire JavaScript heap for all other objects that have a strong reference to that given object. As we can see in this example, 'alice' has a strong reference to 'john' through its 'parent' property which is why 'alice' appears in the array returned by 'queryHolders.' Now let's talk about our last feature for today. I'm very happy to announce that in the latest Safari, so long as Web Inspector is already open, enabling Intelligent Tracking Prevention Debug Mode from Safari's Develop menu will cause all debug logging from Safari's Intelligent Tracking Prevention to also appear in the Web Inspector Console, as well as in the macOS system Console.app. Additionally, logs for Ad Click Attribution Debug Mode will also be shown in the Web Inspector console, which can be enabled from the Experimental Features submenu of Safari's Develop menu. This way, you'll never have to switch away from Safari to see all of the logs you might find useful. And with that we've, reached the end of our feature highlights. There is so much more coming in the latest Safari, including a ton of bug fixes and minor tweaks throughout Web Inspector. Before we finish up, there's a few general tips I'd like to leave you with. Tooltips are your friend.
If you're unsure of what something does, simply hover over it with your cursor for a few seconds, and voila! The answer will appear. Every icon in Web Inspector has a tooltip. All links have a tooltip. In fact, almost every component of the interface has a tooltip. Web Inspector makes heavy use of iconography as there's a ton of varying functionality that has to fit into a very limited amount of space. As such, it relies on tooltips to provide additional explanation and description where there isn't enough room. For a similar reason, Context Menus are everywhere and they often contain additional functionality that can't be accessed anywhere else. Many icons have a context menu.
Every link has a context menu. Again, almost every component of the interface has a context menu. And in fact, most of what we've done so far could have also been done via a context menu action. For much of the same reason as tooltips, Web Inspector puts a lot of functionality into context menu actions as there isn't enough room for each action to have its own component in the interface. For more tips like those, there's an all new section of the WebKit website that talks specifically about Web Inspector. It contains a bunch of reference pages that each explore both the breadth and the depth of various features, parts of the interface and more. In fact, many of the features we talked about today already have reference pages and we're working on writing even more from many of the others. Also, be sure to follow @webkit on Twitter as we post weekly tips about various features in Web Inspector.
And I'd also highly recommend using Safari Technology Preview for your daily development, as it gets bi-weekly updates with bug fixes and new features, both to Web Inspector and to the rest of WebKit. Be sure to check out this session's related resources for other sessions about some of these new features, as well as links to our documentation. I really hope you've enjoyed learning about what's new in Web Inspector and I hope you find that as things we've discussed useful for understanding and debugging web content in the future. Thank you so much for listening and I hope you have a wonderful WWDC.
-
-
찾고 계신 콘텐츠가 있나요? 위에 주제를 입력하고 원하는 내용을 바로 검색해 보세요.
쿼리를 제출하는 중에 오류가 발생했습니다. 인터넷 연결을 확인하고 다시 시도해 주세요.